본문 바로가기

프로그래머스 데브 코스/TIL

[6기] 프로그래머스 인공지능 데브코스 93일차 TIL

1202

[15주차 - Day5] Visual Recognition

Custom YOLO v3 제작 과제

# 강의에서 배운 Custom YOLO제작방법과
# 유튜브(https://www.youtube.com/watch?v=saDipJR14Lc)에 나오는 OpenCV를
# GPU와 같이 사용하는 방법을 같이 이용하여
# 로컬에서 GPU로 동작하는 Custom YOLO v3를 제작해보기

# 예를 들어 ‘총’을 들고 있는 사람을 인지하는 실시간 위험감시 프로그램 제작

# GPU로 OpenCV가 돌아가지 않으면 CPU로라도 제작

 

Custom YOLO 제작 전 CustomYOLOv3 실습 수행

# darknet repository에서 clone하기
!git clone https://github.com/AlexeyAB/darknet


#GPU와 OPENCV의 사용이 가능하도록  makefile을 수정하기
%cd darknet
!sed -i 's/OPENCV=0/OPENCV=1/' Makefile
!sed -i 's/GPU=0/GPU=1/' Makefile
!sed -i 's/CUDNN=0/CUDNN=1/' Makefile


# CUDA버전 확인하기
!/usr/local/cuda/bin/nvcc --version


# make를 이용하여 darknet를 build
!make


# coco 데이터셋으로 사전학습된 weight값들을 다운로드함
!wget https://pjreddie.com/media/files/yolov3.weights


# helper함수들
def imShow(path):
  import cv2
  import matplotlib.pyplot as plt
  %matplotlib inline

  image = cv2.imread(path)  #경로로부터이미지를 불러읽어들여서
  height, width = image.shape[:2]   #현재 영상의 height와 width를 읽어서
  resized_image = cv2.resize(image,(3*width, 3*height), interpolation = cv2.INTER_CUBIC) #영상을 3배로 키운다(크게 보여주기 위해서)

  fig = plt.gcf()
  fig.set_size_inches(18, 10)
  plt.axis("off")
  plt.imshow(cv2.cvtColor(resized_image, cv2.COLOR_BGR2RGB))  #opencv로 읽어들인 영상은 BGR포맷을 갖기 때문에 RGB포맷으로 변환해야 함
  plt.show()

# google colab으로 파일을 업로드할 때 사용하는 함수를 정의
def upload():
  from google.colab import files
  uploaded = files.upload() 
  for name, data in uploaded.items():
    with open(name, 'wb') as f:
      f.write(data)
      print ('saved file', name)

# google colab에서 파일을 다운로드할 때 사용하는 함수를 정의
def download(path):
  from google.colab import files
  files.download(path)

- YOLO 수행을 위한 환경 설정 및 파라미터 로드

 

git clone https://github.com/theAIGuysCode/OIDv4_ToolKit.git

cd .\OIDv4_ToolKit\

pip install -r requirements.txt

- Window Power Shell에서 위의 코드를 수행해 customYOLO 코드 로드

 

 

python main.py downloader --classes Elephant Giraffe Hippopotamus Tiger Zebra --type_csv train --limit 300 --multiclasses 1

- 위 코멘드에서 Elephant부터 Zebra까지는 https://storage.googleapis.com/openimages/web/visualizer/index.html?type=detection&set=train&c=%2Fm%2F0k5j 이곳에서의 데이터셋 클래스를 지정해 주는 부분

- 맨 마지막 <--multiclasses 1> 코드는 위의 모든 데이터셋 클래스를 각각으로 생성하지 않고 한 폴더 안에 생성한다는 옵션

- 원하는 클래스 명을 적어서 train 데이터를 다운로드받으면 된다

 

 

> 번외: 'aws'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다.

위와 같은 코드가 뜨고 다운로드가 제대로 안 된다면

https://docs.aws.amazon.com/ko_kr/cli/v1/userguide/install-windows.html

 

Windows에서 AWS CLI 버전 1 설치, 업데이트 및 제거 - AWS Command Line Interface

이러한 구성 및 자격 증명 설정은 모든 AWS SDK 및 AWS CLI에서 공유됩니다. 이 폴더를 제거하면 아직 시스템에 있는 AWS SDK에서 액세스할 수 없습니다.

docs.aws.amazon.com

위 사이트로 들어가서 aws 라인을 수행할 수 있는 msi를 다운로드받아주면 된다.

* 다운로드 후 파워 셀 재실행한 뒤 < aws --version > 이 명령어로 다운로드가 잘 되었는지 확인

 

 

python convert_annotations.py

rm -r OID/Dataset/train/Elephant_Giraffe_Hippopotamus_Tiger_Zebra/Label/

- 다운로드가 끝나면 위 명령어를 수행해 라벨을 YOLOv3에서 사용하는 포맷으로 변환시켜 커스텀 object detector를 학슴시킬 수 있는 형태가 되게 한다

- 그리고 두 번째 명령어로 옛날 'label' 폴더/YOLOv3에서 사용할 수 없는 라벨을 제거한다

 

# 압축한 zip파일을 넣은 폴더
!ls /mydrive/dl


cd darknet


# obj.zip파일을 클라우드의 root directory로 copy하기
!cp /mydrive/dl/obj.zip ../


# 다음과 같이 zip파일을 압축풀기하면 파일안의 내용들이 /darknet/data/obj 안에 있게 된다
!unzip ../obj.zip -d data/obj/

- 이전 명령어를 통해 만들어진 <C:\...\OIDv4_ToolKit\OID\Dataset\train> 폴더 안에는 train 이미지와 각 이미지에 해당하는 좌표값이 txt 파일로 들어가져 있는데, 이 파일을 전체 압축해 코랩 폴더에 업로드해준다.

- 업로드한 폴더 경로를 숙지하고(zip 파일을 올린 폴더 이름을 'dl' 위치에 넣어주면 된다) 위 코드를 수행해 주면 코랩에서 해당 이미지 데이터셋을 사용할 수 있는 환경이 만들어진다.

 

 

> 번외: 폴더를 압축 해제했을 때 obj 폴더 아래에 우리가 만든 폴더 이름 그대로 '폴더'가 생겼으면

그 폴더를 obj 바로 상위 폴더로 꺼낸 다음 obj 폴더 삭제 후 우리가 만든 폴더(압축 해제한 폴더)의 이름을 obj로 만들어 줘야 한다

즉, obj 폴더 아래에 바로 이미지와 텍스트 파일들이 존재해야 아래 python 코드 및 모델 학습이 가능해진다

 

 

# cfg파일을 구글 드라이브로 복사하고 이름을 바꾸기
!cp cfg/yolov3.cfg /mydrive/yolov3/yolov3_custom.cfg


# PC로 다운로드하려면 다음과 같이 하면 된다. 다운로드후에는 파일 이름을 yolov3_custom.cfg로 바꾸면 된다.
download('cfg/yolov3.cfg')

- 위의 코드를 실행해 cfg 파일을 다운로드받은 뒤 원하는 파일명으로 변경해 주고, 이를 코랩에 업로드한 뒤 text edictor로 열고 아래의 옵션대로 custom 해 주면 된다.

  • batch = 64
  • subivisions = 16       # 메모리 에러가 나면 32, 64 순으로 올려 주면서 학습 
  • max_batches = 10000     # 맥스 배치는 class의 개수 * 5로 설정하는 것을 추천
  • steps = 8000, 9000     # 스텝 수는 맥스 배치의 80% 값과 90% 값으로 설정
  • classes = 5     # [yolo]로 묶여 있는 애들로 가서 변경 (총 3개)
  • filters = 30      # [yolo]로 묶여 있는 곳 바로 위의 [convolutional] 속 filters 값들 >  (classes 개수 + 5) * 3
  • random = 0      # [yolo] 속 랜덤값을 바꿔 주면 정확도는 떨어지지만 속도가 빨라지고 메모리 부족 현상이 나아짐

 

# 커스텀 .cfg 파일을 다시 클라우드로 올림
!cp /mydrive/dl/yolov3_custom.cfg ./cfg

# 다음과 같이 하면 PC에서 커스텀 .cfg 파일을 클라우드로 올릴 수 있음.
#%cd cfg
#upload()
#%cd ..

- 커스텀 파일을 수정 저장한 뒤 코드 실행

 

# obj.data 
classes = 5
train = data/train.txt
valid = data/test.txt
names = data/obj.names
backup = /mydrive/dl/backup/

# obj.names
Elephant
Giraffe
Hippopotamus
Tiger
Zebra

- 주석에 있는 이름.확장자로 된 파일을 만들어서 코랩에 업로드한 뒤 text edictor로  위의 내용을 안에 넣어 준다

- 참고로 names의 클래스 순서는 꼭 지켜야 한다.

 

# obj.names 와 obj.data 파일들을 구글 드라이브에서 클라우드로 올리기
!cp /mydrive/dl/obj.names ./data
!cp /mydrive/dl/obj.data  ./data

# obj.names 와 obj.data 파일들을 PC에서 클라우드로 올리기
#%cd data
#upload()
#%cd ..

- 위의 obj.data 안에 있는 backup 파일까지 해당 경로에 미리 만들어 두고 위 코드 실행

 

# 구글드라이브의 generate_train.py 스크립트를 클라우드로 올리기
!cp /mydrive/dl/generate_train.py ./

# PC에서 generate_train.py 스크립트를 클라우드로 올리기
#upload()


!python generate_train.py


# darknet/data폴더내에 train.txt이 존재함을 확인해보기
!ls data/

- https://github.com/theAIGuysCode/YoloGenerateTrainingFile/blob/master/generate_train.py/

- 위 경로에 있는 generate_train.py 파일을 다운로드받은 뒤 사용

 

# 사전학습된 convolutional layer weights를 다운로드하기
!wget http://pjreddie.com/media/files/darknet53.conv.74


# 커스텀 detector를 학습시키기. 기존에 학습하다 말았으면 backup에 있는 weight를 불러서 학습하는 셀로 이동하기
!./darknet detector train data/obj.data cfg/yolov3_custom.cfg darknet53.conv.74 -dont_show


imShow('chart.png')

- 위의 코드를 실행하면 10시간이 넘게 소요 후 iteration에 따른 평균 loss 값의 변화 확인 

 

!./darknet detector train data/obj.data cfg/yolov3_custom.cfg /mydrive/dl/backup/yolov3_custom_last.weights -dont_show

- 혹시라도 학습이 더 이상 진행되지 않을 때 이 코드를 실행해 100 iteration마다 저장된 파일을 불러와 사용할 수 있음

 

# custom cfg 를 test mode 로 바꾸기
%cd cfg
!sed -i 's/batch=64/batch=1/' yolov3_custom.cfg
!sed -i 's/subdivisions=16/subdivisions=1/' yolov3_custom.cfg
%cd ..


# 구글 드라이브로 원하는 영상을 업로드한 후에 커스텀 detector를 돌리기. 여기서 -thresh 0.3은 Accuracy가 0.3이하가 되는 Object의 Bounding Box는 보이지 않게 하겠다는 뜻임
!./darknet detector test data/obj.data cfg/yolov3_custom.cfg /mydrive/dl/backup/yolov3_custom_last.weights /mydrive/images/test.jpg -thresh 0.3
imShow('predictions.jpg')

- 이제 만들어진 object detector를 사용해 볼 수 있음