앞에서 라벨링한 데이터를 가지고 YOLO의 원본모델을 커스텀하여 모델학습을 진행하였다. 학습 알고리즘을 가지고 있는 yolo모델에서 학습데이터만 바꾸어 인식하길 원하는 물체만 인식하도록 학습시키는 것이다. 학습을 진행하는 동안 gpu를 지원받기 위해 코랩에서 노트를 gpu로 설정한 뒤 학습하였다. 구글 드라이브에 직접 제작한 데이터셋을 업로드하고 darknet파일을 git clone으로 다운받은 뒤 훈련에 필요한 파일들을 목적에 맞게 변경하여 각 폴더에 함께 업로드하였다.
a. custom cfg (yolov4-tiny-custom.cfg)
yolov4-tiny-custom.cfg
darknet/cfg 폴더에 있는 yolov4-tiny.cfg파일을 다운받아 훈련설정을 조정하여 yolov4-custom.cfg파일로 변경하였다.
max_batch값을 (class 수*2000)으로 하여 iteration을 max_batch번 진행하였다.
width와 height(해상도)는 모두 416으로 하였으며 이 값을 낮춰서 훈련시킬 시에 fps가 빨라지고 이 값을 높여서 훈련시킬 시에 정확도가 증가한다. gpu는 코랩에서 지원받아 한 개만 사용하므로 learning rate는 0.001로 설정해주었다.
해당 파일에서 ctrl+f를 이용해 [yolo]를 찾으면 총 세부분이 나온다. 이 부분의 classes값을 훈련시키고자 하는 class의 개수로 바꾸어주고 이제 그 바로 위의 [convolutional] 부분의 filters값을 바꿔야한다. filter의 값은 보통 filters=(classes + 5)x3으로 한다. (yolo를 찾으면 나오는 세부분을 모두 바꿔줘야한다. )
argumentation 추가
채도 추가 - saturation = 1.5
노출 추가 - exposure = 1.5
색상 변경 - hue=.1
b. obj.data (훈련에 필요한 파일들의 경로정보)
obj.data
다음과 같이 훈련에 필요한 파일들의 경로정보를 넣어준다. train.txt, test.txt, obj.names파일이 훈련할 때 필요한 파일이다. train.txt와 test.txt는 뒤에 process.py 코드를 통해 생성하게 된다. 훈련을 실행하면 1000 iteration마다 학습된 모델의 weight파일을 저장해준다. 이때 이 weight파일이 저장되는 경로가 backup경로이다.
c.obj.names (class 이름정보)
obj.names
d. process.py (데이터셋의 경로를 가져와 train.txt파일과 test.txt파일을 생성하는 코드)
해당 코드는 아래 올려놓은 유튜브 영상 더보기란에서 다운받을 수 있다.
train.txt, test.txt 파일이 생성되지 않는 경우
필자는 여기서 처음 문제가 발생했다. 각 경로에 yolov4-tiny-custom.cfg, obj.data, obj.names, process.py 를 집어넣고 process.py를 실행하면 train.txt 와 test.txt 파일이 폴더에 생겨야 하는데 아무리 코드를 실행해도 텍스트파일이 생성되지 않았다. 이 파일들은 모델을 학습시킬때 각 이미지의 경로를 가르쳐주는 파일이기 때문에 이 파일이 생성되지 않으면 학습할 이미지가 없다고 판단하고 학습이 진행되지 않는다. 에러의 이유는 process.py코드 내에 있었다.
코드 맨 아래쪽에 이미지파일을 찾을 때 'jpeg'파일을 찾도록 되어있는 경우가 있다. 이때 이를 'jpg'로 바꾸어주고 다시 실행하면 바로 원하는 파일이 생성된다. (원래 했을땐 잘됐는데 갑자기 이런 에러가 생겨서 원인찾는데 진짜 오래걸렸다;;)
이제 모든 파일이 준비되었으면 코랩 코드를 따라 순차적으로 실행시키면 된다.
모델학습 실행코드
해당 코드를 실행하면 모델학습이 진행된다. 데이터셋의 양에 따라 4시간~6시간 정도 훈련시간이 걸린다.
** 따라서 중간에 코랩의 런타임이 끊기면 학습이 중단된다... 1000 iteration이 넘어가서 중간 weight파일이 저장되면 그부분부터 다시 학습할 수는 있지만 보통 그전에 런타임이 끊긴다. 이를 방지해주기 위해 콘솔창에 자바스크립트 코드를 추가해주어야 한다.
1. 코랩을 연 뒤 f12를 누르면 다음과 같은 창이 나타난다.
f12
2. 상단의 console 탭을 눌러준다. 코드를 칠 수 있는 부분에 다음 코드를 복붙한 뒤 엔터를 눌러주면 된다.
60초마다 ClickConnect() 함수를 실행시켜준다.
function ClickConnect(){ console.log("코랩 연결 끊김 방지"); document.querySelector("colab-toolbar-button#connect").click() } setInterval(ClickConnect, 60 * 1000)
(코랩에서 gpu를 지원받을 수 있는 시간은 하루 최대 12시간이니 너무 방대한 양의 학습은 어려울 수 있다. 필자의 경우는 15000장의 데이터셋을 학습시키는데 6~8시간 정도 걸렸던 것 같다. )
2. 물체인식 정확도 개선과정
i. 제안발표에서 학습시켰던 학습모델은 yolov4모델로 test용 curry와 rice 학습
->다각도에서 정확하게 인식했으나 인식속도가 너무 느림
yolov4-tiny 모델로 학습시킨 뒤 정확도를 높이는 방향으로 학습을 진행하였다.
ii. yolov4-tiny 모델로 curry와 rice 학습
->iteration이 약 1000번을 넘자마자 훈련 mAP(정확도)가 100%로 일정함
curry의 최종정확도는 100%, rice의 최종정확도는 99.29%
이는 과대적합으로 의심할 수 있었고 실제 테스트 결과에서도 화면 뒷배경을 물체로 인식하는 일이 발생,
이를 해결하기 위해 각 class 별로 더 많은 양의 데이터를 수집해 진행하였다.
과대적합(overfitting): 모델이 훈련 데이터에 너무 잘 맞지만 일반성이 떨어진다는 의미로, 훈련 데이터와 비슷한 환경의 데이터는 정확히 검출하지만 배경색이 비슷하지 않은 데이터는 정확도가 떨어지는 현상이 발생한다. - 해결법 1. 다양한 훈련 데이터를 더 많이 수집 2. 정규화(Regularization) 이용
iii. yolov4-tiny 모델로 모든 class(curry, rice, cupnoodle, chicchoc, powerade, zerocider, kancho, gagrin) 학습
->모든 class를 학습시키니 정확도가 현저히 떨어지는 것을 확인
최종 mAP가 85.14%가 나왔고 그 중 CupNoodle과 zerocider의 정확도가 81.34%와 80%로 낮은 것을 확인, 테스트결과 cupNoodle을 kancho로 인식하거나 zerocider를 gargrin으로 인식하는 등 비슷한 부분이 있는 물체는 혼동하는 문제를 발견할 수 있었다. 이는 데이터를 수집하는 과정에서 동영상을 jpg파일로 자를 때 화질저하가 생긴 것을 원인으로 보고 CupNoodle과 kancho, zerocider, powerade 데이터를 고화질로 약 2000개씩 추가로 생성 또한 해당 물체를 더욱 다양 한 각도에서 촬영하였다.
iv. yolov4-tiny 모델로 추가 라벨링 데이터를 넣고 최종학습(curry, rice, cupnoodle, chicchoc, powerade, zerocider, kancho)
->최종 mAP가 97.62%로 향상된 결과를 보임
테스트시 각 class 물품을 정확히 인식하는 것을 확인하였고 인식속도 또한 준수한 것을 확인할 수 있었다.