[논문 리뷰] Fast R-CNN 본문
1. Abstract & Introduction
이번에는 Fast R-CNN에 대한 논문 리뷰를 해볼 것이다.
Fast R-CNN(Fast Region-based Convolutional Network method)는 object detection에서 주로 사용한다. 기존 R-CNN보다 training & testing speed를 증대하고 detection accuracy를 높였다. Deep VGG16 network에서 Fast R-CNN은 R-CNN보다 9배 빨리 학습시켰고 test time에는 213배 빨랐다. PASCAL VOC 2012에서는 R-CNN보다 높은 mAP(mean-Average Precision)을 달성했다. Faster R-CNN은 SPPnet보다도 빠르고 정확한 결과값을 돌려준다. Fast R-CNN의 코드를 확인하고 싶으면 아래 링크를 참조하라.
https://github.com/rbgirshick/fast-rcnn
Fast R-CNN은 object detection에서 사용한다고 했는데, object detection은 image classification에 비하여 해결해야할 복잡한 문제가 많다. Detection은 object(물체)의 정확한 위치를 파악(localize)해야 하는데, 이는 두 문제점을 야기한다.
- Object가 있을 법한 위치들에 후보군을 설정해야 한다. (그 후보군들을 "proposals"라고 칭한다)
- 후보군들은 "rough localization"을 통하여 형성되기 때문에 정확한 localization을 위하여 정제의 과정을 거쳐야 한다.
(논문이 나왔을 당시) Fast R-CNN은 CNN기반 SoTA object detector이었고, single-stage training algorithm으로써 object proposal classification 및 spatial location refining을 동시에 할 수 있다. 속도, 정확성, 간결함도 만족하였다.
1.1 R-CNN and SPPnet
기존 R-CNN은 아래와 같은 문제점이 존재했다.
- 학습 시 multi-stage pipeline이 존재하였다. 먼저 log loss를 활용하여 convolutional network를 fine tune하고, 그 feature들로 SVM(Support Vector Machine)에 적용시킨다. SVM은 softmax classifier의 대체였고, fine-tuning으로 인해 학습되었다. 마지막으로 bounding-box regressor들이 학습되었다.
- 훈련 시 시공간적 비용이 엄청나다. SVM 및 bounding-box regressor training 같은 경우 이미지마다의 region proposal에 대하여 feature들이 계산되기 때문에 많은 시간이 걸린다. VGG16같은 깊은 network로 R-CNN을 학습시키면 몇백 기가바이트의 저장소가 필요할 뿐만 아니라 학습시킬 때 2.5GPU일이 걸린다.
- Object detection 자체가 그냥 느리다. GPU로 VGG16를 사용하였을 때 한 이미지 당 detection 시간이 47초이다.
3번에 대한 부가설명을 조금 하자면, object detection이 느린 이유는 forward pass를 할 때 각 object proposal마다의 연산이 공유되지 않기 때문이다.
이를 극복하려고 SPPnet이 출시되었다. SPPnet은 전체 이미지에 대한 convolutional feature map으로부터 추출된 feature vector로 각각의 object proposal을 분류한다. 추출은 proposal 안에 있는 feature map들이 max pooling으로 정해진 크기의 출력값(ex: 6 * 6)을 출력한다. 여기서 여러 크기의 출력값들이 pooled되고 하나의 spatial pyramid pooling으로 합쳐진다. Test time에서 SPPnet을 활용하면 R-CNN보다 10~100배 이상의 속도를 낼 수 있다고 한다. Training time도 3배 정도 줄어든다고 한다. 그러나 R-CNN처럼 multi-stage pipline을 사용하면서 feature을 추출하고, log loss로 네트워크를 fine-tuning 하고, SVM을 학습시키고, bounding-box regressor까지 학습시켜야 한다. (연산해야할 것들이 너무 많다.) 또한 fine-tuning 알고리즘은 spatial pyramid pooling전의 convolutional layer들에 대한 값들을 조정하지 못한다. 그러므로 깊은 층이 있을 때 좋은 결과를 낼 수가 없다.
1.2 Contributions
Fast R-CNN은 R-CNN과 SPPnet의 단점을 보완하였다. Fast R-CNN의 이점은 아래와 같다.
- Detection quality(mAP)가 R-CNN, SPPnet보다 높았다.
- 학습은 single stage로 이루어지고, multi-task loss가 사용되었다.
- 학습을 통해 모든 네트워크 층에 대한 update를 가능하게 하였다.
- Feature caching을 위한 디스크 저장소가 필요 없어졌다.
2. Fast R-CNN Architecture and Training
Fast R-CNN은 다음과 같은 방식으로 이루어져 있다.
- Fast R-CNN은 input으로 이미지 전체와 object proposal set이 들어간다. 네트워크는 먼저 convolutional layer로 이미지들을 통과시키고 convolutional feature map을 형성한다.
- Region of interest(ROI) pooling layer에서 feature map로부터 a fixed-length feature vector을 각 object proposal마다 추출한다.
- 각각의 feature vector은 fully-connected (FC) layers들을 통과하여
- K개의 object class + 1 background class에 대한 softmax
- K개의 object class 각각에 대한 4개의 실수 (4개의 실수는 Bounding box 위치를 파악 및 bounding box regression을 하기 위하여 사용된다.)
를 생성한다.
Fast R-CNN의 개요를 확인하려면 아래 이미지를 살펴보아라.
2.1 The ROI Pooling Layer
ROI pooling layer은 H*W크기의 spatial extent안에 유효한 valid region of interest를 작은 feature map으로 변환시켜 max pooling을 사용하는 층이다. (직역을 하여 문체가 매우 난해하다... 설명이 어렵다면 아래 예시를 보자!)
H, W는 hyperparamter로써 특정 RoI와는 독립하다.
각 RoI는 4개의 원소가 있는 튜플 (r, c, h, w)로 정의한다. (r,c)는 왼쪽 위 모서리 위치를 알려주고 (h,w)는 (r,c)를 기점으로한 height랑 width값을 각각 알려준다.
ROI pooling layer에 대한 자세한 설명은 아래 예시를 참조하면서 설명하고자 한다. (필자가 해당 방식으로 이해하였기 때문이다.)
크기가 800*800인 이미지가 있다고 치자. 그리고 이 이미지를 convolutional layer(VGG)에 통과시켜 8*8 feature map을 생성하였다고 하자. 이는 앞서 언급한 H, W의 값이다. (부가적으로 sub-sampling ratio는 원본 이미지에서 convolutional layer에서 feature map이 형성되기까지 pooling의 비율이다. 위의 경우 sub-sampling ratio는 8/800=0.01 이다.)
동시에 특정 방식(ex: selective search)로 추출한 region proposal로 500*700의 영역을 얻었다고 치자.
우리는 이 region proposal이 8*8 feature map에서 할당되는 부분이 어디인지 찾아내어 추출한다. 이는 region projection이라는 기법으로 확인 가능하다. 그 크기를 구하려면 region proposal 값과 sub sampling ratio를 곱해주면 된다. 즉 feature map에서 나타나는 region proposal(RoI feature map)의 크기는 (500 *(0.01), 700*(0.01)) = (5,7)이다.
그 다음 sub-window의 크기를 2*2로 설정하였으므로 5*7을 그 크기에 맞게 영역을 나누어준다.
마지막으로 영역 내에서 max pooling을 하여 2*2 feature map을 최종적으로 얻는다.
즉, region proposal의 크기가 달라도 ROI pooling layer로 고정된 크기의 feature map을 얻을 수 있다.
해당 예시는 아래의 블로그에서 퍼왔으며, 상기 서술한 내용은 논문의 것과는 차이가 있다.
https://herbwood.tistory.com/8
2.2 Initializing from Pre-Trained Networks
Fast R-CNN은 pre-trained된 3개의 ImageNet 네트워크를 사용하였다. 각각의 네트워크는 5개의 max pooling layers가 있었으며, 5~13개 사이의 convolutional networks가 있었다. 이 3개의 네트워크가 Fast R-CNN에 사용되었을 때, 그에 맞게 3가지 변형을 하였다.
- 마지막 max-pooling layer이 ROI pooling layer로 변형되었다. 이는 첫 FC layer의 node를 H*W와 호환되도록 설정하였다. (VGG16에서는 7*7)
- 모델의 마지막 FC layer 및 softmax가 K개의 object class + 1 background class에 대한 softmax / bounding box regressors 로 변형되었다.
- 이미지 리스트 및 그 이미지에 대한 ROI가 모델의 두 inputs으로 사용되었다.
2.3 Fine Tuning for Detection
아까도 언급하였지만, Fast R-CNN의 장점 중 하나는 backpropagation을 통해 네트워크 내 모든 가중치를 update할 수 있다는 것이다. 이 방법은 feature sharing이라는 기법으로 가능하였다. Fast R-CNN을 학습시킬 때, stochastic gradient descent(SGD) 미니 배치들이 "계층적"으로 샘플링(hierarchial sampling)되었는데, N개의 이미지를 먼저 샘플링하고 각 이미지마다 R/N개의 ROI를 생성하였다. 예를 들어 N=2개의 이미지가 하나의 미니배치로 형성되고 R=128이라면, 각 이미지마다 64개의 ROI가 생성된다. Feature sharing을 사용하면 같은 이미지에서의 region proposal은 서로의 연산 및 메모리를 공유할 수 있다는 장점이 있다. 또한 하나의 fine-tuning stage에서 softmax classifier과 bounding box regressor을 동시에 조정하기 때문에 연산이 공유된다.
Multi Task Loss
마지막 output layer은 2가지 결과물을 출력한다. 첫 번째로는 discrete probability distribution(per RoI)를 진행하여, K+1 개의 카테고리(+1은 배경)에 대하여 p = (p0, ... , pk) 의 분포를 돌려준다. 각 p는 softmax 함수로 나타낸다. 두 번째로는 bounding-box reression offsets를 진행하는데, 이를 나타내는 식은 tk = (txk, tyk, twk, thk) 이다. k는 각 object class를 나타낸다. 또한 아래첨자의 x, y, w, h에서 x, y는 중심점, w, h는 각각 너비와 높이를 의미한다.
또한 training ROI에는 ground-truth class "u" 및 ground-truth bounding-box regression target v = (vx, vy, vw, vw)가 존재한다. 우리는 두 결과물과 ground-truth를 비교하여 비용함수를 구한 후 모델을 학습시킬 것인데, 그 때 발생하는 비용함수를 Multi-task loss라고 한다.
Multi-task loss의 식은 아래와 같다.
식의 구조는 생각보다 어렵지 않다. Lcls는 classification에서 발생하는 손실이고 Lloc는 localization에서 발생하는 손실이다. 그리고 그 두 비용함수는 서로 더해져 최종 비용함수를 얻을 수 있다. 각 부분을 상세히 살펴보자.
먼저 classifcation loss 같은 경우, Lcls(p, u) = -logpu의 식으로 표현한다. 이는 실제 class u에 대한 log loss이다.
다음 localization loss는 조금 더 복잡한 형식으로 이루어져 있다. 위 이미지의 두 번째 항을 왼쪽부터 차례대로 살펴보자.
- 람다는 두 개의 task losses에 대한 균형을 유지한다. 모든 실험은 람다를 1로 설정하였다.
- [u≥1]은 Iverson bracket indicator function이라고 한다. 만약 u가 1이상일 경우 1의 값을 출력하고, 그 외에는 0의 값을 돌려주는 함수이다. 배경에 대한 class는 u=0이라고 한다. Bounding box에 대한 ground truth가 없기 때문이다.
- Lloc(tu, v)에서 tu는 class u에 대한 predicted tuple을 의미하며, tu = (txu, tyu, twu, thu)의 형태이다. 그리고 Lloc(tu,v)는
의 형태이다. L1 loss를 사용한 이유는 이상치에 덜 민감하기 때문이다. 또한 각 vi들은 정규화하여 평균 0 분산 1을 가지도록 설정하였다.
Mini-batch Sampling
Fine-tuning 시 각 SGD 배치는 N = 2 이미지와 R = 128로, 각 이미지마다 64개의 ROI를 샘플링한다. 그 다음 우리는 intersection of union(IOU)가 0.5 이상인 object proposal 중에서 25%의 ROI를 가져와 foreground object class(u≥1)를 형성한다.
그 외 ROI들은 IOU가 0.1이상 0.5 미만인 object proposal 중에서 샘플링 되며, 이들은 background examples에 해당한다. 그러므로 u = 0이다.
또한 data augmentation의 일환으로 0.5의 확률로 이미지를 가로로 뒤집는다고도 하였다.
Backpropgation through ROI Pooling Layers
당연히 backpropagation을 할 때 ROI pooling layer들을 구하며 미분값들을 구할 것이다. 명확성을 위하여 본 예시에서는 N = 1로 설정할 것이다. 먼저 각 notation을 살펴보면
- xi는 ROI pooling layer에 입력되는 i번째 activation input
- yrj는 r번째 ROI에 대한 j번째 출력
이다.
Backpropagation을 하기 전 ROI pooling layer의 연산을 먼저 살펴보자.
그 꼴은 yrj = xi * (r,j)이다. 그리고 i * (r,j) = argmaxi'xi'이다.
xi'는 영역 내에서의 최대값이고(argmax 함수를 사용하기 때문) i'는 영역을 나타내는 것이라고 생각하였다. 그리고 그 영역은 R(r,j)로 표현된다고 한다.
ROI pooling layer의 backpropagation은 아래의 식과 같이 연산한다.
[]내에서 i가 yrj 에서 선택된 argmax일 때만 그 미분값을 구하여 더하는 방식으로 이루어진다.
[]는 앞서 설명한 iverson bracket indicator function이다.
SGD hyper-parameters
- Softmax classification 이랑 bounding-box regression에 사용된 FC layer들은 평균 0, 그리고 표준편차가 각각 0.01과 0.001이다.
- Bias는 0으로 설정되었다.
- 가중치의 per-layer learning rate에는 1, bias에는 2가 사용되었으며 global learning rate는 0.001이다.
- VOC07, VOC12를 학습시킬 때 SGD를 30k mini batch iteration을 사용하였다. 그 다음 learning rate를 0.0001로 줄여 다른 10k의 iteration을 학습하였다.
- Momentum은 0.9, Weight Decay는 0.0005를 사용하였다.
2.4 Scale Invariance
Scale invariance란 이미지의 크기에 상관없이 그 성질이 유지되는 것을 의미한다.
Scale invariant object detection을 위해서는
- Brute-force approach
- Multi-scale approach (image pyramid 활용)
이 있다. Brute-force approach는 이미지가 training 및 testing 시 지정된 특정 픽셀 사이즈로 고정됨을 뜻한다. 그리고 네트워크는 training data에서 배운 이미지 사이즈로 testing에도 object detection을 한다. Multi-Scale Approach는 image pyramid를 사용하여 네트워크에 대략적인 scale-invariance를 부여한다. 그러나 GPU의 한계로 인하여 작은 네트워크에서만 진행한다고 한다.
3. Fast R-CNN Detection
Fine tuning 이후에 네트워크는 input으로 이미지 및 R개의 object proposal을 받는다. Test time 때 R의 개수는 약 2000개이다.
3.1 Truncated SVD for Faster Detection
Object detection에서는 processing해야할 ROI의 개수가 많기 떄문에 forward pass을 할 때 걸리는 시간의 절반이 FC layer을 연산하는 데에 사용된다. 그래서 truncated SVD라는 방식을 사용하여 FC layer에서 걸리는 시간을 단축시킬 수 있다.
Truncated SVD를 간단히 설명해보고자 하는데, 그 전에 Full SVD에 대하여 먼저 확인해보자.
아래 이미지처럼 행렬 A를 mxm크기의 U, mxn크기 ∑, nxn 크기 VT 로 특이값 분해(SVD)를 진행하는 과정을 Full SVD라고 한다. 이제 Truncated SVD를 살펴보자.
Truncated SVD는 ∑에서 비대각 부분 및 특이값이 0인 부분을 제거하고, 그 부분에 해당하는 U, V의 원소까지 제거하여 SVD의 차원을 줄인 것이다. 이렇게 연산을 해도 full SVD에서의 행렬 A와 유사한 값을 얻을 수 있다.
(이 부분 또한 ROI pooling layer를 설명할 때 참조한 링크에서 한 번 더 참조하였다.)
우리가 Fast-RCNN에서 구해야할 u * v 가중치 행렬 W는 아래와 같이 factorize할 수 있다.
W=≈U∑tVT
이 방식을 사용하면 parameter의 개수를 u*v에서 t(u+v)로 줄일 수 있다는 장점이 있다. 그리고 t가 min(u,v)보다 훨씬 작은 값을 내면 더욱 큰 효과를 낼 수 있다고 한다. 그리고 네트워크를 압축하기 위해서 하나의 FC layer였던 W를 두개의 FC layer로 대체한다. 첫번째 layer은∑tVT 를 가중치 행렬로 사용하고, 두 번째 layer은 U를 가중치 행렬로 사용한다.
4. Main Results
Fast-RCNN으로
- SoTA mAP on VOC07, 2010, 2012
- R-CNN, SPPnet보다 바른 training & testing
- VGG16의 층들을 fine-tuning하여 mAP 증가
를 이루었다.
4.1 Experimental Setup
세가지 학습된 ImageNet 모델을 사용하였다.
R-CNN으로부터 가져온 CaffeNet을 S,
VGG_CNN_M_1024를 M,
VGG16을 L로 설정하였다.
S, M, L은 모델의 크기에 따라 분류되었다.
4.2 VOC 2010 2012 Results
VOC 2010 Results
Baby Learning, R-CNN BB, SegDeepM 과 Fast-RCNN을 VGG16 network로 비교하였다. Baby learning에 대한 정확한 convnet architecture은 존재하지 않았고, R-CNN 기반의 pipeline으로 만들어졌다고 한다. SegDeepM 은 Markov Random field을 사용하여 detection과 segmentation을 용이하게 하였다. Fast R-CNN에서 07++12의 enlarged training set을 사용할 경우, Baby learning과 SegDeepM보다 높은 mAP를 얻었다.
VOC 2012 Results
NUS_NIN_c2000 또한 정확한 convnet architecture을 알 수 없고, R-CNN 기반 pipeline으로 만들어졌다. Fast R-CNN의 mAP가 가장 높은 것을 확인할 수 있다.
4.3 VOC 2007 Results
VOC 2007은 Fast R-CNN과 R-CNN & SPPnet을 VGG16네트워크로 비교한다. (당연히) Fast-RCNN의 mAP가 가장 높다.
4.4 Training and testing time
VGG16(L)을 비교하였을 때, training time은 R-CNN에 비하여 8.8배 빨라졌고(9.5시간으로 단축), test를 진행하였을 때도 truncated SVD 없이는 146배, truncated SVD가 있을 때에는 213배 빨라지는 모습을 볼 수 있다. 또한 디스크 저장소를 쓰지 않는다는 장점도 있다.
Truncated SVD
Truncated SVD를 사용하면 detection time을 30% 줄일 수 있다. (물론 0.3%의 mAP 감소는 있다.) 아래 이미지는 truncated SVD를 사용하지 않았을 때(왼쪽)와 truncated SVD를 사용했을 때(오른쪽)을 비교한다.
4.5 Which Layers to Fine Tune?
SPPnet에서는 FC layers에 대해서만 fine-tuning을 진행하였다. 하지만 VGG-16(L) 같은 깊은 network의 경우에는 conv layers까지 fine tuning 하는 것이 더 좋은 결과를 불러들일 것이라고 생각하였다. 실험 결과 conv layers까지 조정한다면 더욱 높은 mAP를 얻을 수 있다는 것을 알 수 있다. 특히 conv 3_1부터 조정하는 것이 좋다고 한다. conv 2_1부터 조정해봤자 0.3%의 mAP 증가밖에 얻지 못함과 동시에 training 시간이 1.3배 늘어나고, conv1_1부터 조정하면 GPU의 메모리가 폭증한다.
그러나 S, M 같은 얕은 네트워크에서는 conv_1의 조정이 mAP에 유의미한 효과를 보여주지 못한다고 하였다. 그래서 conv2_1부터 조정하는 것이 좋다고 한다.
5. Design Evaluation
Fast R-CNN이 R-CNN 및 SPPnet보다 우수한 성능을 보인다는 것을 알았으니, PASCAL VOC07 dataset에 기반하여 실험을 해본다.
5.1 Does Multi-task Training Help?
Multi-task training은 multi-pipeline이 없고, 서로의 연결성 때문에 결과가 더 잘 나온다는 장점이 있다. 본 논문은 Fast R-CNN이 multi-task training을 통해서 높은 accuracy를 얻는지 확인해 보았다.
실제로 classification loss만 사용했을 때, multi-task training + bounding box regressor을 학습하지 않았을 때, classification loss + 다른 parameter을 frozen 상태로 고정했을 때 보다 multi-task training을 하면서 bounding box regressor을 사용했을 때 mAP가 증가한다. (아래 이미지에서 각각의 경우는 S,M,L의 첫 번째, 두 번째, 세 번째, 네 번째 열에 대응한다.)
5.2 Scale Invariance: to Brute Force or Finesse?
위에서 언급하였듯이 Brute-Force Approch 및 Multi-Scale Approach 중 어느 것이 더 좋은지 학습해보았다.
Brute-Force Approach에서는 1개의 scale을 사용하여 픽셀 사이즈를 600으로 고정하였고, Multi-Scale Approach에서는 5개의 scale {480, 576, 688, 865, 1200}을 사용하였다. 결과 또한 앞서 얘기했던 것과 같이 S,M에서는 Multi-Scale Approch가 좋은 mAP를 보였고, L에서는 Brute-Force Approach가 높은 mAP를 보였다.
5.3 ~ 5.5
5.3은 training data가 많으면 mAP가 올라간다고 설명한다.
5.4는 SVM보다 Softmax가 L에서 더 좋은 성능을 낸다고 한다.
5.5는 object proposal이 많다고 무조건 mAP가 올라가는 것은 아니라고 한다.