반응형

Custom 데이터로 YoloV5 모델 학습하기 2편 -

[AI/Self-Study] - yolov5 학습 튜토리얼 2 (+ mAP, IoU 설명 / Test 와 Inference)

 

1. 환경 세팅 

1) YoloV5 깃헙 레포지토리 clone

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

 

2) PyTorch 깔기

아나콘다 가상환경을 만들어주고 CUDA 버전에 맞는 PyTorch를 깐다.

pytorch.org/get-started/previous-versions/ 에서 CUDA 버전에 맞는 PyTorch를 깔아주면 된다.

 

YoloV5 는 최소 Python>=3.8PyTorch>=1.7 를 만족해야한다.

$ conda create -n yolov5 python=3.8
$ conda activate yolov5
$ conda install pytorch==1.7.1 torchvision==0.8.2 torchaudio==0.7.2 cudatoolkit=11.0 -c pytorch # CUDA 11.0

 

3) 나머지 필요한 모듈 설치

$ cd yolov5
$ pip install -r requirements.txt  # install

 

2. 데이터 폴더 세팅

data 폴더 안에 이미지 폴더와 라벨 폴더를 만든다. 그 안에 train, valid 폴더를 만든다.

YoloV5를 학습시키려면 아래와 같은 데이터 폴더 구조를 만들어 줘야한다. 

 

Yolo V5 학습을 위한 폴더 트리
yolov5 폴더 구조 예시 -> data 폴더안에 images랑 labels를 만들면 된다.

 

LabelImg 를 써서 데이터 라벨링을 해줬기 때문에 위에 폴더 구조를 만들려면 txt 파일과 이미지 파일 (.jpg)를 분리해줘야한다.

from glob import glob
import shutil
import os

data = ['train','valid','test']

for i in data:
    source = './data/images/' + i + '/'
    images = './data/images/' + i
    labels =  './data/labels/'+ i
    mydict = {
        images: ['jpg','png','gif','jpeg','JPG'],
        labels: ['txt','json']
    }
    for destination, extensions in mydict.items():
        for ext in extensions:
            for file in glob(source + '*.' + ext):
                shutil.move(file, os.path.join(destination,file.split('/')[-1]))

 

3. yaml 파일 만들기 

1) dataset.yaml 만들기

data 폴더 안에 coco128.yaml 이라는 파일이 있는데 이와 비슷하게 custom data용 yaml 파일을 만들어 주면 된다 (파일 이름은 원하는대로).

yaml 파일 안에는 1) training data 경로 2) validation data 경로 3) 탐지할 class 개수 4) class 이름 리스트 가 들어간다.

 

dataset.yaml 예시)

train: /data/images/train 
val: /data/images/valid

nc: 1
names: ['wheat']

 

model 폴더 안에 보면 yolov5l.yaml, yolov5m.yaml, yolov5s.yaml, yolov5x.yaml 파일들이 있다.

YoloV5는 s, m, l, x의 4가지 버전이 있는데, s가 가장 가벼운 모델이고 x가 가장 무거운 모델이다.
s가 성능이 제일 낮지만 FPS(초당 프레임 수) 가 가장 높고, x가 성능이 제일 높지만 FPS는 가장 낮다.

 

yoloV5 모델 종류

 

* Object Detection 의 성능지표 중 하나인 FPS:

Frame Per Second 라고 하는데 초당 frame 수라고 생각하면 된다. 영상에서 초당 frame이 많을수록 움직임이 더 자연스러울 것이다. Object Detection 에서 FPS라는건 초당 detection (탐지)하는 비율을 의미한다. 초당 30개의 frame에 대해 detection을 수행하면 30 fps가 된다. 우리가 Real time 이라고 느끼는 FPS는 30 fps로 초당 frame을 30개 이상 처리하면 자연스러운 영상으로 인식한다 (30 fps = 움직임이 부드러움, 60 fps = 움직임이 더 부드러움, 60 fps 이상 = 움직임이 엄청 부드러움). Obejct Detection 의 성능 측정을 할때는 accuracy 도 중요하지만 speed 도 중요하다~!

출처 : 89douner.tistory.com/80

 

YoloV4는 MS COCO 데이터셋에서 AP : 43.5% (AP50 : 65.7%), 65 FPS(Tesla V100 그래픽카드 , 거의 실시간에 가까운 높은 FPS) 를 달성했다.

YoloV4 설명 : ropiens.tistory.com/33

YoloV4 성능

 

2) model yaml 파일 변경

원하는 모델을 고른 후, model 폴더 안에 그 모델의 yaml 파일을 연다.

그리고 nc (number of classes) 만 바꿔주면 된다.

# YoloV5m

# parameters
nc: 1  # number of classes
depth_multiple: 0.67  # model depth multiple
width_multiple: 0.75  # layer channel multiple

# anchors
anchors:
  - [10,13, 16,30, 33,23]  # P3/8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

# YOLOv5 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Focus, [64, 3]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, BottleneckCSP, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 9, BottleneckCSP, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, BottleneckCSP, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 1, SPP, [1024, [5, 9, 13]]],
   [-1, 3, BottleneckCSP, [1024, False]],  # 9
  ]

# YOLOv5 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, BottleneckCSP, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, BottleneckCSP, [256, False]],  # 17 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, BottleneckCSP, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, BottleneckCSP, [1024, False]],  # 23 (P5/32-large)

   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

 

4. (Optional) Weights & Biases Logging (🚀 NEW)

코드안에 이미 내장되어 있어서 Weight & Biases(wandb) 로깅 툴을 쉽게 사용할 수 있다. Tensorflow의 Tensorboard와 비슷한데, 이 도구는 tensorflow나 pytorch 등 여러 flatform에서 사용할 수 있다. 실시간으로 학습과정을 시각화해서 볼 수 있고, validation result 도 눈으로 볼 수 있어서 좋은 것 같다. YoloV5 에는 이미 코드에 들어가 있기 때문에 간단히 설치만 해주고 가입하면 아주 쉽게 사용가능하다.

 

1) 설치를 해주고

$ pip install wandb

 

2) wandb.ai/site?utm_campaign=repo_yolo_traintutorial 가서 회원가입을 해준다. (안해줘도 상관없음)

 

Weights & Biases – Developer tools for ML

A central dashboard to keep track of your hyperparameters, system metrics, and predictions so you can compare models live, and share your findings.

wandb.ai

3) train code를 돌리면 세팅 가이드가 알아서 뜬다.

위에서 회원가입했으면 (2) 선택하고 아니면 (1) 선택해서 바로 account를 만들 수도 있는 것 같다.

 

 

(2)를 선택하면 API key 를 적으라고 한다. 친절하게 링크까지 주니 링크로 들어가서 복붙하면 된다.

 

 

wandb를 사용하면 이런식으로 학습로그, train loss, validation loss 그래프, 평가지표 그래프, validation 데이터 predict한 output 까지 볼 수 있다. 좋다.

 

wandb report 예시

 

로그 예시

 

wandb 를 안써도 YoloV5 코드에 로컬 로깅도 포함되있다. runs/train 폴더로 가면 training을 새로 돌릴 때마다 runs/train/exp2, runs/train/exp3, ... 이런식으로 폴더가 생긴다.

 

Augmentation 적용된 train 이미지도 볼 수 있고 (train_batch0.jpg : mosaic 적용된거 확인 가능

-> Mosaic Augmentation: YoloV4 에서 소개된 기법으로, 4개의 image를 하나로 합치는 방식),

 

train_batch0.jpg 예시

 

test (validation) 데이터 예측한 결과도 볼 수 있다 (test_batch0_labels.jpg : 정답값, test_batch0_pred.jpg : 예측 결과값). 

 

test_batch0_labels.jpg 와 test_batch0_pred.jpg 예시

 

 

 

5. 학습하기

$ python train.py --img 640 --batch 32 --epochs 200 --data '/data/dataset.yaml' --cfg 'models/yolov5m.yaml' --weights yolov5s.pt --name test

runs/train/ 폴더에 runs/train/exp2, runs/train/exp3 ... 이런식으로 학습 돌릴 때마다 exp 폴더가 생겨 학습 결과가 저장된다. 

 

인자값 설명

  • --img: input image 사이즈
  • --batch: 배치 사이즈 
  • --epochs: epochs 수
  • --data: 3. 에서 만든 YAML 파일
  • --cfg: 모델 YAML file
  • --weights: 전이학습 사용시에 쓸 weight (모델에 맡게 yolov5s.pt / yolov5m.pt / yolov5l.pt / yolov5x.pt)
  • --device: GPU / CPU (0 or 0,1,2,3 or cpu)
  • --name: 학습 정보를 runs 폴더 안에 저장해 줄 때 이름을 정할 수 있는 것 같다 (exp1, 2, ... 기본값으로 설정되어 있는 이름들은 나중에 알아보기 힘들 수도 있으니..) -> yolov5/runs/exp0_name/ 이런식
  • --resume: 학습이 어떤 이유로 중간에 멈췄다면, $ python train.py --resume 코드를 통해 제일 최근에 저장된 weight "last.py" 부터 학습을 다시 시작할 수 있다. Epoch도 멈췄던 지점부터 다시 학습이 된다. 특정 weight 부터 학습을 다시 시작하고 싶다면 $ python train.py --resume runs/exp0/weights/last.pt 이런식으로 weight 경로를 적어주면 된다.

 

* 성능 높이는 팁 

YoloV5 공식 깃허브에 모델 성능을 높이는 팁이 나와있다.

  • 당연한 얘기지만 데이터 셋이 충분이 크고 라벨링이 정확하게 되야한다.
  • Background image 넣기 -> 백그라운드 이미지는 탐지할 물체가 없는 데이터들을 의미한다. 이 백그라운드 이미지를 넣어주면 False Positives (FP) 가 줄어드는 효과를 볼 수 있다. 전체 학습 데이터 셋에 0-10% 정도 넣는 것을 추천한다고 한다. (COCO 데이터 셋은 1000 개의 백그라운드 이미지를 가지고 있다 - 학습 데이터 셋의 1%)
  • Pretrained weights 사용하기 -> 작거나 중간 정도 사이즈의 데이터셋에 추천한다. (--weights 인자값을 넣으면 됨)
  • Epoch는 300부터 시작해서 overfit 이 발생하면 줄이고 발생하지 않으면 600 1200 등으로 점점 늘리면 된다.
  • 이미지 사이즈를 보면 COCO는 640으로 학습한다. 작은 크기의 물체가 많을 수록 높거나 원래의 해상도 사이즈를 쓰면 좋다. 최고의 인퍼런스 성능을 내려면 인퍼런스 돌릴 때 input으로 들어가는 이미지 사이즈가 학습 때 설정한 이미지 사이즈와 같아야한다.
  • 기본값 으로 저장된 모델 하이퍼 파라미터들은 data 폴더 안에 hyp.scratch.yaml 에서 찾을 수 있다. 먼저 이 하이퍼파라미터로 학습하는 것을 추천한다.
    • YoloV5 에서는 Hyperparameter evolution 이라는 기법을 설명해준다. Hyperparameter evolution 은 Genetic Algorithm (GA) 를 사용해서 하이퍼파라미터를 최적화하는 방법이라고 한다. 자세한 방법은 : github.com/ultralytics/yolov5/issues/607
    • +) --evolve argparser argument. It will run your scenario 50 times, evolving the hyperparameters from their initial setting each generation, creating mutation from successful offspring, saving the results in evolve.txt
    • 인자값으로 --evolve 를 줘서 Hyperparameter evolution 을 사용할 수 있다고 한다. 시나리오 50번을 돌려서 hyperparameter를 최적화하고 결과값은 evolve.txt 에 저장된다고 한다.

 

참고 :

github.com/ultralytics/yolov5/wiki/Tips-for-Best-Training-Results

towardsdatascience.com/yolo-v5-object-detection-tutorial-2e607b9013ef

github.com/ultralytics/yolov5

반응형