본문 바로가기

논문 리뷰

Fast R-CNN 리뷰

Object detection에서 R-CNN, SPP-Net 다음으로 읽은 Fast R-CNN이다. 이름만 봐도 R-CNN의 속도를 개선한 모델이라는 것을 알 수 있다.

 

Contribution

 

1. 빠르다. R-CNN은 물론이고 SPP-Net보다도 train은 3배, test시에 10배나 빠르다.

2. 그러면서 성능도 더 좋다.

3. Multi-task loss를 이용해 훈련 과정을 간소화했다.

 

R-CNN, SPP-Net과의 비교

 

기존의 모델들은 multi-stage pipelines를 통해 train했다. 다시 말해,

 

1. 모델을 먼저 트레이닝 하고(이것도 여러 단계에 걸쳐서)

2. 그 뒤에 bounding box regression을 훈련했다.

 

이 논문에서는 위의 과정을 single-stage-training 할 수 있는 방법을 찾아냈다. 때문에 더 빠르다.

 

R-CNN은 2000개 가량의 region proposal을 다 CNN에 넣는 비 효율적인 구조였기 때문에, 느릴 뿐 아니라 공간 복잡도도 커져서 중간 중간 disk에 저장해야 했다. 저장 공간도 많이 필요했고 그 과정에서 더 느려졌다. Test 시에도 너무 느린 나머지 이미지 하나 당 47초나 걸렸다고 한다.

 

SPP-Net이 이미지 전체를 넣고 그 feature에서 region proposal 하는 방식으로 이를 해결했지만, 여기에도 단점이 있다. 훈련 과정이 multi-stage pipeline인 것은 물론이고, spp layer 전에 붙어 있는 CNN layer들까지 back prop을 하지 못한다는 치명적인 단점이 있었다.

 

Architecture

 

 

1. 전체 이미지와 object proposal을 CNN에 넣는다.

2. 뽑아낸 각각의 RoI(region of interest, 기존의 region proposal과 같은 개념)을 RoI pooling layer에 넣는다.

3. RoI pooling layer는 spp layer와 같은 방식으로(level 1짜리 spp pooling이다) 일정한 길이의 feature를 뽑는다.

4. 이걸 fc에 넣고 output을 뽑아 softmax layer와 bounding-box regression layer에 둘 다 넣어준다.

5. Softmax는 classification 결과를 확률 값으로 뱉고, bbox layer는 클래스 별 bounding box를 뱉는다.

 

RoI Pooling

 

RoI pooling 시에, h x w의 RoI window를 H x W 개의 sub-window로 쪼갠다. Sub-window는 h/H x w/W 가 될 것이다. 이제 각각의 sub-window에 pooling을 적용하면 H x W로 사이즈가 줄어든다. 가령 12 x 12의 RoI는 3 x 3 개의 4 x 4 sub-window로 쪼갤 수 있다. 이제 이 sub-window를 각각 max-pooling 하면 12 x 12 에서 3 x 3으로 바뀐 것을 알 수 있다. 이런 방식으로 input size에 상관없이 고정된 길이의 feature를 뽑을 수 있다.

 

SPP-Net의 back propagation 문제

 

  Fast R-CNN은 전체 input 이미지에서 region proposal을 수행해 RoI를 뽑아놓고 마지막 conv의 feature에 projection한다. 이와 달리 SPP-Net에서는 마지막 conv layer의 feature에서 region proposal을 수행하는데,  마지막 conv의 feature은 많은 convolution 연산과 pooling을 거치면서 크기가 많이 작아졌을 것이고 여기서 region proposal을 하면 RoI의 receptive field가 거의 전체 이미지를 차지하게 된다. 만약 하나의 RoI의 receptive field가 전체 이미지를 차지하면 RoI가 하나밖에 생기지 않을 것이다. 총 128개의 RoI를 한 batch로 봤을 때, Fast R-CNN은 2개의 input을 넣어서 각각 64개의 RoI를 뽑으면 되므로 conv layer를 2번만 거치면 되지만 SPP-Net은 128개의 input을 넣어서 RoI를 하나씩 뽑을 수 밖에 없으므로 비효율적이다. 이런 비효율성 때문에 SPP-Net은 전체 네트워크에 대해 backprop을 수행할 수 없었고 fcn만 학습시키는 방법밖에 없었다고 이해했다. 이 부분에 대한 설명은 이 정도로만 써있고, 따로 자료를 찾아봐도 더 좋은 설명은 찾을 수 없었다. 

 

여기서 드는 궁금증은 그러면 어떻게 SPP-Net이 작동을 할 수 있었는가 이다. RoI의 receptive field가 전체 이미지라면 bounding box가 전체 이미지에 씌워진다는 이야기인데 object detection 모델로서 기능 자체를 상실한 게 되어버리는 것 아닌가? 이 부분은 조금 더 알아봐야겠다.

 

Multi-task Loss

 

위와 같은 loss를 사용한다. Classification loss와 location loss가 합쳐져 있다. 

 

각각의 RoI에 대해 softmax가 뱉은 각 class 별 확률 값이 p이다.

 

Classification loss는 cross-entropy로 계산한다. Label은 u이다.

 

이번엔 location loss이다. v는 label이다. 위에서 본 바 실제 이 RoI의 class가 u였다. 

 

해당 u class에 대한 bounding box layer의 예측 값이다. 원소가 4개인 tuple인데, 이 만큼 보정을 하라는 뜻이다.

 

위에서 classification loss는 cross entropy를 썼다고 했다. Location loss는 smooth L1 loss를 사용한다.

 

그건 이렇게 생겼다. L1 loss와 다른 점은 -1~1 구간이 곡선이라는 것이다(말 그대로 smooth). R-CNN과 SPP-Net에서는 L2 loss를 사용했는데, L2 loss는 outlier에 민감하기 때문에 loss를 바꿨다고 한다.

 

논문에는 없는 내용이지만, L1 loss는 coordinate system에 의존하고 L2 loss는 그렇지 않기 때문에, bounding box regression같이 4개의 원소의 자리가 각각 의미가 명확한 경우에 L1 loss를 쓰는 게 조금 더 말이 된다고 한다.

yun905.tistory.com/4?category=878116

 

CS231n 2017 Lecture 2 : Image Classification

Lecture 1은 Vision 분야에 대한 전반적인 이야기를 소개했다면, 이번 강의는 좀 더 specific하게 classification으로 들어갈 것이다. Image Classification이 어려운 이유는 무엇일까? 사람이 인지하는 방식과..

yun905.tistory.com

 

CS231n의 Lecture 2에서 언급된 내용이다.

 

결론적으로 우리는 이런 multi-task loss를 갖게 된다. 참고로,

 

이건 Iverson bracket indicator function이라는 거고, 한국말로는 아이버슨 괄호라고 한다. [P]에서 조건 P가 참이면 1을, 아니면 0을 뱉는 함수이다. 여기서는 u가 해당 RoI의 class인데, u가 0인 경우는 background이므로 bounding box 자체가 성립이 안되기 때문에 이 함수를 사용한 것이다.

 

 

Truncated SVD

 

Forward pass에서 fc layer가 차지하는 시간이 대략 절반 정도인데, truncated SVD를 이용해서 fc의 parameter를 줄이면 시간상의 이득을 볼 수 있다.

이 방식으로 detection time을 30% 이상 줄였다. Fc6만 보면 4배 가량 감소했고, fc7은 5배 감소했다. mAP는 0.3밖에 떨어지지 않았다. 특이값 분해에 대해서는 따로 공부가 필요할 것 같다.

 

Results

 

1. VOC07, 2010, 2012에서 SOTA를 달성했다.

2. R-CNN과 SPP-Net보다 빠르다.

3. VGG16의 conv layer를 fine tuning해서 mAP를 올렸다.

 

SPP와 R-CNN, Fast R-CNN 모두 VGG16을 썼다. 기존의 R-CNN보다 좋은 성능을 보여주고 있고, 주목할만한 점은 SPP-Net이 VGG16에서 힘을 못쓴다는 것이다. 위에서 언급했듯이 SPP layer 이전의 conv layer까지 back prop을 못하는 문제점이 있었고, 그래서 conv layer를 fine tuning 하지 못했기 때문이라고 한다. AlexNet 정도의 네트워크는 fc layer만을 fine tuning 하는 걸로 충분했지만, VGG 급의 deep한 네트워크에서는 그게 안된다는 것이다.

 

Fast R-CNN으로 ablation 해보니, fc layer만 fine tuning 했을 경우 mAP가 61.4까지 떨어진다. SPP-Net의 단점이 얼마나 심각한지 알 수 있다. 그렇다고 모든 conv layer를 다 fine tuning 해야 하는 것은 아니다. 어차피 하단의 layer들은 generic한 low level feature만 뽑기 때문에 task independent 하다. VGG16의 경우 conv3_1부터 fine tuning 하는게 실용적이라고 한다.

 

Fast가 붙은 모델 답게 엄청난 속도 향상을 보여준다. SVD가 적용된 버전의 경우 R-CNN에 비해 200배 이상 빠른 detection 속도를 보여준다. Training도 훨씬 빠르다.

 

Multi-task training : Worth it?

 

Stage-wise와 multi-task 방식 간에 mAP 차이가 꽤 난다. 단순히 훈련 과정을 간소화시킨 것 뿐 아니라 성능의 향상도 가져왔다.

 

No more SVM

 

Fast R-CNN에서는 softmax를 사용했는데, SVM과의 비교를 위해 hard negative mining으로 실험했다고 한다. Hard negative mining이란 hard한 false positive만 모아서 따로 학습시키는 방식인데, 우리가 공부할 때 틀린 답 위주로 보는게 효율적인 것과 비슷한 것 같다. 그런데 왜 통상적인 data로 비교하지 않았는지 그 이유는 언급이 없다. 결과를 보면 softmax가 약간 더 좋다. Pre trained CNN들은 다 softmax가 붙어있는데, 이걸 떼고 SVM을 붙이고 하는 과정이 너무 번거로웠던 마당에 더이상 SVM을 쓸 이유가 없어졌다.

 

 

  그 밖에도 multi-scale 과 single-scale이 성능 차이가 크지 않았다는 얘기가 있었다. Multi-scale로 훈련을 하면 mAP가 1.5정도 증가해서 그렇게 적은 상승폭은 아니라고 생각하지만, 얕은 모델에서 multi-scale 훈련 하는것보다 그냥 깊은 모델을 쓰는 게 낫다(깊은 모델에서 multi-scale로 훈련하는 건 GPU 메모리 상의 문제로 불가능했다고 한다). 그리고 object proposal을 늘린다고 성능이 좋아지는게 아니라는 얘기, dataset 크기를 늘렸을 때 성능이 어떻게 되는가에 대한 얘기도 흥미로웠다. Data의 경우, VOC07의 trainval과 VOC12의 trainval을 합쳤을 때 VOC07에서 mAP가 0.1% 정도 증가했다. 그리고 VOC07의 test를 추가로 넣고 VOC10과 12에서 실험했을 때 mAP가 2~3% 가까이 상승했다. 

 

Next

  기존 모델들의 여러 문제들을 해결한 R-CNN이지만, 아직도 selective search를 이용한다는 단점이 남아있다. Selective search는 learnable 하지도 않고 cpu를 사용하는, 비용이 크면서 성능은 나쁜 존재였다. 다음번에는 Faster R-CNN을 읽으면서 이 문제를 해결했는지 보겠다.