[Paper Review] Fast R-CNN

Date:     Updated:

카테고리:

태그:

Paper:
- Fast R-CNN


🚀 Abstract

Fast R-CNN은 기존의 Detection 모델인 R-CNN과 SPPnet을 개선해 정확도와 속도 모두를 높이는데 성공했다. 특히 test inference의 경우 R-CNN에 비해 무려 213배나 빠르다.


🚀 Introduction

최근 (2015년) cnn을 통한 분류 작업은 큰 성과를 이루었다. 다만 detection의 경우 classification에 비해 문제가 조금 복잡해진다. 물체의 정확한 위치를 파악해야 하기 때문인데, 이게 생각보다 어려운 작업이다.

  • 수많은 영역(RoI)들을 확인해봐야 한다. (R-CNN 기준 이미지당 2000개의 영역)
  • Selective Search를 통해 제안된 영역은 대락적인 위치이므로 조정 작업이 필요하다.

R-CNN and SPPnet

R-CNN SPPnet
rcnn sppnet

R-CNN의 경우 성공적인 detection 모델이라 할 수 있지만 다음과 같은 단점들이 존재한다.

  1. Training is multi-stage pipeline
    • classification 따로, box regression 따로 계산함
    • 심지어 classification은 cnn 거친 후 SVM 계산
  2. Training is expensive in space and time
    • mini-batch sampling을 서로 다른 이미지의 RoI들로 진행
    • 서로 다른 이미지 영역에 대해 inference를 해봐야 하니 시간도 오래걸리고, 메모리도 엄청 많이 필요함
  3. Detection is slow
    • R-CNN의 경우 이미지 한 장 inference하는데 47초나 필요함.
    • real-time은 어림도 없는 시간

R-CNN 이후 제안된 SPPnet의 경우 전체 이미지에 먼저 convolution연산 후 작업들을 수행한다. 따라서 낭비되던 많은 연산들을 공유하고, 속도도 개선시켰다. 하지만 여전히 multi-pipeline이라는 단점은 해결하지 못했고, SPPnet에서 제안한 fine-tuning 기법으로는 conv layer를 학습하지 못했다(R-CNN은 가능했다).

본 논문에서는 위 단점들을 극복하고 다음과 같은 특징을 가진 새로운 Detection 모델, Fast R-CNN을 제안한다.

  • accuracy & speed 모두 개선
  • multi-stage가 아닌 single-stage training
  • 네트워크의 모든 layer들을 학습할 수 있음


🚀 Fast R-CNN architecture and training

architecutre

Fast R-CNN의 핵심은 다음 두 가지라 할 수 있다.

  1. 기존의 방식은 RoI를 input으로 받지만, fast rcnn은 전체 이미지(원본)를 input으로 받는다.
  2. classify와 box regression을 single-stage로 학습한다.

이러한 차이점은 단순해 보이지만 학습 방법에 큰 변화를 가져온다.


RoI pooling layer

pooling

원본 이미지에서 region proposal → roi projection → fixed size로 max pooling (7x7)


Initializing from pretrained networks

Fast R-CNN은 기존의 R-CNN과 같이 pretrined network(e.g., VGG16)를 사용하는데, 다음과 같은 변환을 해주면 된다.

  • 네트워크의 마지막 pooling layer를 RoI pooling layer로 변환
  • 마지막 softmax layer를 (classify + box regression) softmax layer로 변환
  • 네트워크가 두 개의 input, 이미지 + RoI 를 받도록 변경


Fine-tuning for detection

Multi-task loss

\[\textbf{L}(p,u,t^{u},v) = \textbf{L}_{cls}(p,u) + \lambda [u \geq 1]\textbf{L}_{loc}(t^{u},v)\] \[p = (p_{0}, p_{1}, \cdots , p_{k})\] \[t^{u} = (t_{x}^{u}, t_{y}^{u}, t_{w}^{u}, t_{h}^{u})\]
  • p : (k+1)개 클래스에 대한 class score ( k + background=0)
  • u : inference하는 객체의 실제 class
  • t^u : class u에 대한 bounding box 비율을 조정하는 값
  • v : 실제 bounding box 좌표
  • λ : classify & box regression 비율 조정 (default = 1)
  • [ u≥1 ] : u=0일 경우 0 (background인 경우 box regression 수행x), 나머지 1


\[\textbf{L}_{cls}(p, u) = -log(p_{u})\] \[\textbf{L}_{loc}(t^{u}, v) = \sum_{i\in {x,y,w,h}}^{} smmoth_{L_{1}}(t_{i}^{u}-v_{i})\] \[smooth_{L_{1}}(x) = \begin{cases} 0.5x^{2} & \text{ if } |x|<1 \\ |x| - 0.5 & \text{ otherwise, } \end{cases}\]
  • R-CNN, SPP에서 box regression을 구할 때에는 L2 loss 사용했는데 종종 gradient exploding 발생. → L1으로 변경


Mini-batch sampling

R-CNN & SPPnet Fast R-CNN
batch1 batch2

Fast R-CNN은 mini-batch sampling 기법도 크게 개선했다. 기존의 방식은 서로 다른 128장의 이미지에서 RoI를 샘플링하는 방법이었지만, 개선된 방식은 2장의 이미지에서 각 64개씩 RoI들을 샘플링했다. 64개의 RoI 중 25%는 IoU>0.5인 실제 object, 나머지 75%는 IoU가 [0.1,0.5) 사이인 background. 이 비율( N=2, R=64 )은 저자들이 실험적으로 정한 비율인데, 이런 방식으로 진행하면 메모리를 훨씬 효율적으로 사용할 수 있다(feature map을 공유하므로). 너무 당연한 이야기라 드는 의문점은 왜 진작 하지 않았을까..


Back-propagation through RoI pooling layers

논문에 등장하는 RoI pooling layer는 저자들이 처음 제안한 layer이기 때문에 back-propagation 방법에 대해서도 소개해준다.

roi_pool

\[\frac{\partial L}{\partial x_{i}} = \sum_{r}^{}\sum_{j}^{}[i = i^{*}(r,j)]\frac{\partial L}{\partial y_{rj}}\] \[x_{i} : i_{th} \text{ activation input into the RoI pooling layer}\] \[y_{rj} : j_{th} \text{ output from the } r_{th} \text{ RoI}\] \[y_{rj} = x_{i*(r,j)} \text{ in which } i*(r,j) = argmax_{i^{'}\in R(r,j)}x_{i^{'}}\]


Scale invariance

저자들은 sclae invariance detection을 위해 두 가지 실험을 진행했다.

  1. pre-defined size로 바꾸고 input 넣기
  2. image-pyramid 방식 이용

image_pyramid

여기서 말하는 image_pyramid란 data augmentaion 느낌으로 하나의 이미지를 여러 사이즈로 변환하며 훈련시키는 방식이다. 언뜻 괜찮은 방법처럼 보이지만, gpu 메모리를 많이 잡아먹는 현실적인 문제도 있고 막상 해보니 소모하는 자원에 비해 성능 향상이 너무 작았다고 한다.


🚀 Fast R-CNN detection

inference

Detection에서의 inference 과정은 CNN의 inference와는 느낌이 다르다. 이미지당 대략 2000개의 RoI들이 존재하고, 각 영역들에 대해 모두 forward 연산이 수행되어야 한다. 뿐만 아니라 forward 수행 결과 나온 score들을 이용해 NMS까지 진행해야 한다. 따라서 inference speed가 굉장히 느리다.

latency

이때 저자들은 inference time 중 fc layer가 차지하는 비중이 생각보다 훨씬 크다는 것을 알았다. 단순 fc layer는 SVD를 이용해 쉽게 압축이 가능하기 때문에 Truncated SVD 방법을 이용해 inference 속도를 개선했다.


🚀 Main results

mAP 많이 좋아졌어요

mAP


training time, test time 모두 빨라졌어요

speed


Which layers to fine-tune

Fast R-CNN은 SPPnet과 달리 원본 이미지를 input으로 받는다. 따라서 backbone network인 VGG의 weight들도 학습이 가능하다. 그렇다면 VGG를 포함한 모든 layer들을 학습하는 것이 좋을까? 실험 결과 그렇지는 않다고 한다.

fine_tune

Fast R-CNN L 모델의 경우 VGG의 conv2_1 layer부터 학습하는 것이 가장 좋다고 한다.


🚀 Design evaluation

Does multi-task training help?

기존의 Detection 모델은 classify에 대한 loss, location에 대한 loss를 따로 계산했다. Fast R-CNN의 경우 두 task를 합친 loss를 정의했는데, 혹시 multi-task training을 했다가 성능이 떨어지지는 않을까? 이를 알아보기 위해 다음과 같은 실험을 진행했다.

multi-task

  • 1th column : only classify
  • 2th column : classify + box regression (disable bounding- box regression at test time) → 기존 모델과 비교하기 위해
  • 3th column : classify, bbox reg 따로따로
  • 4th column : Fast R-CNN method

결과적으로 성능이 올랐다는 것을 알 수 있다. 생각해보면 bbox location과 classify 성능은 서로 correlated 하기 때문에 두 개를 묶는 것이 합리적으로 보인다.


Scale invariance

sclae

  • single scale 학습 vs {480, 576, 688, 864, 1200} 각 크기에 대해 image pyramid를 이용한 학습
  • mAP 조금 상승 & inference time 크게 증가
  • 심지어 L 모델에서는 메모리 문제로 실험조차 못함
  • 결론 : 그냥 single sclae로 학습하자.


Do SVMs outperform softmax?

기존의 R-CNN, SPPnet은 one-vs-rest 방식의 SVMs을 이용하여 classify를 진행했다. 하지만 Fast R-CNN의 경우 muli-task pipeline을 합치기 위해 softmax로 분류를 한다. 혹시 이 과정에서 classify 성능이 떨어지지는 않을까?

SVM

결과는 응 아니야. 성능 증가는 미미하지만, one-shot fine tune이 가능하니 훨씬 이득이다.


Are more proposals always better?

Roi

Fast R-CNN은 selective search를 이용한 2천개의 RoI를 사용한다. RoI는 왜 하필 2천개를 사용할까? 많으면 많을 수록 좋을까? 위 그래프는 SS (selective search), Dense (DPM) 두 방식을 이용해 RoI 갯수를 계속 늘린 결과이다. RoI를 막 던지기 때문에 recall성능은 올라가지만 mAP성능은 어느정도 올라가다가 떨어지는 것을 볼 수 있다. 따라서 RoI는 무조건 많다고 좋은 것이 아니다.



맨 위로 이동하기

Paper 카테고리 내 다른 글 보러가기

댓글 남기기