개발 관련/SW, App 관련

Yolov3을 이용한 Unity 사물인식 제작 정리(3)

소서리스25 2024. 11. 11. 12:47
반응형

Yolov3을 이용한 Unity 사물인식 제작 정리(3)

 

5. 커스텀 데이터셋 준비

 

보통의 Yolo를 쓰면 미리 훈련된 모델들을 가지고 많이들 사용한다. 다양한 훈련 모델들이 있어서 플랫폼에 맞춰서 적절하게 사용되고 있다.

 

하지만 본인이 여기서 다루고자 하는 것은 원하는 데이터를 기반으로 훈련하는 것이다. 이게 가장 큰 목적이다.

로봇이 플라스틱 병이나 우유팩 같은 것을 인식하여 물건을 잡고 이를 분리수거함으로 운반하여 넣는 것이 최초의 목적으로 시작하게 되었다. 이는 지금도 진행 중이다.

 

훈련데이터에서 준비되어할 것은 다음과 같다. Darknet 실행파일이 있는 위치에 data 폴더가 있다.

훈련 준비 폴더

 

obj 폴더에 훈련할 이미지와 label 정보 텍스트가 들어가야 한다. 하나의 이미지당 하나의 label 정보 텍스트가 따른다.

훈련할 이미지와 label 정보

 

obj.data 에는 아래와 같이 각각의 훈련 정보를 지정하는 파일이다.

classes= 2
train  = data/train.txt
valid  = data/test.txt
names  = data/obj.names
backup = backup/

* 인식하도록 지정만 한다면 파일명은 달라도 상관없다.

 

object.names는 classes에서 지정한 만큼의 객체이름을 작성하면 된다.(최종 인식되었을 때 나타날 텍스트)

object
rbox

 

train.txt에는 훈련할 이미지들의 위치이다. Darknet 실행파일의 위치를 기준으로 폴더와 이미지의 파일명이 기록되어 있어야 한다.

훈련할 이미지의 경로

 

그러면 순차적으로 설명하면 우선 인식할 이미지는 준비되어 있을 것이다. 이 이미지에서 정확히 어떤 것을 인식시킬 것인지에 대해 label을 정해 주어야 한다.

 

이를 편하게 도와주는 것으로 관련 웹사이트도 있겠지만 소개할 python 패키지는 LabelImg로 다음과 같다. 

GitHub - HumanSignal/labelImg: LabelImg is now part of the Label Studio community. The popular image annotation tool created by Tzutalin is no longer actively being developed, but you can check out Label Studio, the open source data labeling tool for images, text, hypertext, audio, video and time-series data.

 

GitHub - HumanSignal/labelImg: LabelImg is now part of the Label Studio community. The popular image annotation tool created by

LabelImg is now part of the Label Studio community. The popular image annotation tool created by Tzutalin is no longer actively being developed, but you can check out Label Studio, the open source ...

github.com

 

위의 git에서 다운로드하여 적절한 폴더에 넣고 아래와 같이 setup를 먼저 실행하고 프로그램을 실행한다.

python setup.py
python labelImg.py

 

실행하다 패키지가 없다며 오류가 날 수 있다. 잘 보고 해당 패키지를 설치해 주면 된다. 예를 들어 pyqt5, pillow 같은 것..

 

실행하면 다음과 같은 화면을 볼 수 있다.

labelImg

 

labelImg에서 먼저 설정해야 할 것이 위에 표시한 것처럼 Yolo 모델로 변경해 주는 것이다. 누를 때마다 모델이 변경된다.

 

그다음으로 Open Dir을 통해 아까의 훈련할 이미지가 있는 폴더를 지정하는 것이다. 그러면 다음과 같은 화면이 나타날 것이다.

labelImg 의 이미지 로딩 화면

 

이제 여기서 인식할 영역을 박스로 그려주면 된다. Edit나 좌측 하단의 Create RectBox에서 원하는 박스를 그려주면 된다. 또는 단축키로도 사용할 수 있다. 가장 많이 사용하는 것이 "w, d, a, Ctrl+S" 정도..

단축키 리스트

 

그리고 여기에서 중요한 사항이 현재의 이미지에 대한 label을 정하는 것이다. 

label 정하기

 

그렇게 해서 모든 이미지들을 labelImg를 통해서 지정해 주어야 한다. 막일이 따로 없다..;;

일반적인 도구라 어렵지 않지만 자세한 사용방법은 git에서 확인해 보면 된다.

 

그러면 훈련을 시작해야 하는데 아시다시피 훈련할 이미지가 몇 장 안 된다면 상관없겠으나 너무 적게 하게 되면 인식이 제대로 될 수 없다. 본인도 처음 50여 장으로 했으나 인식률이 너무 처참했다. 그래서 최종 437장을 준비했다. 그랬더니 좀 나아졌다.;;

 

그런데 문제는 저 이미지들을 모두 train.txt에 경로와 파일명을 기록해야 하는 사항이 있다.

여기서 우리를 도와줄 python 명령어가 있다. 물론 이미지 관리도구나 기타 파일 관리도구를 이용할 수도 있겠으나 일단 python을 이용하는 것이 더 편리하다고 생각 된다. 간편하니까...

 

다음의 코드를 filename.py로 저장하고 python에서 실행해 보자.

import os

f = open("filenames.txt", 'w')

filenames = os.listdir("./obj")

for filename in filenames:
    data = "data/obj/"+filename+"\n"
    f.write(data)

print("Saved")
f.close()

 

obj내의 이미지 파일들을 우리가 원하는 경로와 파일명으로 filenames.txt에 한 번에 저장해 준다.

바로 train.txt로 해도 되지만 한번 확인하고 사용하면 된다.

 

이제 커스텀데이터셋 준비는 완료되었다.

 

 

6. Darknet 훈련

 

이제 주어진 데이터를 토대로 Darknet으로 훈련을 시작해 보도록 한다.

 

먼저 훈련하기 위해서는 어떻게 훈련할 것인지에 대한 훈련 정보가 있는 cfg를 설정해야 한다.

다음은 yolov3-tiny.cfg 파일 내용인데 이를 환경에 맞춰 수정해 줘야 한다.

[net]
batch=64
subdivisions=16
width=416
height=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
max_batches = 4000
policy=steps
steps=3200,3600
scales=.1,.1

 

[net]의 설정

batch = 64(기본값)

subdvisions = 8(기본값) 메모리 오류등이 발생했을 때 16, 32, 64로 조절하여 학습

width, height = 416(기본값) 해상도에 맞추기

max_batches = 4000 (보통 class 수 x 2000으로 한다고 함)

steps = 3200, 3600 (보통 80%, 90% 정도로 한다고 함)

 

다음으로 중요한 yolo 설정으로 약 119줄부터 끝까지의 내용이 아래와 같다.

[convolutional]
size=1
stride=1
pad=1
filters=21
activation=linear

[yolo]
mask = 3,4,5
anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
classes=2
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1

[route]
layers = -4

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[upsample]
stride=2

[route]
layers = -1, 8

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[convolutional]
size=1
stride=1
pad=1
filters=21
activation=linear

[yolo]
mask = 0,1,2
anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
classes=2
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1

 

[yolo] 내의 classes 값은 인식할 객체의 수를 입력하면 된다.

 

그리고 fillters의 내용을 수정해 주어야 한다. convolutional의 activations=liner가 포함된 그룹의 fillters는 모두 수정해 준다.

fillters의 값을 정하는 기준은 다음과 같다.

#class 수에 따른 fillters 값 설정

*예 class = 1
yolo v2: (5 + class 수) x 5 = 30
yolo v3: (5 + class 수) x 3 = 18

*예 class = 2
yolo v2: (5 + 2) x 5 = 35
yolo v3: (5 + 2) x 3 = 21

 

나머지는 일단 그대로 두면 된다. 세부적인 것은 잘 모르니 더 찾아보고 공부해 봐야 한다.

 

이제 훈련 준비는 다 되었다.

Darknet.exe가 있는 폴더로 anaconda prompt를 통해 대기한다.

다음과 같은 명령어로 훈련을 시작해 본다.

darknet detector train data/obj.data yolov3-tiny.cfg yolov3-tiny.weights -dont_show -clear

 

훈련이 시작되면 다음과 같은 화면으로 진행이 된다.

darknet 훈련

 

훈련이 끝나면 최종적으로 yolov3-tiny_filnal.weights의 훈련결과 가중치 파일이 생성된다. 물론 중간에 설정해 놓은 1000 단위마다 생성되지만 우리가 필요한 것은 저 final이다.

 

 

다음 포스팅에서 계속...

 

 

반응형