반응형

Ubuntu에서 darknet을 사용하여 Yolo v4 커스텀 학습하는 방법을 다루고 있습니다. 



2021. 05. 16  최초작성

2021. 05. 28  

2023. 9. 10  Ubuntu 22.04에서 진행



darknet 설치후 Yolo v4 테스트



0. CUDA 및 OpenCV를 먼저 설치해야 합니다.



Ubuntu 22.04에 CUDA 사용하는 OpenCV 설치하는 방법

https://webnautes.blog/2153/ 



.bashrc파일을 열어서  다음 내용을 끝에 추가합니다.

 

$ gedit  ~/.bashrc

 

export PATH="/usr/local/cuda-11.8/bin:$PATH"



환경에 적용한 후, nvcc가 실행되는지 확인합니다.

 

$ source ~/.bashrc

 

$ nvcc -V

nvcc: NVIDIA (R) Cuda compiler driver

Copyright (c) 2005-2022 NVIDIA Corporation

Built on Wed_Sep_21_10:33:58_PDT_2022

Cuda compilation tools, release 11.8, V11.8.89

Build cuda_11.8.r11.8/compiler.31833905_0




1. darknet 프로젝트를 다운로드합니다. 

 

webnautes@webnautes-laptop:~$ git clone https://github.com/AlexeyAB/darknet.git



실행했을때 에러가 난다면 git 설치가 필요할 수도 있습니다. 

 

webnautes@webnautes-laptop:~$ sudo apt-get install git 



2. Makefile에서 다음 부분들의 값을 1로 수정합니다. 

( CUDNN_HALF 옵션을 켜면 학습은 되지만 darknet을 사용하여 인식이 안되서 0으로 했습니다.

OpenCV DNN 모듈을 사용시에는 됩니다. 

이 옵션들을 0으로 하면 학습시 속도가 하향되는 듯합니다. )



편집기로 Makefile을 열어서…

 

webnautes@webnautes-laptop:~$ cd darknet

webnautes@webnautes-laptop:~/darknet$ gedit Makefile 



다음처럼 1로 수정합니다.

 

GPU=

CUDNN=

CUDNN_HALF=0 

OPENCV=1 

AVX=0 

OPENMP=0 

LIBSO=1



3. make 명령을 사용하여 빌드합니다. 

 

webnautes@webnautes-laptop:~/darknet$ make




4. 테스트를 위해 yolov4.weights를 다운로드 받아 현재 디렉토리로 가져옵니다. 

 

https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights 

 

webnautes@webnautes-laptop:~/darknet$  mv ~/다운로드/yolov4.weights .



5. 예제를 실행시켜봅니다.



이미지

./darknet detect cfg/yolov4.cfg yolov4.weights data/dog.jpg

 




웹캠

./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights -c 0




잘 실행되다가 다음과 같은 에러가 나면서 안되는 경우 재부팅이 필요합니다.

 

"cuDNN Error: CUDNN_STATUS_EXECUTION_FAILED" 




커스텀 데이터 학습



홈 디렉토리로 이동합니다. 

 

$ cd



테스트를 위해 폴더를 생성합니다. 

 

$ mkdir custum_yolo_test



새로 생성한 폴더에 img 폴더를 생성하여 이곳에 학습할 이미지를 JPG 확장자로 저장합니다. 

 

$ cd custum_yolo_test

 

$ mkdir img




 다음처럼 2개의 이미지 파일을 복사해두었습니다. 

 

webnautes@webnautes-laptop:~/custom_yolo_test/img$ ls

IMG_2157.jpg  IMG_2160.jpg





홈 디렉토리로 이동합니다. 

 

$ cd



이미지 어노테이션 도구

https://github.com/AlexeyAB/Yolo_mark



이미지 어노테이션 도구 Yolo mark를 다운로드하여 빌드합니다. 

 

webnautes@webnautes-laptop:~$ git clone https://github.com/AlexeyAB/Yolo_mark.git

webnautes@webnautes-laptop:~$ cd Yolo_mark

webnautes@webnautes-laptop:~/Yolo_mark$ cmake .

webnautes@webnautes-laptop:~/Yolo_mark$  make



현재 위치에 obj.names 이름으로 파일을 열어서 학습할 물체의 이름을 적어줍니다. 

여기에선 펜을 인식할거라서 다음처럼 생성했습니다. 

 

webnautes@webnautes-laptop:~/Yolo_mark$ gedit obj.names



파일 내용을 확인해봅니다.

 

webnautes@webnautes-laptop:~/Yolo_mark$ cat obj.names 

pipe




이미지 위치를 지정하여 다음처럼 실행합니다. 

 

webnautes@webnautes-laptop:~/Yolo_mark$ ./yolo_mark ~/custom_yolo_test/img/ ./train.txt ./obj.names



마우스로 드래그하면 사각형이 그려집니다. 

라벨 아이디가 0이고 이름이 pen이라는 것을 볼 수 있습니다. 

 

라벨 개수가 2개 이상인 경우에는 그리기전에 원하는 번호로 바꾼 후,  그리면 됩니다. 

예를 들어 obj.names의 두번째 줄에 mouse를 입력했다면  1을 누르고 마우스로 그리면 1 - mouse라고 표시됩니다. 

 

사각형을 그린 후, 스페이스바를 누르면 다음 이미지로 이동합니다.

배경만 학습 이미지에 추가할 경우 사각형을 안그리고 스페이스바를 누를 필요도 있습니다.

그러면 빈 텍스트 파일이 생성됩니다. 

 

주의할 점은 스페이스바를 눌러야 현재 이미지파일에 대한 어노테이션이 파일로 저장된다는 것입니다. 

 

상단에 썸네일로 이미지 목록이 보여집니다. 왼쪽 끝이 현재 보고 있는 이미지입니다. 

어노테이션이 저장되면 썸네일에 초록색 기호로 표시됩니다. 

 

어노테이션을 지우려면 c를 누르면 됩니다. 자세한 사용방법은 h를 눌러 확인하세요. 

 



터미널에 다음과 같은 정보가 표시됩니다. 

 

txt ./obj.names   <- 학습할 객체 이름이 저장된 파일입니다.

File opened for output: ./train.txt  <- 어노테이션한 이미지 파일 목록이 저장됩니다. 

File loaded: ./obj.names   <- 학습할 객체 이름을 불러왔다는 의미입니다. 

 trackbar_value = 0 <- 첫번째 이미지이므로 인덱스가 0입니다.

txt_filename_path = /home/webnautes/custom_yolo_test/img//IMG_2157.txt <- 첫번째 이미지 파일의 어노테이션 정보가 저장된 파일입니다. 

 trackbar_value = 1 <- 두번째 이미지이므로 인덱스가 1입니다.

txt_filename_path = /home/webnautes/custom_yolo_test/img//IMG_2160.txt <- 두번째 이미지 파일의 어노테이션 정보가 저장된 파일입니다. 



해당 파일을 확인해보면 첫번째 항목은 라벨 아이디이고 두번째 이후 항목은 사각형 위치 정보입니다. 

 

webnautes@webnautes-laptop:~/Yolo_mark$ cat /home/webnautes/custom_yolo_test/img//IMG_2157.txt

0 0.462109 0.490278 0.174219 0.916667



두번째 이미지도 사각형을 그려줍니다. 첫번째 트랙바가  오른쪽 끝에 있는 것은 모든 이미지를 다봤다는 의미입니다.

 



스페이스바를 눌러 현재 어노테이션을 저장하고 ESC키를 누르면  프로그램이 종료됩니다.



현재 디렉토리에 어노테이션이 된  이미지 파일 목록이 저장된 train.txt 파일이 생성되어 있습니다. 

 

webnautes@webnautes-laptop:~/Yolo_mark$ cat train.txt 

/home/webnautes/custom_yolo_test/img//IMG_2157.jpg

/home/webnautes/custom_yolo_test/img//IMG_2160.jpg





이제 학습을 진행합니다. 

 

앞에서 만들었던 폴더로 이동합니다. 

webnautes@webnautes-laptop:~/Yolo_mark$ cd ~/custom_yolo_test/

webnautes@webnautes-laptop:~/custom_yolo_test$ 




darknet 디렉토리에서 필요한 파일을 복사합니다.  

webnautes@webnautes-laptop:~/custom_yolo_test$ cp ~/darknet/darknet .

webnautes@webnautes-laptop:~/custom_yolo_test$ cp ~/darknet/cfg/yolov4.cfg yolo-obj.cfg



별도의 디렉토리를 만들어야 합니다. 이곳에 학습 결과가 저장됩니다. 

 

webnautes@webnautes-laptop:~/custom_yolo_test$ mkdir backup



data 디렉토리 생성하고 obj.data 파일을 생성하여 다음 내용 입력합니다. 

 

webnautes@webnautes-laptop:~/custom_yolo_test$ mkdir data

webnautes@webnautes-laptop:~/custom_yolo_test$ gedit data/obj.data




classes에 학습할 물체의 종류 개수를 의미하는 클래스 개수를 적어줍니다.

여기에선 한가지 물체이므로 1입니다. 

 

valid 항목에는 test.txt로 적어줘야 하는데 여기에선 train.txt를 사용했습니다. 

학습할 이미지 파일의 20% 정도를 test.txt에 적어줘야 합니다.  

 

classes = 1
train  = data/train.txt
valid  = data/train.txt
names = data/obj.names
backup = backup/




어노테이션했던 디렉토리에서 필요한 파일을 복사합니다. 

webnautes@webnautes-laptop:~/custom_yolo_test$ cp ~/Yolo_mark/train.txt ./data/

webnautes@webnautes-laptop:~/custom_yolo_test$ cp ~/Yolo_mark/obj.names ./data/




yolo-obj.cfg을 수정합니다. 

 

gedit yolo-obj.cfg




subdivisions를 64로 수정합니다.

 

subdivisions = 64





width, height를 416으로 수정합니다.  32의 배수로 적으면 됩니다.

 

width=416

height=416




max_batches는 클래스 갯수 * 2000 

1개의 클래스라면 1*2000 = 2000

이 수치는 최소 추천 iter이므로 더 추가 가능하며  추가한 만큼 steps 수정 필요합니다.

max_batches = 2000




steps는 max_batches의 80%와 90%를 적어주면 됩니다.

 

2000 * 0.8 = 1600

2000 * 0.9 = 1800

 

steps=1600,1800




Ctrl + F 로 yolo를 검색하면 3군데 있습니다. 다음 값들을 모두 바꿔줘야 합니다.

여기에선 클래스 개수를 1로 수정합니다.

 

classes=1



yolo 항목 바로 위에 있는 convolutional 항목에 있는 filters를 다음 수식으로 계산하여 넣습니다.

이것도 3군데 있습니다.

filters=(classes + 5)x3)

 

(1 + 5) x 3 = 18

 

filters=18




다음처럼 anchor 계산하여 3군데 입력해 줍니다.

width와 height는 앞에서 입력한 이미지 크기와 일치해야 합니다.

./darknet detector calc_anchors data/obj.data -num_of_clusters 9 -width 416 -height 416

 

num_of_clusters의 인자로 9 사용

width와 height는 위에서 적은 값과 동일하게 416 

 

이미지 개수가 적으면 세그멘테이션 오류 에러가 날 수 있습니다. 

 

https://stackoverflow.com/a/55292318/15850881

 

anchors = 




다시 진행시  num_of_clusters의 값을 9로하면 세그멘테이션 오류가 발생하여 6으로 변경하여 진행했습니다.  anchors에 있는 값을 복사하여 yolo-obj.cfg의 anchors 항목에 붙여넣기 해줍니다.

 

webnautes@webnautes-laptop:~/custom_yolo_test$ ./darknet detector calc_anchors data/obj.data -num_of_clusters 6 -width 416 -height 416

 CUDA-version: 11080 (12000), cuDNN: 8.7.0, GPU count: 1  

 OpenCV version: 4.6.0

 

 num_of_clusters = 6, width = 416, height = 416 

 read labels from 2 images 

 loaded image: 2 box: 2

 all loaded. 

 

 calculating k-means++ ...

 

 iterations = 1 



counters_per_class = 2

 

 avg IoU = 100.00 % 

 

Saving anchors to the file: anchors.txt 

anchors =  72,381,  72,381,  72,381,  72,381,  72,381, 401,102




yolov4의 pretrain모델을 다운로드하여 custom_yolo_test/에 저장해야 합니다. 

 

 webnautes@webnautes-laptop:~/custom_yolo_test$ wget  https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.conv.137 




이제 학습을 시작합니다. 

 

webnautes@webnautes-laptop:~/custom_yolo_test$./darknet detector train data/obj.data yolo-obj.cfg yolov4.conv.137 




학습 관련  로그가 출력됩니다.  

 



또 하나의 창이 보이게 되는데 학습이 진행되면서 loss(에러)가 0에 가까워지는 그래프를 그려줍니다.  아래쪽을 보면 몇시간 걸린다고 파란색 문자열로 보여줍니다. 글 작성 시점에선 5시간 정도 걸린다고 표시되었습니다. 

 

다음 에러가 나는 경우 이미지 크기(width, height)를  160으로 줄이면 해결됩니다. 

그래픽카드의 메모리 부족때문에 발생하는 듯합니다. 

 

CUDA Error: out of memory

 




시간이 좀 지나면 다음처럼 Loss가 떨어지는 그래프가 그려지게 됩니다. 

 





완료후 메시지입니다. 

 

Saving weights to backup//yolo-obj_4000.weights

Saving weights to backup//yolo-obj_last.weights

Saving weights to backup//yolo-obj_final.weights

If you want to train from the beginning, then use flag in the end of training command: -clear 



 

학습완료 후, 테스트해봅니다. 

 

webnautes@webnautes-laptop:~/custom_yolo_test$ ./darknet detector test data/obj.data yolo-obj.cfg backup/yolo-obj_final.weights img/IMG_2157.jpg

 




webnautes@webnautes-laptop:~/custom_yolo_test$ ./darknet detector test data/obj.data yolo-obj.cfg backup/yolo-obj_final.weights img/IMG_2160.jpg 





인식 결과에서 pipe라는 이름이 출력되지 않지만..(원인을 찾지 못했습니다.)




터미널의 출력결과를 보면 정상인것을 알 수 있습니다.

 

img/IMG_2157.jpg: Predicted in 515.086000 milli-seconds.

pipe: 99%



img/IMG_2160.jpg: Predicted in 524.768000 milli-seconds.

pipe: 99%




하지만 학습에 사용하지 않은 것은 인식을 전혀 못하네요. 너무 적은 이미지(2장)으로 학습을 진행해서로 보입니다.  학습에 사용하는 이미지를  좀 더 많이 사용하면 인식 결과가 개선됩니다. 

 





참고 

 

https://keyog.tistory.com/21 

 

https://keyog.tistory.com/22

 

https://github.com/AlexeyAB/darknet#how-to-train-to-detect-your-custom-objects












반응형

'Deep Learning > YOLO' 카테고리의 다른 글

YOLO v4 실행시키는 방법  (0) 2023.10.21
YOLO v8 pose 사용해보기  (0) 2023.10.04
YOLO v8 사용해보기  (0) 2023.10.04

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts