스크린샷 2018-11-07 오후 9.32.51

이번 포스트에서는 Realtime Object Detector로 가장 성능이 좋은 Joseph Redmondarknet YOLO를 이용하여 실시간으로 음식을 인식하는 Food Detector를 만들어보겠습니다.

YOLO

Yolo_How_it_Works2_700 darknet-53-architechture

YOLO는 간단한 구조 덕분에 처리 속도가 매우 빨라, Realtime Object Detector로 가장 적합합니다. 우리는 yolo_v3 모델을 사용하겠습니다.

Dataset - UEC-Food100

3-Figure4-1

음식 데이터셋은 일본 The University of Electro-Communications의 UEC-FOOD100을 사용합니다. 총 100개의 클래스에 대하여 약 1GB남짓한 적은 용량의 가벼운 데이터셋입니다. 정확도는 조금 낮더라도, 빠르게 실습하고 테스트해 볼 수 있는 장점이 있습니다.

UEC-FOOD100의 Dataset의 구조는 다음과 같습니다.

yolotree

각 클래스는 1~100의 폴더로 나뉘어져 있고, 각 클래스의 label을 적어둔 category.txt 파일이 있습니다. 각 폴더에는 음식사진들과 각 사진별 boundary box를 기술한 bb_info.txt파일이 들어있습니다.

학습을 하기 위해서는, 이 dataset을 YOLO가 원하는 형식으로 바꾸어주는 전처리 과정이 필요합니다. 전처리 과정은 다음과 같은 절차로 이루어집니다.

Dataset 전처리 과정

  1. yolo.cfg yolo 모델 수정하기
  2. Bounding Box 다시 정의하기
  3. label txt파일 생성하기
  4. train.txt, test.txt 생성하기
  5. *.data파일 생성하기

1. yolo 모델 다운받고 수정하기 (yolo.cfg)

UEC-FOOD100 Dataset은 총 100개의 class 되어있습니다. \ 따라서 yolo 모델에서 최종 output layer는 100개의 노드로 수정해주어야 합니다. 또한 직전 레이어의 filter 수 역시 바꾸어주어야 합니다. 그리고 input data의 형식에 맞도록 batch와 subdivision도 바꾸어줍니다.

저는 yolo v3를 사용하기로 했으므로, yolov3.cfg 파일을 다운로드 해줍니다. 만약 없다면, 아래 링크에서 다운로드해줍니다. GPU의 메모리 사이즈가 4GB이상이라면 yolov3모델을, 4GB 이하라면 tiny모델을 사용할 것을 추천합니다.

다운받은 파일을 cfg/폴더에 넣어줍니다.cfg파일을 복사 해서 yolov3-tiny.cfg 혹은 yolov3-tiny-food.cfg로 저장합니다. 그리고 파일을 열어 다음 절차를 따라 모델을 수정해줍니다.

1) batch 수정하기

2| [net]
3| batch = 64

batch를 64로 수정합니다. 이 뜻은 한 training step에 64개의 이미지를 사용하겠다는 뜻입니다.

2) subdivision 수정하기

4| subdivision = 8

subdivision을 8로 수정합니다. 이 뜻은 batch를 8개로 나누어 GPU 메모리 부하를 줄이겠다는 의도입니다.

3) classes 수정하기

- classes=80
+ classes=100

line 135, line 177에 class를 100으로 수정합니다.

4) filters 수정하기

+filters = 315

line 127, 177의 filters를 다음과 같이 계산하여 수정해줍니다.

2. bounding box 다시 정의하기

Screenshot from 2018-10-31 11-04-31

YOLO와 FOOD100 Dataset은 bounding box를 정의하는 방법이 다릅니다. YOLO는 box 중심 점의 좌표와 box의 width, height로 정의하는 반면 FOOD100 Dataset은 bounding box의 좌상단 점의 위치와 우하단 점의 위치로 정의합니다. 이를 고려하여 다시 기술해 줄 필요가 있습니다.

참 쉽죠?

3. 각 이미지 마다 label file 생성하기

Screenshot from 2018-10-31 11-06-51

YOLO는 각 이미지 마다 label, bounding box, category를 기록한 text파일을 원합니다. 위에서 계산한 bounding box를 바탕으로 생성해줍니다.

4. test.txt, train.txt 파일 만들기

Screenshot from 2018-10-31 11-14-15

YOLO는 test set과 train set의 파일 위치를 담고있는 txt 파일을 필요로 합니다. 각 클래스에 대하여 train set 80%, test set 20% 의 비율로 나누어주어 기록합니다. 이때 train set과 test set의 이미지는 따로 폴더를 나눌 필요 없습니다.

5. *.data 파일 생성하기

food100.data

classes= 100
train  = data/train.txt
valid  = data/test.txt
names = data/food100.names
backup = backup

YOLO는 클래스의 수, 데이터 셋의 위치, name 파일, weight와 checkpoint를 저장할 backup 폴더를 지정한 *.data파일을 설정해주어야 합니다. 위와 같은 파일을 생성하여 저장합니다.

6. pretrained weight 다운받고 저장하기

Imagenet에 대하여 학습된 pretrained weight를 적용하 학습을 진행하겠습니다.

7. 마지막으로 한번 더 확인하기

.
├── bin/
│   └── darknet53.conv.74   (or yolov3-tiny.conv.15)
├── cfg/
│   └── yolov3-food.cfg     (or yolov3-tiny-food.cfg)
├── data/
│   ├── images/
│   │   ├── 1
│   │   │   ├── *.jpg
│   │   │   └── *.txt
│   │   │   ...
│   │   └── 100
│   │       ├── *.jpg
│   │       └── *.txt
│   ├── labels/
│   │   ├── 1
│   │   │   └── *.txt
│   │   │   ...
│   │   └── 100
│   │       └── *.txt
│   ├── food100.names
│   └── food100.data
├── backup/

│
└── (bunch of darknet files)

지금까지 다운받고, 수정하고, 생성한 파일들이 올바른 위치에 들어있는지 확인합니다.

Let’s train!

자, 준비가 다 되었습니다. 이제 training을 시작해보겠습니다. 터미널에서 다음 명령어중 하나를 선택해 학습을 시작합니다.

for yolov3

# 학습하기
./darknet detector train data/food100.data cfg/yolov3-food.cfg bin/darknet53.conv.74

# 여러개의 GPU를 가지고 있다면
./darknet detector train data/food100.data cfg/yolov3-food.cfg bin/darknet53.conv.74 -gpus 0,1,2,3

# 저장된 Checkpoint로부터 다시 학습을 시작한다면
./darknet detector train data/food100.data cfg/yolov3-food.cfg backup/yolov3-food.backup -gpus 0,1,2,3

for yolov3-tiny

# 학습하기
./darknet detector train data/food100.data cfg/yolov3-tiny-food.cfg bin/yolov3-tiny.conv.15

# 여러개의 GPU를 가지고 있다면
./darknet detector train data/food100.data cfg/yolov3-tiny-food.cfg bin/yolov3-tiny.conv.15 -gpus 0,1,2,3

# 저장된 Checkpoint로부터 다시 학습을 시작한다면
./darknet detector train data/food100.data cfg/yolov3-tiny-food.cfg backup/yolov3-tiny-food.backup -gpus 0,1,2,3

output Peek 2018-09-03 08-54

학습이 잘 되네요!

언제까지 학습할 것인가?

언제까지 학습을 할 것인가에 대한 이야기도 빼놓을 수 없겠죠. overfitting되지 않는 시점..이 모범 답안이겠지만 그래도 좀 쉽게 알 수는 없을까요?

저자에 의하면 class당 2,000 iteration을 권하고 있습니다. 우리는 100개의 classes를 가지고 있으므로 200,000 iteration정도에서 train이 완료되겠네요.

Let’s Test!

train이 완료되었다면, weight파일이 생성이 되었을 것입니다. 바로 웹캠을 연결하고 테스트를 해봅니다.

#for yolov3
./darknet detector demo data/food100.data cfg/yolov3-food.cfg backup/yolov3-food_final.weights

#for yolov3-tiny
./darknet detector demo data/food100.data cfg/yolov3-food-tiny.cfg backup/yolov3-tiny-food_final.weights

## 잘 안된다면? threshold를 낮춰봅니다. 아래 옵션을 뒤에 추가합니다.
-thresh 0.1

Result

Test with yolov3-tiny & UEC FOOD-100 dataset

Test with yolov3 & UEC FOOD-100 dataset 스크린샷 2018-11-07 오후 9.32.51

yes! 잘 됩니다!

References and Further Reading

Comments

Eungbean Lee's Picture

About Eungbean Lee

Lee is a Student, Programmer, Engineer, Designer and a DJ

Seoul, South Korea https://eungbean.github.io