즉! GPU 메모리만 충분하다면 batch 를 높이거나 subdivisions 를 낮추어 학습속도를 빠르게 할 수 있다.
GTX 1080 기준 batch(64), subdivisions(4)
를 쓰면 GPU Memory를 6.5GB정도를 쓴다.(상한선)
이는 기본 네트워크(기본 cfg)를 쓸 경우이고, 다른 CNN을 사용하면 달라질수 있다.
당연하겠지만 batch(32),subdivisions(8)
보다 batch(64),subdivisions(4)
가 더 좋다. 배치가 높은쪽이 좋다.
이 이미지가 크면 학습과 검출속도가 느리고, 작은 물체까지 검출이 가능하다.
학습시와 검출시 반드시 같은 크기를 사용할 필요는 없다. 크게 학습하면 성능은 좋아질지 모르나 학습 시간이 매우 느려진다. 따라서 학습은 416정도로 하고 검출을 할때 늘리는 방법도 좋은 방법이다.
https://github.com/AlexeyAB/darknet/issues/12 이 링크에서는 학습과 검출에서의 width, height의 크기를 조절하는것 만으로도 Recall이 증가함을 볼 수 있다
width와 height의 크기는 32의 배수여야 하며, 논문에서는 288(32x9) 부터 성능을 측정했지만 적당한 정확도를 얻기위해서는 학습시에 최소 416(32x13)은 사용해야 한다고 생각한다.
몇가지 이상한점은 단순히 32의 배수를 사용한다고 되는것이 아닌 특정 크기는 검출시간이 이상하다. 아래 표는 직접 성능을 테스트한 결과이다.(GTX 1080)
width,height | Elapsed time | FPS |
---|---|---|
1088(34*32) | 0.1147 | 8.71 |
1056(33*32) | 0.1154 | 8.66 |
992(31*32) | 0.0903 | 11.06 |
928(29*32) | 0.199 | 5.01 |
864(27*32) | 0.0842 | 11.86 |
800(25*32) | 0.0817 | 12.24 |
736(23*32) | 0.0683 | 14.63 |
672(21*32) | 0.2892 | 3.46 |
608(19*32) | 0.0595 | 16.78 |
544(17*32) | 0.0543 | 18.4 |
480(15*32) | 0.07 | 14.25 |
416(13*32) | 0.042 | 23.77 |
반드시 홀수곱을 할 필요는 없다. AlexeyAB는 학습에 416(32x13)을 사용하고 검출에 832(32x26) 을 사용하였다.
위에 표에서 빨간색으로 표기된 숫자는 검출 속도가 이상한걸 볼 수 있듯이, 직접 테스트해보고 이상점이 없는 시간에서 가장 좋은 width와 height를 구해서 사용하는것이 바람직하다.
결론은, 웬만하면 학습은 416x416으로 하고 검출은 직접 가장 좋은 크기를 찾으면 된다.
귀찮다면 544나 608을 추천한다.
다만, 학습은 큰 width,height 로 했는데 검출은 그보다 낮으면 안되는것 같다.(멍청한 짓이다)
그렇다면, 416으로 학습하고 1088로 검출한다면 성능이 좋지 않느냐, 라고 할 수 있는데
이렇게 사용하면 큰 물체를 찾지 못한다. 반대로 1088로 학습하고 1088로 검출하면 작은물체, 큰물체 모두를 찾을 수 있다.
width, height를 키울때 anchors도 같이 비례해서 키워야 한다.
https://github.com/AlexeyAB/darknet/issues/228
YOLO v1은 이 부분이 [detection] 으로 되어 있다. 이 포스팅은 YOLO v2에 대해서만 기술하므로 YOLO v1은 신경쓰지 않는다.
anchors는 2개씩 짝을 지어 num의 개수만큼 존재한다. 예를들어 num이 5라면 anchors는 총 10개가 있어야 한다.
이 anchors 는 KMeans알고리즘을 이용하여 학습데이터를 보고 생성한다.
아래의 코드로 Anchors를 생성하고 직접 볼 수 있다.
https://gist.github.com/springkim/b2dc66e2d1d754aeb4ca38dda0a81615
조금 더 설명하자면, 이 anchors는 태깅 데이터에 의존적이다.
기다린 태그(i.e 서있는사람) 만을 태깅했을땐 anchor boxes 이 길쭉한 모양이고
얼굴 같이 정사각형에 가까운 물체를 태깅하면 anchor boxes도 정사각형에 가까운 모양이다.
이 부분은 [region] 바로 전 마지막 Conv Layer를 뜻한다.
각 파라매터에 대한 내용은 https://github.com/cvjena/darknet/blob/master/cfg/yolo.cfg 에서 찾아 볼 수 있다.
YOLOv2 는 Object Detection에 대해 4가지 base model 을 지원한다.
먼저 DarknetReference는 Darknet의 가장 기본적인 network로 Tiny-YOLO를 구성한다.
장점으로는 144FPS에 달하는 빠른 속도가 끝이고, 단점으로는 mAP가 낮다.
사실 이 FPS는 정말 검출에 대한 속도만을 뜻한다. 무슨 뜻이냐면 네트워크에 이미지를 넣을때 필요한 resize나 메모리 할당 시간을 뺀 시간이다. 따라서 코드의 시간을 측정할때 이런 부분은 고려해야 한다.
Darknet19는 YOLOv2를 구성하는 네트워크이다. 가장 범용적으로 사용되며 빠른 속도와 높은 mAP를 고루갖춘 network이다.
Resnet50은 유명한 네트워크이다. Alexey는 Resnet50에 대해 단순히 작은 물체검출용 이라고 적어 놓았다.
Densenet201은 그냥 이름부터 느리게 생겼다. 이 네트워크가 YOLOv2의 성능을 가장 최대로 끌어올릴 네트워크이다. 작은 물체와 큰 물체 모두를 잘 탐지 한다고 한다. 다만 학습속도와 검출속도가 2배가량 느려진다.
이들에 대한 cfg수정은 위에 기술한 바와 같으며 검출하고자 하는 객체의 특징에 따라 네트워크를 선택하는게 맞는듯 하다.
batch, subdivisions
먼저 batch와 subdivisions은 검출시에는 반드시 둘다 1로 설정해야한다.
width, height
일반적으로 검출시에 width, height를 변경하면 그에 비례하게 anchors 도 키워야 한다.
다만 random으로 학습 하였을 경우에는 width, height 를 변경할 이유가 없다. 변경해도 결과는 더 안좋아진다. 애초에 다양한 해상도를 학습하였으므로, 크기가 다양한 물체에 대해서도 잘 검출한다. (그래도 변경한다면 anchors는 변경하지 말아야 한다)
일반적으로는 (아주쉬운방법으로는) width와 height만 늘리면 작은 물체를 검출할 수 있다.
https://groups.google.com/forum/#!topic/darknet/MumMJ2D8H9Y
당연한 말이지만 학습과 검출에 1088을 사용하는것이다. 학습속도는 보장하지 못한다.
https://pjreddie.com/darknet/imagenet/#darknet19_448
https://github.com/pjreddie/darknet/tree/master/cfg
Classifier의 cfg를 그대로 쓴뒤 뒤에 [region] 레이어만 붙이면 Object Detection에 쓸 수 있음.
resnet152 동작 확인
VGG16
Alexnet
https://github.com/pjreddie/darknet/issues/323