2017년 3월 16일 목요일

Faster R-CNN 다른 DB학습시키기

문제: 원하는 데이터를 Faster R-CNN코드를 이용하여 학습시키자

해결:
1. Faster R-CNN 설치 깔기 및 Demo까지 따라하여 잘 설치되었는지 확인.
https://github.com/rbgirshick/py-faster-rcnn

2. Data준비하기
 data폴더를 다운받아서 압축풀고 학습을 원하는 데이터를 같은 포맷으로 생성하기
 ex)
   data/Annotations/ABCD.xml - class명, Boundingbox가 파일별로 저장됨.
   data/Images/ABCD.jpg or ABCD.png - 이미지파일
   data/ImageSets/train.txt - 학습용 image의 이름이 row-by-row로 저장됨.
   data/ImageSets/test.txt - 테스트용 image의 이름이 row-by-row로 저장됨.

3. 코드 수정.
<참고: https://github.com/zeyuanxy/fast-rcnn/tree/master/help/train>
<참고: http://sgsai.blogspot.kr/2016/02/training-faster-r-cnn-on-custom-dataset.html>
 * stage2의 형식을 따랐다면 다음만 바꾸면 됨.
   slsv1.py와 factory.py를 lib/dataset에 overwrite.

   lib/dataset/slsv1.py에서
     self._classes에서 class명 수정
     self._image_ext에서 이미지 파일 확장자 원하는 것 추가
   lib/dataset/factory.py에서
     slsv1_devkit_path 를 data폴더의 하나위 상위폴더를 가르키도록 수정

4. 학습코드로 학습시키기.
 run폴더를 다운받아서 학습/데모/테스트시킨다.
  학습: run_my_train_net.py
  데모: my_demo.py
  테스트: my_test_net.py (matlab필요)

 data폴더 및 run폴더는 100번 서버(yochin/Faster-RCNN-myTutorial)에 있음.

에러모음
- File "../lib/rpn/anchor_target_layer.py", line 137, in forward
    gt_argmax_overlaps = overlaps.argmax(axis=0)
ValueError: attempt to get argmax of an empty sequence
<참고: https://github.com/rbgirshick/py-faster-rcnn/issues/27>
 -> image의 ratio가 너무 크거나 너무작으면 문제가 되므로 제거하면 됨.
 -> 이미지의 크기는 상관없음.

- File "../lib/datasets/imdb.py", line 111, in append_flipped_images
    assert (boxes[:, 2] >= boxes[:, 0]).all()
AssertionError
<참고: https://github.com/rbgirshick/py-faster-rcnn/issues/34>
-> 최종적으로 읽혀진 bounding box가 zero-base가 되도록 해야됨. 또한 이전 pkl 파일이 존재해서 안되는 경우도 있음(py-faster-rcnn/data/cache/의 파일을 모두 삭제).

- 얻어진 결과에 대하여 classification은 맞으나, boundingbox가 터무니없는 경우(너무 많이 터무니없는 위치를 BBox로 예측하는 경우).
<참조: https://github.com/rbgirshick/py-faster-rcnn/issues/497>
<참조: https://github.com/rbgirshick/py-faster-rcnn/issues/186>
setting __C.TEST.BBOX_REG = False 으로 하면 RPN에서 나온 region proposal을 그대로 나오는 것으로 regressor_BB의 학습여부를 확인할 수 있음. 즉, False로 했는다 잘된다는 말은 RPN위의 BBox_regressor가 제대로 학습을 잘 못한다는 말임. 하지만, 원저자의 소스코드와 shell script를 활용하는 경우에는 이러한 문제가 생기지 않았음.