본문 바로가기

IT/Deeplearning

[Object Detection / Deeplearning ] YOLO Darknet v2 - [3]

이번 포스팅에서는 YOLO Darknet v2를 어떻게 학습시키는지에 대해서 포스팅하겠습니다.


[Object Detection / Deeplearning] YOLO Darknet v2 - [1]

[Object Detection / Deeplearning] YOLO Darknet v2 - [2]





기본적으로 YOLO Darknet 홈페이지에 어떻게 VOC Pascal Data를 이용해서 YOLO를 학습시키는지 확인할 수 있습니다.

이번 포스팅에서는 이를 따라하는 것에 대해서 포스팅하도록 하겠습니다.


1. DataSet Download :: VOC Pascal 2007/2012


먼저 다음과 같은 명령어를 이용해서 VOC Pascal 데이터를 다운로드를 받고, 압축을 해제해줍니다.


wget https://pjreddie.com/media/files/VOCtrainval_11-May-2012.tar
wget https://pjreddie.com/media/files/VOCtrainval_06-Nov-2007.tar
wget https://pjreddie.com/media/files/VOCtest_06-Nov-2007.tar

tar xf VOCtrainval_11-May-2012.tar
tar xf VOCtrainval_06-Nov-2007.tar
tar xf VOCtest_06-Nov-2007.tar


압축을 해제하였으면, 다운로드받은 파일의 디렉토리 구조는 다음과 같을겁니다.


VOCdevkit
├── VOC2007
│   ├── Annotations
│   ├── ImageSets
│   ├── JPEGImages
│   ├── SegmentationClass
│   └── SegmentationObject
└── VOC2012
    ├── Annotations
    ├── ImageSets
    ├── JPEGImages
    ├── SegmentationClass
    └── SegmentationObject


Object Detection을 학습시키기위해서 필요한 디렉토리 구조는 다음과 같습니다.


Annotations : Object Detection Label이 모여있는 파일입니다. 파일의 확장자는 .xml입니다.

JPEGImages : Object Detection의 학습 데이터의 사진들이 모여있습니다.


2. Convert to YOLO Darknet Format


이제, 여기서 Annotations 파일들을 YOLO Darknet이 필요로하는 Object Detection label로 변환하는 작업을 시작합니다.

이전 포스팅에서 이야기했듯이 Darknet 프로젝트를 클론하였다면, 다음과 같은 Darknet의 디렉토리 구조를 확인할 수 있습니다.


Darknet
├── cfg
├── darknet
├── data
├── examples
├── include
├── libdarknet.a
├── libdarknet.so
├── LICENSE.gen
├── Makefile
├── obj
├── python
├── results
├── scripts
└── src


여기서 Darknet이 필요로하는 Object Detection label format으로 변환해주는 스크립트파일은 Scripts폴더에 있습니다.

Scripts 폴더에 들어가서 확인해보면 다음과 같은 Scripts폴더의 디렉토리 구조를 확인할 수 있습니다.


scripts
├── dice_label.sh
├── gen_tactic.sh
├── get_coco_dataset.sh
├── imagenet_label.sh
└── voc_label.py


여기서 우리가 사용할 스크립트파일은 voc_label.py입니다.

해당 스크립트를 아까 VOC 데이터셋 폴더 VOCdevkit의 상위폴더로 옮깁니다.

스크립트 파일을 VOCdevkit의 상위폴더로 옮기게되면, 스크립트폴더와 VOCdevkit의 폴더 디렉토리 구조는 다음과 같게 됩니다.


.
├── VOCdevkit
└── voc_label.py


위와 같이 파일이 위치한 것을 확인하였다면, 다음과 같은 명령어를 실행합니다.


#
python voc_label.py
#


만약에 성공적으로 변환이 되었다면, 디렉토리 구조가 다음과 같을 겁니다.


.
├── 2007_test.txt
├── 2007_train.txt
├── 2007_val.txt
├── 2012_train.txt
├── 2012_val.txt
├── VOCdevkit
└── voc_label.py


그럼 이를 다음과 같은 명령어를 통해서 파일을 하나로 합쳐줍니다.


cat 2007_train.txt 2007_val.txt 2012_*.txt > train.txt


명령어가 잘 작동했다면, 디렉토리에 train.txt파일이 추가된 것을 확인할 수 있습니다.


.
├── 2007_test.txt
├── 2007_train.txt
├── 2007_val.txt
├── 2012_train.txt
├── 2012_val.txt
├── train.txt
├── VOCdevkit
└── voc_label.py


train.txt파일을 열어보면 다음과 같은 내용들이 적혀있습니다.

내용을 잘 보면 학습할 학습 이미지들의 위치가 빼곡히 적혀있음을 확인할 수 있습니다.


/media/martin/DataSet/VOC/VOCdevkit/VOC2007/JPEGImages/000012.jpg
/media/martin/DataSet/VOC/VOCdevkit/VOC2007/JPEGImages/000017.jpg
/media/martin/DataSet/VOC/VOCdevkit/VOC2007/JPEGImages/000023.jpg
/media/martin/DataSet/VOC/VOCdevkit/VOC2007/JPEGImages/000026.jpg
/media/martin/DataSet/VOC/VOCdevkit/VOC2007/JPEGImages/000032.jpg
.
.
.


3. Ready for Train

3-1. voc.data 설정

이제 데이터는 준비가 모두 되었습니다.

이제 다시 YOLO Darknet의 디렉토리로 돌아와서, Darknet 디렉토리안의 cfg 폴더를 봅시다.


Darknet
├── cfg
│   ├── alexnet.cfg
│   ├── cifar.cfg
│   ├── cifar.test.cfg
│   ├── coco.data
│   ├── combine9k.data
│   ├── darknet19_448.cfg
│   ├── darknet19.cfg
│   ├── darknet9000.cfg
│   ├── darknet.cfg
│   ├── densenet201.cfg
│   ├── extraction22k.cfg
│   ├── extraction.cfg
│   ├── extraction.conv.cfg
│   ├── go.cfg
│   ├── go.test.cfg
│   ├── gru.cfg
│   ├── imagenet1k.data
│   ├── imagenet22k.dataset
│   ├── imagenet9k.hierarchy.dataset
│   ├── jnet-conv.cfg
│   ├── resnet152.cfg
│   ├── resnet50.cfg
│   ├── rnn.cfg
│   ├── rnn.train.cfg
│   ├── strided.cfg
│   ├── t1.test.cfg
│   ├── tiny.cfg
│   ├── tiny-yolo.cfg
│   ├── tiny-yolo-voc.cfg
│   ├── vgg-16.cfg
│   ├── vgg-conv.cfg
│   ├── voc.data
│   ├── writing.cfg
│   ├── yolo.2.0.cfg
│   ├── yolo9000.cfg
│   ├── yolo.cfg
│   ├── yolov1
│   ├── yolo-voc.2.0.cfg
│   └── yolo-voc.cfg
.
.
.


이번에 우리가 봐야하는 것은 voc.data라는 파일입니다.

voc.data파일을 살펴보면 다음과 같습니다.


Classes : 디텍팅할 클래스 종류 (20가지)

train : train.txt 위치 

-> 2. convert to yolo data format에서 나온 결과 파일의 위치를 의미합니다.

valid : valid.txt 위치

-> 2. convert to yolo data format에서 나온 결과 파일의 위치를 의미합니다.

names : label list 파일 위치

backup : 학습하면서 중간중간 가중치 파일들과 최종 학습 완료된 가중치파일을 저장할 위치


classes= 20
train  = /home/pjreddie/data/voc/train.txt
valid  = /home/pjreddie/data/voc/2007_test.txt
names = data/voc.names
backup = backup


이제 우리는 여기에서 classes, train, valid names과 backup의 위치를 확인해줘야합니다.

일단 voc pascal은 학습데이터에 20가지의 클래스가 있으므로 20이 맞습니다.

train과 valid의 위치는 아까 변환했던 위치를 넣어줍니다.

이번 포스팅에서 저의 경우에는 train과 valid의 위치는 다음과 같습니다.

names파일은 Darknet 디렉토리의 data폴더에 있으니, 그대로 둡니다.

그리고 Darknet 디렉토리에 가중치를 저장할 용도의 backup이라는 이름을 갖는 폴더를 하나 만듭니다.


train  = /media/martin/DataSet/VOC/train.txt
valid  = /media/martin/DataSet/VOC/2007_val.txt


3-2. voc.names

voc.names파일은 voc pascal의 각각 클래스의 이름을 적어놓은 파일입니다.

내용은 다음과 같습니다.

읽어보면, 20개의 클래스에 대한 이름들이 각자 적혀있는 것을 확인할 수 있습니다.


aeroplane
bicycle
bird
boat
bottle
bus
car
cat
chair
cow
diningtable
dog
horse
motorbike
person
pottedplant
sheep
sofa
train
tvmonitor


3-3. Pretrained model download

transfer learning을 위해서 다크넷 디렉토리 안에서 다음과 같은 명령어를 이용해서 

darknet19_448.conv.23 가중치 파일을 다운받습니다.


wget https://pjreddie.com/media/files/darknet19_448.conv.23


3-4. cfg파일 설정

Darknet 디렉토리안의 cfg폴더에서 yolo-voc.cfg 파일을 보면 다음과 같은 내용을 확인할 수 있습니다.

[net]
# Testing
batch=1
subdivisions=1
# Training
# batch=64
# subdivisions=8
height=416
width=416
channels=3
momentum=0.9
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1

learning_rate=0.001
burn_in=1000
.
.
.

여기서 # Testing 밑의 batch와 subdivisions에 #이라는 주석처리를 해주고, # Training 밑의 batch와 subdivisions의 
#이라는 주석을 지워줍니다. 그러면 다음과 같은 cfg 파일의 설정이 완료되게 됩니다.

[net]
# Testing
# batch=1
# subdivisions=1
# Training
batch=64
subdivisions=8
height=416
width=416
channels=3
momentum=0.9
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1

learning_rate=0.001
burn_in=1000
.
.
.


4. Train

이제 학습할 준비가 모두 끝났습니다.

이제 다음 명령어를 통해서 YOLO Darknet을 VOC Pascal 데이터를 이용하여 학습합니다.


./darknet detector train cfg/voc.data cfg/yolo-voc.cfg darknet19_448.conv.23


학습을 진행하면 다음과 같은 화면을 볼 수 있으며, 적당한 학습이 완료되고 나서는 

backup폴더에 가중치 파일들이 다음과 같이 저장되는 것을 확인할 수 있습니다.




5. Issue

만약에 학습을 시켰는데, 다음과 같은 메모리 에러가 뜬다면, 그래픽카드의 메모리가 부족해서 그럴 수 있으므로, 

3-4)의 cfg파일 설정에서 batch의 크기를 조금 줄여주고, subdivision의 크기를 키워주시면 됩니다. (ex> batch :  32...16....8....4....2 subdivision : 8....16...32....64)





이번 포스팅에서는 YOLO Darknet v2를 어떻게 학습시키는지 포스팅하였습니다.

다음 포스팅에서는 YOLO Darknet의 학습 label과 VOC Pascal Format의 xml포맷이 어떻게 구성이 되어있고

이것이 어떤 의미를 갖는지 포스팅하도록 하겠습니다.