반응형

Yolo v3의 Keras 구현

Github의 [구현] 내용임

  • 원하는 디렉토리에 클론을 만든다.

    
      git clone https://github.com/xiaochus/YOLOv3
      
  • yolov3.weight를 다운로드 하여 클론의 최상위 디렉토리로 복사한다.

  • darknet 가중치 파일을 keras .h5 파일로 변환한다.

    
      python yad2k.py cfg\yolo.cfg yolov3.weights data\yolo.h5
      
  • 데모 실행. 결과는 images/res/에서 확인할 수 있다.

    
      python demo.py
      

이 소스의 경우, 가중치 변환 및 사용은 가능하지만, 모델 훈련은 구현되어 있지 않은 상태이다. 또한 YOLO의 경우, 케라스(텐서 플로우) 변환시 원래의 다크넷에서보다 box의 정확도가 떨어지기 때문에 가능하다면 다크넷을 이용하는 것이 좋다고 한다.


Darknet Yolo 사용하기

다크넷 설치하기

    다크넷은 두가지 옵션으로 쉽게 설치할 수 있다.

  • OpenCV : 다양한 이미지 타입의 지원이 필요한 경우
  • CUDA : GPU 사용이 필요한 경우

    위의 두가지 모두 선택사항이다. 따라서 기본 시스템만을 설치해 보자. (원문은 리눅스와 맥에서 테스트되었다고 하였으나, 여기서는 윈도우10에서 Ubuntu Bash shell로 진행한다. 정확히는 윈도우를 위한 DLL을 생성하여 진행하는 것이 아니기 때문에 가상환경에서 진행하는 것과 큰 차이는 없다.)

Linux Bash Shell 설치 : [참고]

  1. PowerShell을 관리자 권한으로 실행하여 아래 명령 입력, 설치 후반에 'Y'를 입력하여 시스템 리붓

    
     Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
     
  2. Windows Store에서 Linux 다운로드 후 설치

  3. Start menu에서 Ubuntu를 찾아 실행.

  4. YOLO 컴파일을 위한 패키지 다운로드

    
     sudo apt-get install make
     sudo apt-get install gcc
     sudo apt-get install g++
     

기본 시스템 설치

  1. [Darknet git 저장소의 clone을 만들고 컴파일
    
     git clone https://github.com/pjreddie/darknet.git
     cd darknet
     make
     
  2. 확인
     
     ./darknet
     
     
     usage: ./darknet 
     
     
  • CUDA로 설치

        CPU에서의 다크넷도 빠르지만 GPU에서는 500배 더 빠르다. NVIDIA GPU와 CUDA가 있으면 Makefile의 첫번째 줄을 아래와 같이 수정한다.

    
      GPU=1
      

        make로 컴파일 하면 CUDA가 활성화된다. 이것은 기본적으로 시스템의 0번째 그래픽 카드에서 네트워크가 동작할 것이다.(만약 CUDA가 올바르게 설치되었다면 nvidia-smi를 사용하여 시스템의 그래픽카드 목록을 볼 수 있다.) 만약 다크넷이 사용하는 그래픽 카드를 바꾸려면 아래와 같이 -i <index>옵션을 사용한다.

    
      ./darknet -i 1 imagenet test cfg/alexnet.cfg alexnet.weights
      

        CUDA를 사용하여 컴파일했지만 CPU를 사용하고 싶다면, -nogpu옵션을 사용한다.

    
      ./darknet -nogpu imagenet test cfg/alexnet.cfg alexnet.weights
      
  • OpenCV로 설치

        기본적으로 다크넷은 이미지를 로드하기 위해 stb_image.h를 사용한다. 만약 CMYK jpges같은 특이한 포멧에 대한 더 많을 지원을 받으려면 OpenCV를 대신 사용할 수 있다. 또한 OpenCV는 이미지와 탐지를 디스크에 저장하지 않고 볼수 있게 한다.

        우선, OpenCV를 설치하고 Makefile의 두번째 라인을 아래와 같이 수정한다.

    
      OPENCV=1
      

        make로 컴파일하고 아래와 같이 이미지 로딩과 디스플레이를 imtest로 테스트해보자.

    
      ./darknet imtest data/eagle.jpg
      
      
      

사전훈련 모델로 탐지하기 : [링크]

    YOLO 설정파일은 cfg/ 하위 디렉토리에 존재하고, [사전훈련 가중치 (237MB)]를 다운로드 받아 디렉토리로 복사한 후 아래 명령을 실행한다.


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

    만약 Couldn't open file: data/coco.names라는 오류가 발생하면 yolo 프로젝트를 다시 다운받아 컴파일한다. (다른 파일 인코딩으로 인한 오류라고 한다. - CRLF : 윈도우, LF : Linux)

    아래와 같은 실행결과를 확인 할 수 있다. 다크넷은 탐지한 객체, 신뢰도 그리고 이를 탐지하기 위해 걸린 시간을 함께 출력한다. (작업중인 PC 사양이 낮아 시간이 꽤 오래 걸린다.)



    OpenCV 옵션으로 설치하지 않았기 때문에 결과 이미지를 바로 볼 수 없고, predictions.jpg에서 아래와 같은 결과를 확인할 수 있다.


    detect 명령은 아래와 같은 일반적인 명령의 약칭이다.


./darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights data/dog.jpg

    이는 단지 이미지에서의 탐지만을 한다면 알 필요가 없지만, 웹캠에서의 동작같이 다른 것을 원한다면 유용하다

Multiple Images

    Command line에서 이미지를 적용하는 대신, 연속해서 여러 이미지를 다루기 위해 공백으로 남겨놓을 수 있다. 그러면 아래와 같은 결과를 볼 수 있다.


./darknet detect cfg/yolov3.cfg yolov3.weights

    data/horses.jpg를 입력하면 아래와 같이 탐지 결과와 다음 대상을 입력받을 수 있게 된다. 탐지된 결과는 위와 같이 prediction.jpg로 확인할 수 있다. 종료하려면 Ctrl + C를 누른다.



임계치 변경하기

    기본적으로 YOLO는 단지 0.25보다 높은 신뢰도를 가진 탐지 객체만을 보여준다. 이는 -thresh <val> 옵션을 전달하여 변경할 수 있다. 아래는 임계치를 0.05으로 하여 모든 탐지된 객체를 표시하는 예제이다. (원문에서는 0으로 테스트 하였으나, 0으로 하는 경우 무한루프가 되어 0.05로 테스트하였다.)


./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg -thresh 0.05



    이는 굉장히 유용하지는 않지만 모델에 의해 결정되는 임계치를 제어하기 위해 다른 값을 설정할 수 있게 한다.

Tiny YOLOv3

    제약이 있는 환경을 위한 매우 작은 모델인 yolov3-tiny도 있다. 이 모델을 사용하기 위해서는

  1. 아래와 같이 가중치를 다운로드 받는다.
    
     wget https://pjreddie.com/media/files/yolov3-tiny.weights
     
  2. 설정(config)파일과 가중치(weight)로 실행한다.
    
     ./darknet detect cfg/yolov3-tiny.cfg yolov3-tiny.weights data/dog.jpg
     

웹캠에서 실시간 탐지

이 부분은 현재 실습을 진행할 수 있는 환경이 되지 않아 확인없이 진행한다.

    결과를 보지 않는다면 테스트 데이터에서 YOLO를 실행하는 것은 그렇게 흥미롭지 않다. 테스트 이미지대신 웹캠 입력에서 실행해보자.

    예제를 실행하기 위해서는 CUDA와 OpenCV로 컴파일한 다크넷을 준비하고 아래 명령을 수행해야한다.


./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights

    YOLO는 현재 FPS와 분류 그리고 바우인딩 박스를 표시한다.

    OpenCV가 연결할 캠이 필요하다 그렇지 않으면 동작하지 않는다. 만약 여러개의 캠이 있고 그중에 하나를 선택해야 한다면, -c <num> 옵션을 사용한다.(OpenCV의 웹캠 기본값은 0을 사용한다.)

    또한 OpenCV가 비디오를 읽을 수 있다면, 비디오에서 실행할 수도 있다.


./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights <Video file>

Training YOLO on VOC

    만약 다른 훈련 제도, 하이퍼파라미터 또는 데이터셋을 사용하려면 설계부터 YOLO를 훈련할 수 있다. 여기서는 Pascal VOC 데이터셋에서 이를 수행하는 법을 알아본다.

Get The Pascal VOC Data

    2007년에서 2012년까지의 VOC data를 다운로드 받는다. 모든 데이터를 받기 위해서 데이터를 저장하기 위한 디렉토리를 만들고(여기서는 VOCdevkit/) 아래 명령을 해당 디렉토리에서 실행한다.


wget https://pjreddie.com/media/files/VOCtrainval_11-May-2012.tar
wget https://pjreddie.com/media/files/VOCtrainval_06-Nov-2007.tar
wget https://pjreddie.com/media/files/VOCtest_06-Nov-2007.tar
tar xf VOCtrainval_11-May-2012.tar
tar xf VOCtrainval_06-Nov-2007.tar
tar xf VOCtest_06-Nov-2007.tar

Generate Labels for VOC

    이제 다크넷이 사용할 레이블 파일을 만들어야 한다. 다크넷은 아래와 같이 각 이미지에 대한 각 실측(ground truth)객체에 대한 정보를 가진 .txt 파일이 필요하다.


<object-class> <x> <y> <width> <height>

    scripts/ 디렉토리의 voc_label.py를 사용하여 파일을 생성하자.


python voc_lablel.py

    이 스크립트는 모든 필요한 파일을 생성한다. 대부분 VOCdevkit/VOC2007/labels/VOCdevkit/VOC2012/labels/에 각 이미지별 레이블 파일을 생성하고 아래처럼 데이터 셋을 나눈다. 여기서 train.all.txt파일은 전체 데이터셋을 합친 것이고, train.txt파일은 train.all.txt파일에서 2007_test.txt파일을 뺀 목록이다.


    2007_train.txt파일은 해당 년의 이미지셋에을 목록화한 것이다. 다크넷은 훈련하려는 모든 이미지를 포함하는 하나의 텍스트 파일이 필요하나. 이번 예제에서는 모델을 테스트할 2007년 테스트셋을 제외한 나머지로 훈련하기 위해 아래처럼 하나의 파일로 만든다. (하지만 이 글을 작성하는 시점에서 voc_label.py를 실행하면 아래 작업을 자동으로 수행하고 있다.)


cat 2007_train.txt 2007_val.txt 2012_*.txt > train.txt

Modify Cfg for Pascal Data

    Darknet의 cfg 디렉토리에서 voc.data 설정을 훈련데이터를 가리키도록 수정해야한다.


  1 classes= 20
  2 train  = <path-to-voc>/train.txt
  3 valid  = <path-to-voc>/2007_test.txt
  4 names = data/voc.names
  5 backup = backup

    여기서 <path-to-voc>를 VOC 데이터의 경로로 수정하면 된다.

사전훈련된 합성곱 가중치 다운로드

    훈련을 위해 이미지넷에서 사전훈련된 합성곱 가중치를 사용한다. 여기서는 darknet53모델의 가중치를 사용한다. 가중치는 여기에서 다운로드한다.


wget https://pjreddie.com/media/files/darknet53.conv.74

모델 훈련

    아래 명령으로 모델을 훈련한다.


./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74

COCO에서 YOLO 훈련하기

    이번에는 COCO dataset으로 훈련해보자.

COCO data 가져오기

    COCO 데이터와 레이블을 가져오자. scripts/get_coco_dataset.sh를 아래와 같이 사용한다.


cp scripts/get_coco_dataset.sh data
cd data
bash get_coco_dataset.sh

Modify cfg for COCO

    cfg/coco.data 설정 파일을 아래와 같이 변경한다.


  1 classes= 80
  2 train  = <path-to-coco>/trainvalno5k.txt
  3 valid  = <path-to-coco>/5k.txt
  4 names = data/coco.names
  5 backup = backup

    여기서 <path-to-coco>을 COCO 데이터의 경로로 바꾸면 된다.

    또한 테스트가 아닌 훈련을 위해 모델의 설정(cfg/yolo.cfg)을 아래와 같이 수정한다.


[net]
# Testing
# batch=1
# subdivisions=1
# Training
batch=64
subdivisions=8
....

모델 훈련

    아래 명령으로 모델을 훈련한다.


./darknet detector train cfg/coco.data cfg/yolov3.cfg darknet53.conv.74

    만약 여러개의 GPU를 사용한다면,


./darknet detector train cfg/coco.data cfg/yolov3.cfg darknet53.conv.74 -gpus 0,1,2,3

    만약 훈련을 멈추고 체크포인트로부터 다시 시작하려면,


./darknet detector train cfg/coco.data cfg/yolov3.cfg backup/yolov3.backup -gpus 0,1,2,3

YOLOv3 on the Open Images dataset


wget https://pjreddie.com/media/files/yolov3-openimages.weights

./darknet detector test cfg/openimages.data cfg/yolov3-openimages.cfg yolov3-openimages.weights
반응형

+ Recent posts