본문 바로가기

머신러닝/[논문으로 짚어보는 딥러닝의 맥]

Image Detection 방법론: RCNN, SPPnet, FastRCNN, FasterRCNN

학습목표

 바로 앞 강의에서 Localization과 함께 언급됐던 Image Detection 방법론들을 알아보도록 하겠습니다. Detection 방법론은 두 파트로 나누어 이번 시간에는 R-CNN 계열의 논문들을 보며 강의를 진행하도록 할 예정입니다. 이번 강의에서는 R-CNN, SPPnet, Fast R-CNN, Faster R-CNN 이렇게 4가지 방법들을 배워보도록 하겠습니다.

핵심 키워드

  • Detection
  • R-CNN
  • SPPnet
  • Fast R-CNN
  • Faster R-CNN

학습하기

 이번에는 Image detection 에 관해 이야기해보겠습니다. 두 파트로 나누어서 설명할 건데요. 이번에는 R-CNN 계열의 논문들을 먼저 보겠습니다. R-CNN, SPPnet, Fast R-CNN 등이요. 그 다음에는 속도가 조금 더 빠른 시리즈. YOLO 등을 보겠습니다.

 먼저 R-CNN(Region proposal Network)입니다. "Rich feature hierarchies for accurate object detection and semantic segmentation" 이 논문은, DL을 이용한 Detection의 시초가 되는 논문입니다. 저번에 보셨던 Segmentation에서도 시초가 된 논문이 굉장히 중요했었는데요. 방법론이 간단할 수는 있지만 DL기법을 통해 Image detectin을 효과적으로 풀었다는 것에 큰 의의가 있겠죠. 일반적으로 CNN이 잘 되는 이유는, Conv layer의 Featrue extraction 능력이 탁월하기 때문이었죠. 이 논문도 그렇습니다. 이미지 안에서, Conv filter로 Feature를 뽑아내요. 그런데 Detection 문제가 Segmentation과 차별되는 것은, 혹은 문제를 어렵게 만드는 것은 뭐냐면, 물체를 네모를 쳐야한다는 건데, 이게 쉽지가 않습니다. Segmentation은 직관적으로 생각할 때, 24x24 Input image를 넣고 24x24 Output을 만들어주면되요. 각 픽셀이 어떤 분류값을 얻어내면 끝나는 거죠. 그래서 저런 데이터셋을 만들기만하면, End to end로 훈련을 끝낼 수가 있어요. 그런데 Detection은 바운딩 박스를 얻어내야한단 말이죠. 직관적으로 잘 떠오르지가 않아요. 그래서 이 논문에서는 그냥 DL과 관련없는 다른 방법론을 이용해서 수많은 바운딩 박스를 먼저 생성합니다. 논문에서는 약 2천개 정도. 그다음에 적당히 정사각형으로 Resizing하고, 그다음, 각각 다 CNN에 넣어서 분류를 합니다. 그래서 내가 분류하고싶은 대상이 20개다. 그러면 분류 클래스는 20개가 아니라 21개가 됩니다. 왜냐면, 바운딩 박스를 잔뜩 만들었기 때문에 그 바운딩 박스가 내가 찾고 싶은 것들 중 하나라는 보장이 없어요. 단순한 Background도 많다는 거죠. 그럼 이런 것들이 분류될 통이 필요하겠죠. 그래서 내가 [사람, 고양이, 강아지] 이랬다면 [사람, 고양이, 강아지, 배경]이렇게 세팅해줘야하는 거죠. R-CNN은 이게 전부입니다.

 R-CNN은 3개의 구성 요소로 이루어져있는데, 1. Generating category independent region proposals. 물체가 있을 것 같은 위치에 바운딩 박스를 생성하는 것. 이게 시간이 엄청 많이 걸려요. CPU를 쓰게되면 한 이미지에 1분도 걸립니다. 2. Extract a fixed length feature vector from CNN. 이제 바운딩 박스를 만들었으면 이걸 CNN에 통과시킵니다. 이 과정에서는 Pretrained CNN model을 사용합니다. 내가 최종적으로 쓸 모델에 넣는게 아니라. 그렇게 Pretrained CNN을 통해 바운딩 박스 이미지에 대한 Feature을 추출했으면, 3. linear SVM을 통해 분류를 하면 됩니다. 이게 R-CNN입니다.

 Region proposals은 여러 방법론이 있을 수 있어요. 여기서는 Selective search algorithm이란 걸 활용했는데요. 생각해보면 Region proposals이 정말 중요하죠. 내가 다음 과정을 백날 잘 만들어봐야, 앞단에서 바운딩 박스를 잘못 만들어서 그 어디에도 내가 찾는 특징이 없다면, 결과가 나올리 없죠.

 Feature extraction을 위한 Pretrained CNN으로는 AlexNet을 사용했습니다. 당시에는 GoogLeNet이 없었기 때문이겠죠. 그렇게 뒷단에 있는 4096개의 Feature을 사용했구요.

 자 다시 한번 처음부터, 하나의 이미지가 들어오면, 거기에 어떤 방법론을 써서 수 많은 바운딩 박스를 찾고, 그 바운딩 박스를 정사각형으로 Resizing하고, AlexNet에 넣어서 4096Dim data로 변환하고, 마지막으로 뭐가 남았죠? SVM을 이용해 분류하는거죠. 이런 과정에 GPU를 써도 이미지당 13초가 걸렸습니다. 왜 이렇게 오래걸릴까요. CNN이 오래걸리긴 해도 이렇게 느리진 않거든요. 단순하겠죠. 바운딩박스를 몇천개씩 뽑아대서 각각 CNN을 넣으니, 어쩔수가없겠죠. 여기서 생기는 Bottleneck을 없애기위해 뒤에 소개할 논문들이 쏟아졌습니다. 

 자 이제 테스트할 때를 생각해봅시다. 위의 흐름대로면, y 데이터가 전체 이미지 위에서 어디에 물체가 있는지에 대한 바운딩 박스로 표현이 될텐데, X를 통해 얻어진 어떤 바운딩 박스와 실제 바운딩 박스가 완전하게 겹쳐질 수 있냐면, 사실 거의 그럴 수가 없겠죠. 그래서 실제로는 실제 바운딩 박스와 예측 바운딩 박스가 얼마나 겹치는지, 그 정도를 보고 모델 평가를 하게 됩니다. 

 그럼 이제 훈련할 때는, 이게 좀 어렵습니다. 예측됬던 바운딩 박스와 실제 바운딩 박스가 안 맞는데, 훈련을 한다는건 예측되는 바운딩 박스의 위치를 실제 바운딩 박스의 위치에 맞게끔 옮겨줘야겠죠. 이게 Bounding box regression입니다. 하나의 바운딩 박스를 다른 바운딩 박스로 옮기기 위해서는, 중심점을 어떻게 옮길지, 종횡비를 어떻게 바꿀지 4개 Parameter를 학습하게 됩니다. 여기까지가 R-CNN이었고, 초기 모델이다 보니 그렇게 좋은 정확도는 얻지 못했습니다.

 이제 SPPnet입니다. Spatial Pyramid Pooling 이란 거는, 내가 지금 찾고 싶은 물체의 사이즈를 모르죠. 앞에 있으면 클거고, 뒤에 있으면 작을거고. 그러면 내가 어떤 분류기가 있는데, 이게 크기가 여러 개인 분류개를 가지고 있어야, 큰 사람도 사람이라고 하고, 작은 사람도 사람이라고 할 수 있겠죠. 그래서 하나의 이미지를 그냥 쓰는게 아니라, 그 이미지를 반으로 줄인거, 반의 반으로 줄인거 이런식으로 여러개의 크기가 다른 이미지를 만든다음에, 그 정보를 한 번에 고려하도록 분류기를 만들어요. 이렇게 하면, 분류 모델이 애초에 여러 스케일의 이미지에 적응이 되어있기 때문에, Robust해질수 있겠죠. SPPnet의 장점은 R-CNN의 단점이었던, 하나의 이미지를 학습하는데 너무 많은 CNN을 작동시켜야했다는 점을 해결했다는 거에요. 한 이미지를 여러 스케일로 나누고 한번에 CNN에 넣으면되니, 한 이미지를 2천번 CNN에 넣었던 것과 비교하면, 소요 시간 차이가 확실하지죠. 쨋든, CNN은 고정된 인풋 사이즈가 필요합니다. 뒷단에 있는 Fully conn layer 때문이죠. 이러한 문제를 해결하기 위해, R-CNN에서는 여러 바운딩 박스를 뽑고, 리사이징해서, CNN에 넣었는데요. SPPnet은 이미지를 CNN에 넣고, Conv feature map을 뽑고, Selective search로 바운딩 박스를 구하고, 각각의 바운딩 박스에 대해 Spatial pyramid pooling을 합니다. 결국 CNN은 단 한번 돌아가겠죠. Spatial pyramid pooling에 대해 조금 더 자세히 설명하면, 예를 들어 6x4짜리 Feature map이 있다고 가정합시다. 그러면 이걸 전체를 평균낸 값으로 1x1 만들고, 이걸 가로세로 반반으로 자른다음 각각의 영역을 평균내서 2x2 만들고, 6x4을 가로세로 4등분한 다음 각각의 영역을 평균내서 4x4만들고. 이걸 다 합칩니다.. 그렇게 만든 데이터를 Fully conn에 넣고, SVM을 통과시키고, 분류합니다. 이렇게하니 R-CNN에 비해 빠르고, 성능도 훨씬 올라갔습니다.

 이렇게 R-CNN과 SPPnet 봤는데요. 이번엔 Fast R-CNN입니다. 이름에서도 알 수 있죠. R-CNN 보다 빠르게 하겠다. SPPnet에서 R-CNN을 발전시킨건 CNN을 한 번 적용시키겠다. 그리고 Feature map 위에서 어떤 Sub region을 뽑겠다. Fast R-CNN도 비슷합니다. Sub region을 뽑을 때, Fixed length data를 만들어야되는데, 이걸 SPPnet은 SPP를 사용한거고, Fast R-CNN은 RoI, Regions Of Interest 를 사용하겠다. ROI Pooling이란건 간단한데요. 그냥, 어떤 이미지가 들어오면, 그걸 정해진 수만큼으로 영역을 나누고(SPP 처럼), 각각의 영역을 평균내서, 벡터화시키면되요. SPP의 특별한 케이스 중 하나라고도 볼 수 있습니다. 쨋든 여기까지가 Fast R-CNN이구요.

 Faster R-CNN, 사실 앞에서는 Region proposal 과정에서 기존의 이미지 처리 방법론인 Selective search를 사용했죠? 굉장히 Naive한 방법이란말이에요. 그런데 Faster R-CNN부터는 DL을 이용한 방법론이 적용되기 시작합니다. YOLO 등도 사실 아이디어가 비슷합니다. 다시, R-CNN은 느렸습니다. SPPnet은 정확도가 부족했구요. Fast R-CNN 역시 여전히 느려요. Region proposal Net과 Fast R-CNN을 결합한 Faster R-CNN은 빠르고, 정확합니다. 어떤 이미지를 동일한 사이즈로 바꾸기 위해서는 3가지 방법이 있다고 말합니다. 1. Pyramids of images. SPP처럼 이미지 자체의 사이즈를 줄여서, 멀티플 스케일드 이미지를 한 번에 고려하는 거죠. 2. Pyramids of filters. 종류가 다른 여러 Filter를 사용하는 거에요. Atrous Conv와 비슷한 아이디어입니다. 강제로 이미지 사이 사이에 0을 끼워넣어서 Feature map의 사이즈를 바꾸는. 3. Pyramids of anchors. anchors라는건 미리 정해져있는 바운딩 박스의 크기를 말합니다. 대충 바운딩 박스가 크기가 얼마일거라고 예상해보는 거죠. 바운딩 박스 크기가 얼마나 될지를 그냥 0부터 학습하는게 아니라, 대충 어느정도 될테니까 거기서 +-해서 찾아보라는 겁니다.  논문에서는 3개의 가로길이, 3개의 세로길이를 Reference length로 삼아서 총 9개의 anchors를 구성해 사용합니다. 

 자 그럼 이걸 어떻게 적용하냐. 어떤 이미지를 CNN에 통과시키면 Feature map이 나올텐데, 이건 기존의 이미지의 정보를 조금 손실한, 조금 더 작은 사이즈의 이미지겠죠. 그럼 이 데이터를 이용해 기존 이미지에 점을 찍는 겁니다. 그 점이 전체 이미지 분류에서 중요한 역활을 한다는 걸테니까요. 그리고 그 점을 기준으로 만들어 뒀던 여러개의 Bound box를, anchor를 씌워보는 겁니다. 그럼 그런 Bounding box가 내가 찾는 Bounding box인지 확인하려면 각 BB별로 점수를 매겨야하고, 여기서는 [Positive score, Negative score]처럼 2개 점수를 배당했습니다. 각 BB마다요. 두번째로, 미리 정해놓은 BB를 어떻게 움직여야 내가 원하는 자리를 찾아갈까에 대한 정보값이 필요하겠죠. 이는 결국 각 BB마다 4개의 Coordinate값이 필요하게 되겠죠. 그래서 Region proposal network는 Fully conv network처럼  k*(4+2) size의 벡터를 Output으로 뽑아내게 됩니다. 이렇게 하니까 기존방법론보다 더 좋았습니다. 언뜻보면 Residual network같은 느낌이죠. 굉장히 큰 물체와 작은 물체를 모두 잘 잡습니다. 이상입니다.