본문 바로가기

AI/CS231N

Lecture 11 : Detection and Segmentation

해당 게시물은 Standford 2017 CS231n 강의를 들으며 정리한 내용이며 슬라이드를 바탕으로 작성되었습니다.

 

 

 

지난 강의에서는 RNN에 대해서 배웠습니다. 이번 강의에서는 Segmentation, Localization, Detection과 같은 여러 CV의 task에 대해 배워 보겠습니다.

 

위 그림은 여러 CV Tasks에 대한 그림입니다. 우선 Semantic Segmentation에 대해 보겠습니다.

 

Semantic Segmentation

우선 Semantic Segmentation은 입력으로 이미지를 받고, 그에 대한 출력으로 이미지의 모든 픽셀에 카테고리를 정합니다. Semantic Segmentation도 Classification처럼 카테고리가 있지만 다른 점은 classification은 이미지 하나에 카테고리가 하나만 정해지지만 segmentation은 모든 픽셀에 대해 카테고리가 정해집니다.

 

하지만 semantic segmentation의 단점은 개별 객체를 구분하지 않는다는 것입니다. 위 그림에서 하나의 이미지에 소가 두 마리가 있다고 해도 하나의 Cow라는 카테고리로 분류합니다.

 

먼저 semantic segmentation를 어떻게 진행할지에 대한 Idea를 소개하겠습니다.

semantic segmentation 문제에 접근할 수 있는 방법 중 하나는 classification을 통한 접근이 있습니다. 

입력 이미지를 아주 작은 단위로 쪼개고, 이 작은 영역만으로 classification문제를 푼다고 생각해보겠습니다. 이는 쪼개진 해당 영역이 어떤 카테고리에 속하는지를 결정하는 문제입니다.

 

이렇게 되면 이미지 한 장 전체를 분류하는 모델로 수많은 작은 영역을 분류하게 되기 때문에 계산 비용이 너무 커지게 되어 비효율적입니다. 그리고 영역을 나누더라고 어느 정도 겹치는 부분이 있기 마련이라 그렇게 좋은 방법은 아닙니다. 하지만 한 번쯤 생각해볼 수 있는 방법입니다.

 

다음 생각해볼 수 있는 방법으로는 위 그림과 같은 네트워크를 사용하는 것입니다. 

이 방법은 앞의 방법보다 개선된 방법입니다. ( 영역을 나누고 분류하는 것이 아닙니다)

 

FC가 없고 Conv로만 구성된 네트워크를 한 번 상상해 보겠습니다.

3x3 필터, zero-padding을 수행하는 layer를 쌓으면 이미지의 공간 정보를 손실하지 않을  것이고, 이 네트워크의 출력 tensor는 CxHxW가 될 것입니다.( C : 카테고리 수)

 

이 모델은 하이퍼파라미터 조절만 잘해준다면 작동은 잘합니다. 하지만 입력 이미지의 spatial size를 계속 유지시켜줘야 하기 때문에 계산 비용이 높아진다는 단점이 있습니다.

 

그래서 보통은 이렇게 생긴 네트워크를 이용해서 downsampling / upsampling을 진행 해줍니다.

 

이 네트워크는 spatial resolution 전체를 가지고 conv를 수행한다기보다 original resolution에서는 conv를 소량만 사용하고 max pool, stride conv 등으로 downsampling을 진행합니다. 그러고 난 후 spatial resolution을 다시 키워줍니다.(FC-layer가 없습니다.)

이러한 방법을 이용하면 계산 효율이 좋아져서 네트워크를 깊게 쌓을 수 있게 됩니다.

 

여기서 upsampling이라는 개념이 나오게 되는데 지금까지 downsampling은 많이 봤지만 upsampling은 처음이라 어떻게 하는지 잘 모를 수 있습니다. 

 

upsampling을 하는 방법은 여러 가지가 있는데 그중 unpooling이라 불리는 방법 중에 nearest neighbor이라는 방법과 bed of nails, max unpooling이라는 방법이 있습니다.

 

1. Nearest Neighbor : 2x2 stride nearest neighbor unpooling은 해당 receptive field로 값을 그냥 복사하는 방법입니다.

2. Bed of Nails : unpooling region에만 값을 복사하고 나머지는 전부 0으로 채우는 방법입니다.

 

3. max unpooling : unpooling과 pooling을 연관 짓는 방법입니다. downsampling을 진행할 때 max pooling에 사용했던 요소를 기억하고 upsampling시에 bed of nails와 유사한 방법으로 진행하지만 단지 같은 자리에 복사를 하는 것이 아니라 이전 max pooling 할 때 선택된 위치에 넣어주게 됩니다.

 

이 방법이 좋은 이유는 semantic은 모든 픽셀의 클래스 분류를 잘 해내야 합니다. 따라서 예측에서 객체 간의 디테일한 경계가 명확할수록 좋습니다. 하지만 maxpooling을 진행하면 비균진성이 발생하게 됩니다. 비균진성이란 어디서 값을 뽑아 왔는지 모른다는 뜻이고, 이 때문에 공간정보를 잃게 됩니다. 공간정보를 좀 더 잘 유지할 필요가 있기 때문에 max unpooling을 사용하게 됩니다.

 

위의 방법들은 고정된 함수이고 별도로 학습을 진행하진 않습니다.

하지만 stride convolution에선 어떤 식으로 downsampling을 해야 할지 네트워크가 학습을 할 수가 있었습니다.

이와 유사한 게 Transpose Convolution입니다. 이 방법은 upsampling을 진행할 때 어떤 식으로 할지 네트워크가 학습을 할 수 있습니다.

 

transpose conv 연산은 조금 다르게 생겼습니다. 여기선 내적을 수행하지 않습니다.

 

1. 우선 입력 특징 맵에서 값을 하나 선택합니다.(scalar)

 

2. 이 값을 필터와 곱합니다.(3x3)

 

3. 출력의 3x3영역에 그 값을 넣어줍니다.

  ▶Transpose Conv에서는 필터와 입력의 내적을 구하는 것이 아니라 입력값이 필터에 곱해지는 가중치의 역할을 합니다. 출력 값은 필터x입력(가중치)가 됩니다.

 

4. upsampling시에 입력에서 한 칸 움직이는 동안 출력에서 두 칸씩 움직입니다. 

 

이렇게 계산을 하다 보면 출력에서 Transpose Conv 간에 Receptive Field가 겹칠 수 있습니다. 겹치는 경우에는 그냥 겹친 부분을 더해줍니다.

위의 방법들을 반복 진행하게 되면 학습 가능한 upsampling을 수행한 것입니다. spatial size를 키워주기 위해 학습된 필터 가중치를 이용한 것입니다. 

이 방법은 다른 말로는 deconvolution, upconvolution, fractionally strided convolution, backward stride convolution이라고 부르기도 합니다.

 

다음으로는 Classification + Localization 문제에 대해 살펴보겠습니다.

 

Classification + Localization

우리가 이미지를 분류하다 보면 입력으로 들어온 이미지가 어떤 카테고리에 포함되는지 뿐만 아니라 실제 객체가 어디에 있는지를 알고 싶을 수 있습니다. classification + localization에서는 위 그림에서 객체가 고양이의 카테고리에 포함된다는 것뿐만 아니라 고양이가 어느 위치에 있는지 네모 박스를 그립니다.

 

이는 object detection이랑은 구별됩니다.  localization에서는 우리가 관심 있는 객체가 이미지에 오직 하나라고 가정하고 task를 진행하게 됩니다. 

 

localization문제를 풀 때도 기존 Image Classification에서 사용하던 기법들을 고스란히 녹일 수 있습니다. 

 

Architectual의 기본 구조는 위 그림과 같습니다. 네트워크가 이미지를 입력으로 받고 출력을 생성합니다. 출력 직전 FC-layer는 class score로 연결돼서 카테고리를 결정하게 됩니다.

하지만 또 하나의 FC-layer가 존재하게 되는데 이 FC-layer는 4개의 원소를 가진 vector와 연결되어 있습니다.(w, h, x, y로 bounding box의 위치를 나타냅니다.)

 

이런 식으로 두 개의 출력을 생성합니다. 하나는 class score이고 또 다른 하나는 객체 위치의 bounding box좌표가 됩니다. 

 

따라서 2개의 loss가 존재하게 되고 loss 함수도 2개가 존재합니다. 하나는 softmax함수로 class score 예측에 대한 loss함수입니다. 또 다른 하나는 Ground Truth Box와 예측한 bounding box사이의 차이를 측정하는 loss함수 입니다.

 

▶ 이렇게 구해진 두 개의 loss를 합해서 gradient를 계산하게 되는데 두 loss의 단위가 달라서 gradient 계산에 문제가 되지 않을까?

 

    ▷ 두 개의 loss를 합친 Loss를 Multi-task Loss라 합니다. 우선 미분을 구하려면 네트워크 가중치들의 각각의 미분 값을 계산해야 합니다. 실제로 이 두 loss의 가중치를 조절하는 하이퍼 파라미터가 있습니다. 두 loss의 가중합이 최종 Loss가 되고, 이 두 loss의 가중합에 대한 gradient를 계산하는 것입니다.

 

Human Pose Estimation

위 내용과 비슷하지만 활용이 조금 다른 task입니다. 바로 human pose estimation입니다. 

사람 이미지를 입력으로 받고 각 관절의 위치를 출력 값으로 해서 이 사람의 포즈를 예측합니다. 

일반적으로 사람의 관절 수는 같다는 아주 심플한 가정을 통해 진행하게 됩니다.

 

이번에는 출력에 bounding box의 좌표가 있는 게 아니라 각 관절의 좌표가 있습니다. 이렇게 예측된 14개의 점들에 대해서 regression loss를 계산하고 backprop 시켜서 학습을 진행하게 됩니다.

 

 

Object Detection

다음으로는 CV의 가장 중요한 task 중 하나인 object detection에 대해서 알아보겠습니다. 이에 대한 내용은 아주 방대하기 때문에 이번 강의에서는 object detection + deep learning에 관한 주요 아이디어만 간단하게 짚고 넘어가겠습니다.

 

우선 여기도 정해진 카테고리가 존재하게 됩니다. object detection task는 입력 이미지가 주어지면 이미지의 객체들의 bounding box(b-box)와 해당 category를 예측합니다. 여기서 localization과 약간 다른 점은 detection에서는 예측 b-box의 개수가 이미지에 따라 계속 달라진다는 점입니다.

 

detection문제를 풀기 위해 예전부터 사람들이 많이 시도했던 방법이 있습니다. 앞에서도 봤던 Sliding Window방법입니다. 

 

semantic segmentation에서 작은 영역으로 쪼갰던 아이디어와 비슷한 방법을 이용하여 다양한 영역을 나눠서 처리합니다. 하지만 이 전과 다른 점은 detection문제에서는 배경(background)에 대한 카테고리가 추가되어야 한다는 점입니다.

 

하지만 이 방법에는 문제가 있습니다. 바로 어떻게 영역을 추출할지가 큰 문제입니다.

object가 어디에 몇 개나 있을지, 사이즈는 얼마나 되는지, 어떤 종횡비로 표현해야 하는지를 모릅니다.

따라서 이런 brute force 방식의 sliding window를 하려면 너무 많은 경우의 수가 존재하게 되고, 때문에 detection에 brute force sliding window를 이용하는 일은 없습니다.

 

대신 Region Proposals라는 방법이 있습니다. 사실 이 방법은 딥러닝을 사용하지는 않고 전통적인 신호처리 기법을 사용합니다.

 

Region Proposals Network는 object가 있을법한 곳에 b-box를 제공해줍니다. 그리고 이미지 내의 뭉텅 진(blobby) 곳들을 찾아냅니다. 이 지역들은 객체가 있을지도 모르는 후보 영역들입니다.

 

Region Proposals를 만들어내는 방법에는 Selective Search가 있습니다. selective search는 2000개의 region proposals를 만들어 냅니다.

 

이러한 방법을 이용해서 만들어진 모델이 있습니다.  바로 R-CNN입니다.

R-CNN

RP(Region Proposal)을 이용하여 우리는 이제 무식하게 이미지 내의 모든 위치와 스케일을 고려하지 않아도 됩니다. 

 

우선 RPN(Region Proposal Network)를 적용하고 객체가 있을법한 RP를 얻어냅니다. 그리고 이 RP를 CNN의 입력으로 하는 것입니다.

이러한 방법은 계산량을 다루기 훨씬 수월합니다.

 

위 그림을 보면 이미지에서 RP를 추출합니다. (RP를 ROI(Region of Interest)라고도 합니다.) 하지만 각 ROI의 사이즈가 다르다는 점이 문제가 될 수 있습니다. 문제 해결을 위해 ROI를 FC-layer를 이용해 같은 사이즈로 바꿔주고 CNN의 입력으로 넣어주게 됩니다.

 

사이즈를 동일하게 바꿔준 ROI를 CNN의 입력으로 넣어주게 되고, 최종 Classification에 SVM을 사용해줍니다.

 

그뿐 아니라 RP를 보정하기 위한 regression과정도 거치게 됩니다. selective search의 RP가 대게는 정확하지만 그렇지 않은 경우도 있기 때문입니다.

 

결과적으로 R-CNN은 b-box카테고리도 예측하지만 b-box를 보정해줄 수 있는 offset값 4개도 예측합니다. 이들을 Multi-task loss로 두고 한 번에 학습을 진행합니다.

 

  • 그런데 왜 ROI는 사각형일까요?
    • 우리가 ROI의 크기를 조정해주는 과정을 거치는데 사각형이 아니라면 크기를 조절하기가 너무 까다롭기 때문입니다. 하지만 Instant Segmentation의 경우 ROI가 사각형이 아닌 경우도 있습니다.

하지만 R-CNN에도 문제는 존재합니다.

  1. 여전히 계산비용이 비쌉니다. 2000개의 Region Proposal이 있고 각각이 독립적으로 CNN에 들어가기 때문입니다.
  2. 학습 과정 자체가 굉장히 오래 걸립니다.
  3. Test time도 굉장히 느립니다.

이런 R-CNN의 문제를 해결하기 위해 만들어진 것이 Fast R-CNN입니다.

Fast R-CNN

Fast R-CNN은 앞의 문제들을 상당 부분 해결합니다.

 

Fast R-CNN은 R-CNN과 시작은 같습니다. 하지만 각 ROI마다 CNN을 수행하지 않습니다. 먼저 전체 이미지에 CNN을 수행하고, 그 결과로 전체 이미지에 대한 고해상도 Feature Map을 얻습니다.

 

Fast R-CNN은 여전히 selective search 같은 방법으로 RP를 계산합니다. 하지만 이제부턴 이미지에서 ROI를 뜯어내지 않습니다. 우린 CNN Feature Map에 ROI를 Projection 시키고 전체 이미지가 아닌 Feature Map에서 ROI를 뜯어옵니다. 이젠 CNN의 Feature를 여러 ROI가 서로 공유할 수 있습니다.

 

그다음 FC-layer가 존재합니다. FC-layer는 고정된 크기의 입력을 받기 때문에 Feature Map에서 뜯어온 ROI는 FC-layer의 입력에 알맞게 크기를 조정해 줘야 합니다. 이때 학습이 가능하도록 미분 가능한 방법을 사용하고 이 방법이 ROI pooling layer입니다.

 

ROI크기를 조정하고 나면 아래 그림과 같이 FC-layer의 입력으로 넣어서 Classification score와 linear Regression offset을 계산할 수 있게 됩니다. 학습 시에는 이 두 개의 loss를 합쳐 Multi-task loss로 학습을 진행합니다.

 

실제로 Fast R-CNN과 R-CNN의 test time에 대한 비교를 보면 엄청나게 빨라진 것을 볼 수 있습니다.

 

하지만 Fast R-CNN은 RP를 계산하는 부분에서 병목현상이 일어나게 됩니다.

 

Faster R-CNN

병목현상에 대한 문제를 해결하기 위해 만들어진 것이 Faster R-CNN입니다.

 

Faster R-CNN은 네트워크가 Region Proposals를 직접 만들 수 있습니다.

 

입력 이미지가 전체 네트워크로 들어가서 Feature Map을 생성하게 됩니다. 여기서 Faster R-CNN은 별도의 Region Proposals Network(RPN)이 있습니다. RPN을 이용해 feature map을 이용해서 RP를 계산하게 합니다. 이렇게 RP를 만들고 난 후에는 R-CNN과 동일한 과정을 진행합니다.

 

Faster R-CNN에서는 총 4개의 loss가 존재합니다.

  1. Region Proposals Network에 존재하는 loss
    1. 객체가 이 위치에 있는지 없는지에 대한 loss
    2. 예측 b-box에 대한 loss
  2. Faster R-CNN의 마지막 부분의 loss
    1. Fianl Classification Score
    2. b-box regression -> 앞서 만든 RP를 보정하는 역할

병목현상 해결로 인해 아주 빨라진 것을 볼 수 있습니다.

 

Instance Segmentation

마지막은 앞에서 배운 내용들의 종합 선물 세트라고 할 수 있는 Instance Segmentation입니다.

 

Instance Segmentation은 입력 이미지가 들어오고 객체별로 객체의 위치를 알아내는 것은 동일합니다. 하지만 객체별 b-box를 예측하는 것이 아니라 객체별 Segmentation Mask를 예측해야 합니다. 이는 이미지에서 각 객체에 해당하는 픽셀을 알아내는 문제입니다.

 

이 문제를 푸는 아주 다양한 방법이 있지만 그중에서 Mask R-CNN이라는 방법이 있습니다.

이는 Faster R-CNN과 비슷합니다. 우선 처음 이미지가 CNN과 RPN을 거칩니다. 여기까지는 Faster R-CNN과 유사합니다.

그리고 특징 맵에서 RPN의 ROI만큼을 뜯어 냅니다.

 

하지만 이다음으로 Faster R-CNN처럼 Classification, BBox Regression을 진행하는 것이 아니라 각 BBox마다 Segmentation Mask를 예측하도록 합니다. RPN으로 뽑은 ROI 영역 내에서 각각 semantic segmentation을 수행합니다.

 

feature map으로부터 ROI pooling(align)을 하면 두 갈래로 나뉩니다. 위쪽으로 가는 갈래는 Faster R-CNN과 비슷합니다. 그리고 하단의 두 번째 갈래는 Semantic Segmentation을 위한 미니 네트워크처럼 생겼습니다. 각 픽셀마다 객체인지 아닌지를 분류합니다. 

 

 

Summary

오늘 여러 가지 Computer Vision Task에 대해 배웠습니다. 그리고 Image Classification의 방법론들을 다른 Task에서 어떻게 활용할 수 있을지를 배웠습니다.

'AI > CS231N' 카테고리의 다른 글

Lecture 9 : CNN Architecture  (0) 2022.09.06
Lecture 10 : Recurrent Neural Networks  (1) 2022.09.06