본문 바로가기
논문 정리

YOLOv5 - training & test

by winston1214 2020. 9. 27.
반응형

Yolov5에 대한 소개는 저번 포스팅을 참고 하길 바란다.(2021.11.14 수정)

2020/09/27 - [논문 정리] - YOLOv5 - Introduction

 

YOLOv5 - Introduction

YOLOv5는 가장 최근에 나온 yolo 시리즈다. 이에 대해서 직접 학습하고 실행해보았다. 일단 개발환경은 Ubuntu 18.04.5, GPU : TitanXP 이다. anaconda 버전은 가장 최근 버전을 사용하였다. Training dataset은 C..

bigdata-analyst.tistory.com

YOLOv5 - Introduction

YOLOv5는 가장 최근에 나온 yolo 시리즈다. 이에 대해서 직접 학습하고 실행해보았다. 일단 개발환경은 Ubuntu 18.04.5, GPU : TitanXP 이다. anaconda 버전은 가장 최근 버전을 사용하였다. Training dataset은 C..

Yolov5를 활용하기 위해 이 깃허브를 참고한다. github.com/ultralytics/yolov5

 

ultralytics/yolov5

YOLOv5 in PyTorch > ONNX > CoreML > iOS. Contribute to ultralytics/yolov5 development by creating an account on GitHub.

github.com

전 포스팅에서도 말했듯이 개발환경은 Ubuntu18.04.5 , GPU : TitanXP ,opencv : 4.4 anaconda는 가장 최신버전을 사용하였다.

그리고 Training set은 COCO dataset을 활용할 것이다.

일단 기본적으로 YOLOv5는 COCO dataset이 기본적으로 pretraining 되어있어서 많은 학습을 안시켜도 성능이 괜찮게 나온다.

하지만 나는 class를 2개로 나누고 (person, car) 학습을 진행할 것이다.

1. 일단 dataset 다운로드를 받아야한다. cocodataset.org/#home

 

COCO - Common Objects in Context

 

cocodataset.org

이 사이트를 들어가면 coco dataset을 다운 받을 수 있다. 용량이 엄청나게 크니 그 점을 유의해서 받아야한다.

나같은 경우는 val2017을 다운 받아서 사용하였다.

2. coco dataset -> yolo dataset 으로 변환시켜줘야 한다. 이 작업이 필요한 이유는 다음과 같다.

coco bbox

세미나 할 때 발표했던 자료인데 coco dataset은 기본적으로 bounding box가 맨 왼쪽의 x,y 좌표로 구성되어 있고 이에 따른 w(가로 길이), h(높이 길이) 로 구성되어있다.

yolo bbox

하지만 yolo dataset은 bounding box의 중심점 좌표가 나타나있고 이에 따른 전체 이미지의 상대값으로 이루어져 있다.

이를 풀어서 설명하자면 전체의 사진 크기를 0~1 사이로 생각한다. 즉 이미지의 맨 위의 왼쪽 좌표가 (0,0) 맨 아래의 오른쪽 좌표가 (1,1) 인 것이다.

다음과 같은 예시를 들어 설명하겠다.

yolo_mark

yolo_mark라는 전처리기를 통해 생성한 것인데 이해하기 쉽게 오른쪽에 있는 사람의 helmet boundingbox 좌표를 보자.

x: 0.953516 y: 0.265972 w: 0.092969 h: 0.156944 로 생성됐다. 맨 오른쪽에 있기 때문에 x의 좌표는 1에 가깝고 y는 상대적으로 윗쪽에 있기 때문에 0.2라는 값이 나왔다. 그리고 w를 보면 0.09로 상당히 작은 값이다. 이는 전체 이미지 비율에서 초록색 bounding box의 가로 길이가 0.09 정도라는 의미이다. 이와 같은 원리로 h도 세로의 길이가 전체 이미지의 0.15 정도라는 것이다.

yolo 좌표에 대한 설명이 길어졌는데 이러한 이유로 coco convert to yolo가 필요하다.

이를 하기 위해서 라벨링이 안되어 있으면 YOLO_MARK를 사용하여 하나하나씩 직접 Bouding box를 만들어줘야한다. 하지만 COCO dataset은 라벨링이 되어 있기 때문에 변환기를 사용하면 금방 변환이 될 수 있다.

폭풍 구글링을 한 결과 가장 간단한 변환 사이트를 찾을 수 있었다.(현재 작동 안됨)

https://bitbucket.org/yymoto/coco-to-yolo/src/master/

이 링크에 들어가서 jar 파일을 다운 받고 입력하면 된다.

$ java -jar cocotoyolo.jar "coco/annotations/instances_val2017.json" "/usr/home/cvai-server/coco/images/train2017/" "person, car" "coco/yolo"

이 코드의 구성은 다음과 같다.

---> cocotoyolo.jar "json file(annotations) path" "img path" "class" "save path"

coco dataset을 다운 받을 때 annotation.json의 위치, 변환할 이미지의 위치, 그리고 내가 원하는 추출하고자 하는 class 이름, 그리고 저장할 위치이다.

이걸 몰랐을 때 다 하나하나 분리해야되나 막막했는데 이를 사용하면 원하는 클래스만 추출할 수 있을 뿐만 아니라 YOLO 형식으로 바꿔주니 너무 감동해서 눈물 날 뻔 했다..

반응형

3. 이제 환경 세팅을 한다.

$ git clone https://github.com/ultralytics/yolov5.git

먼저 git clone을 하고

$ cd yolov5
$ pip install -r requirements.txt

yolov5 폴더로 이동한 담에 필요한 패키지들을 다운 받는다.

4. yaml file 변경

# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]
train: ../coco128/images/train2017/
val: ../coco128/images/train2017/

# number of classes
nc: 80

# class names
names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
        'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
        'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
        'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
        'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
        'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
        'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 
        'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 
        'teddy bear', 'hair drier', 'toothbrush']

data.yaml 파일의 초기 형태는 위와 같이 구성되어있다. 나는 이를 car와 person만 구분할 것이므로

nc: 2 , names: ['person','car'] 로 변경한다. 그리고 train , val 부분을 이미지가 있는 파일 경로로 변경한다.

나같은 경우 val2017 하나만 다운 받았기 때문에 train_test_split()을 사용하였다.

# jupyter notebook
# image list.txt 에 있는 경로를 list로 받기
f= open('/home/cvai-server/convert2Yolo/image_list.txt','r')
img_list =[]
while True:
    line = f.readline()
    if not line: break;
    img_list.append(line[:-1])

# train_test_split
from sklearn.model_selection import train_test_split # train,validation split
train_img_list , val_img_list = train_test_split(img_list,test_size=.2,random_state=42)

# validation 및 train 이미지 작업 폴더로 복사
import shutil
path1 = '/home/cvai-server/COCO/val2017'
path2 = '/home/cvai-server/convert2Yolo/val2017'
for i in val_img_list:
    shutil.copy2(i,path2)

# bounding box에 있는 좌표 txt 파일 옮기기
train_label_list = []
val_label_list =[]
for x in train_img_list:
    y =x.replace('/COCO/val2017','/convert2Yolo/val_label').replace('.jpg','.txt')
    train_label_list.append(y) # jpg로 저장되어 있는 것을 txt로 변경 후
for x in val_img_list:
    y = x.replace('/COCO/val2017','/convert2Yolo/val_label').replace('.jpg','.txt')
    val_label_list.append(y)
    
# 작업 폴더로 복사하기
path2 = '/home/cvai-server/convert2Yolo/coco/labels/val_label'
for i in val_label_list:
    shutil.copy2(i,path2)

 

 

다음과 같은 코드를 사용하여 작업 폴더로 이미지를 옮겨주고 나눠준다. ( 상황에 따라 수정 필요, 급하게 만든거라..)

5. 디렉토리 정리하기

디렉토리 정리

다음과 같은 형태로 디렉토리를 정리한다.

5-1 txt 파일 정리(NEW)

train_list.txt, val_list.txt 라는 텍스트 파일을 생성

이 때 txt의 내용은 사진의 경로를 넣어줌. ex) ../data/train/00000.jpg

6. Training

이제 드디어 train을 시킬 차례이다.

$ python train.py --data coco.yaml --weights yolov5s.pt --batch-size 64
                                             yolov5m                 40
                                             yolov5l                 24
                                             yolov5x                 16

다음과 같이 자신이 train시키고 싶은 사이즈를 선택하고 batch size를 선택하여 코드를 작성한다.

나는 yolov5s를 사용할 것이고 batch_size는 64로 크게 설정하였다.

더 좋은 성능을 선택하고 싶다면 yolov5x를 사용하고 batch_size를 줄이고 이미지의 개수를 늘리면 더 좋은 성능이 나올 수 있다.(대신 train 시간이 오래걸림)

$ python3 train.py --data ./data/coco.yaml --weights yolov5s.pt --batch 64 --epochs 50 --name ep50

 

각각의 파일 경로를 기입해준다. 그리고 weights는 yolov5s.pt 라는 파일을 이용할 것인데 이는 미리 학습되어 있는 weight 이다. 적은 이미지를 학습할 때 학습 성능을 높일 수 있다. 그리고 --names는 폴더에 저장할 파일 이름이다.

 

7. test

학습이 완료되면 바로 test를 통해 확인을 해보자!

python3 detect.py --source ~/test_img/2011_09_26_drive_0091_sync/image_01/data/ --weights ./runs/exp5_ep50/weights/my_best.pt

detect.py를 통해 test를 하고 --source는 test할 data의 파일 경로 , --weights는 train에서 나온 결과 파일에서 weight 파일을 선택한다. weight file은 best.pt와 last.pt 가 나오는데 나는 best.pt로 설정했다.

그리고 --conf 옵션을 사용안하였는데 이는 신뢰도 어느 정도 이상인 것만 나타내는 것이다.(default:0.4)

총 300장의 파일을 test를 돌리고 동영상으로 변환한 결과이다.

test한 결과

https://youtu.be/zzaC7ID1fD4

링크를 통해 확인하면 사람이 잘 분류 되는 반면 각도에 따라 차량은 잘 인지하지 못하는 경향이 있다.

이는 추후에 yolov5x로 바꾼 후 batch_size를 줄인 후 epoch를 늘리는 방식으로 하면 각도에 따른 차량도 인식할 수 있게 된다.(실제로 해봄)

 

아마 내가 조금 빠뜨린 부분이 있을 수 있는데 이는 추후에 수정하겠다.

그리고 상세한 코드와 파일은 

https://github.com/winston1214/AICT/tree/master/yolov5

 

winston1214/AICT

Internship. Contribute to winston1214/AICT development by creating an account on GitHub.

github.com

여기에 README.md에 설명이 적혀있다. 그리고 코드도 함께 첨부해놨다.

 

 

 

반응형

'논문 정리' 카테고리의 다른 글

Auto Encoding Variational Bayes(VAE) -1  (5) 2021.03.29
Deep Residual Learning for Image Recognition(ResNet)  (4) 2021.03.13
Towards open set deep networks  (4) 2021.01.20
YOLOv5 - Introduction  (0) 2020.09.27
YOLO  (0) 2020.09.11

댓글