열심히 정리해본 딥러닝: Faster R-CNN

임성완·2022년 1월 3일
0
post-thumbnail

"Faster R-CNN"

- R-CNN 패밀리 중 하나 (R-CNN, Fast R-CNN, Faster R-CNN, Mask R-CNN)

- Fast R-CNN 보다 향상된 속도와 정확도, 또한 RoI 추출 과정을 Neural Network에 넣어서 모든 과정 GPU 병렬처리 가능


Faster R-CNN 과정을 요약한 이미지입니다.

Faster R-CNN에서는 속도가 느린 Selective Search 를 사용하지 않고 대신 RPN(Region Proposal Network)를 사용합니다. 따라서 Fast R-CNN에 비해 속도가 향상되었습니다.


Faster R-CNN의 흐름을 잘 요약해놓은 이미지가 있어서 가져왔습니다.

1. CNN layers


입력 이미지를 위와 같은 pre-trained ZFNet 신경망에 통과시킵니다.
그리고 Layer 5에서 13 * 13 * 256 feature vectors를 추출합니다.(입력 이미지의 크기에 따라 조금씩 달라질겁니다)
논문에선 ZFNet을 사용한 경우가 mAP가 가장 높았다고 하지만 VGG를 써도 되는것 같습니다.

2. Region Proposal Network


위 이미지는 RPN을 요약한 이미지입니다.

2.1. Anchor generation layer

RPN에서 Region Proposal을 방법은 Anchor box를 생성하는 Anchor generation layer입니다. 3개의 scale과 scale마다 각각 3개의 ratio를 가진 Anchor box를 생성합니다.
3개의 scales는 PASCAL VOC 2007 detection dataset 기준 각각 {128, 256, 512}\begin{Bmatrix} 128,\ 256,\ 512 \end{Bmatrix} 입니다.
그리고 3개의 ratios는 각각 {0.5, 1, 2}\begin{Bmatrix} 0.5,\ 1,\ 2 \end{Bmatrix}로 세로:가로가 각각 2:1, 1:1, 1:2 이라고 생각하면 됩니다.
또한 ratios에 따라 s(scale)을 알면 h(세로)와 w(가로)를 구할 수 있는 식이 정의되어있습니다. 이 식은 다음과 같습니다.

ratio = 0.5(2:1)일 때:
h=2s2h = \sqrt{2s^2}
w=2s22w = \frac{\sqrt{2s^2}}{2}

ratio = 1일 때:
h=w=sh = w = s

ratio = 2일 때:
h=2s22h = \frac{\sqrt{2s^2}}{2}
w=2s2w = \sqrt{2s^2}

그리고 scale이 이미지의 크기에 따라 바뀌는것 같습니다. 글마다 scale이 달라서 여러가지로 계산을 해봤더니 scale을 계산할 수 있는 식이 나왔습니다.
(height는 input 이미지의 세로 길이)
s1=height/6.25s_1=height / 6.25
s2=height/3.125s_2=height / 3.125
s3=height/1.5625s_3=height / 1.5625

이 anchor boxes를 움직여야합니다. 이때 sub-sampling ratio라는 개념이 나옵니다. sub-sampling ratio란 입력 이미지와 feature map의 비율을 말합니다. 즉, 입력 이미지에서 얼마나 축소되었는지를 나타내는 값입니다. 이 sub-sampling ratio가 116\frac{1}{16} 이라고 가정하면 feature map 한 픽셀에 입력 이미지의 16 * 16 만큼의 정보를 담고 있는 거라고 볼 수 있습니다. 따라서 feature map 안에서 1픽셀 씩 이동시키며 anchor box의 값을 저장합니다. 이 때 h와 w는 전의 식 대로 쓰면 될 것이고 x와 y는 (features map에서의 x or y) * (sub-sampling ratio) 로 구할 수 있습니다. 이 정보들(x, y, w, h)을 합쳐서 50 * 50 * 9(anchor box의 수) 형태의 텐서로 저장합니다. 어떤식으로 합쳐서 저장하는지는 정확히 논문에 나와있지 않지만 아마도 50 * 50 * (9 * 4) 와 같은 형태로 저장하지 않을까 싶습니다.

2.2. Anchor target layer

2.1.에서 생성한 region proposal과 ground-truth의 IoU를 비교합니다.
0.7보다 크면 positive label로,
0.3보다 작으면 negative label로 분류합니다.

2.3. Proposal layer

이제 feature map을 가져와서 3*3의 sliding window 연산을 진행합니다. 이는 3*3의 conv 연산을 하는것과 같습니다. 이때 필터의 채널 수는 feature map의 채널 수와 같게 합니다. 그 후 각각 두번 1*1 conv 연산을 진행합니다. 따라서 output은 2개가 나옵니다.
첫번째 conv layer의 필터는(이 때 k는 anchor box의 수인 9) 1*1*2k 로 클래스의 개수인 2를 곱해줍니다. 여기서 클래스의 개수가 2인 이유는 RPN에서는 해당 region proposal이 객체인지 배경인지만을 알아내기 때문입니다.
두번째 conv layer의 필터는 1*1*4k 로 region proposal의 정보의 개수, 즉 x, y, w, h 총 4를 곱해줍니다.

위 이미지가 이 과정을 잘 요약해주고 있습니다.

2.3.1. Loss function

loss function은 다음을 사용합니다.

pi{p_i}^*는 anchor가 positive면 1이 되고 negative면 0이 되는 ground-truth label입니다.
ti{t_i}^*는 실제 ground-truth의 위치, 크기 정보입니다.
tit_i는 예측된 bounding-box의 위치, 크기 정보입니다.
pip_i는 예측된 클래스입니다.(0 or 1)

Ncls=256N_{cls} = 256 (mini-batch size)
Nreg2400N_{reg} \sim 2400 (anchor box 개수(scale과 ratio를 고려한))
λ=10\lambda = 10 (하이퍼피라미터)

Lreg=smoothL1L_{reg} = smooth\, L_1
이때 smooth 함수는 fast r-cnn의 smooth 함수와 동일합니다.


tit_i^* 를 구하는 식은 위와 같습니다.
i=i= predicted bounding-box
ia=i_a= anchor box
i=i^*= ground-truth

2.3.2. Non-Maximum Supression

6천여개의 bounding-box를 겹치는 것들을 제거해서 300개 정도로 줄입니다. 이 작업은 정확도를 향상시키면서 이후의 연산들에 대한 연산량을 줄일 수 있습니다.

아까전에 구했던 각각 bounding box의 confidence score(RPN 출력중 H*W*18 벡터에서 각각의 score) 중 confidence scroe threshold 를 넘지 않는 bounding box는 제거합니다. 그 후 남은 bounding box들의 score를 비교해서 가장 큰 것부터 정렬합니다. 그 후 score가 가장 큰 박스와 다른 박스들의 IoU를 각각 구하고 이 IoU가 threshold 값을 넘는 것은 동일한 객체를 감지했다고 생각하고 제거합니다. 이 때 threshold와 confidence scroe threshold의 정확한 값은 논문에 나와있지 않습니다.

어쨌든 겹쳐있는 여러가지 박스를 가장 정답에 가까운 박스 하나만 남긴다고 생각하면 될 것 같습니다.

3. Detection Network

Fast R-CNN에서 쓰였던 RoI pooling을 진행합니다.
https://velog.io/@sungwanim/%EC%97%B4%EC%8B%AC%ED%9E%88-%EC%A0%95%EB%A6%AC%ED%95%B4%EB%B3%B8-%EB%94%A5%EB%9F%AC%EB%8B%9D-Fast-R-CNN#2-cnn-layers
위 링크는 저번에 작성한 Fast R-CNN 글로 RoI Pooling도 다루고 있습니다.

Fast R-CNN 에서 Region Proposal을 추출하는 Selective Search 작업을 RPN으로 대체한거라고 생각하시면 됩니다.

4. 4-Step Alternating Training

4.1. 1st step

ImageNet-pre-trained로 초기화된 VGG or ZFNet을 이용해서 end-to-end 방식으로 region proposal을 추출하는 과정, 즉 RPN을 학습시킵니다.

4.2. 2nd step

첫번째 단계에서 생성된 region proposals을 가지고 Detection Network를 학습합니다. 이 Detection Network 또한 ImageNet-pre-trained로 초기화되어있습니다.

4.2. 3rd step

RPN과 Detect Network를 불러온 후 RPN을 제외한 다른 CNN의 가중치를 고정시킨 뒤 RPN만 fine-tuning 합니다.

4.2. 4th step

같은 방법으로 CNN의 가중치를 고정시킨 뒤 Detection Network만 fine-tuning 합니다.

끝났습니다. 다음 글은 Yolo를 리뷰할 생각입니다.
여담으로 어렸을 때 큐브를 맞춰보신 분들이라면 아시겠지만 region proposal 생성만 Faster R-CNN 고유의 방법으로 하고 그 후 방법은 Fast R-CNN의 과정을 사용하는것을 보면 마치 5* 5 큐브를 맞추다 보면 초중반까지는 고유의 공식을 사용하다가 마지막은 3 * 3 큐브의 공식대로 맞추는데 그 방법이 떠오르네요.

참고한글:
논문: Faster R-CNN: Towards Real-Time Object
Detection with Region Proposal Networks
전체적인 논문 요약: https://deep-learning-study.tistory.com/464
RPN loss: https://medium.com/@lsrock125/faster-r-cnn-%EB%85%BC%EB%AC%B8%EC%9D%BD%EA%B8%B0-1a7fdc9c43ee

profile
미래를 꿈꾸는 고등학생 개발자입니다

0개의 댓글