본문 바로가기

Deep Learning(강의 및 책)/CS231

Lecture 11. Detection and Segmentation

728x90

이번 강의는 computer vision task에 대해서 다룹니다. segmentation, localization, detection 등 다양한 CV task와 이 문제점들을 CNN으로 어떻게 접근해 볼 수 있을지에 대해 다룹니다.

 

이번 강의에서 다룰 CV task를 위에서 볼 수 있습니다. semantic segmantation, classification + localization, object detection, instance segmentation이 있습니다.

 

 

먼저 semantic segmentation을 보겠습니다. input으로 image가 들어가고 output은 이미지의 모든 픽셀을 카테고리에 맞춰 분류된 모습입니다. 모든 픽셀에 대해 그 픽셀이 잔디, 고양이, 하늘, 나무, 배경인지를 결정하는 방식이라 볼 수 있습니다. 결국 이 방식은 classification처럼 class category가 존재해야 합니다. 

 

개별 객체를 구분하지는 않습니다. 픽셀의 카테고리만 구분해주기 때문에 소 두 마리를 구별하지는 않습니다. 오직 소라고 label된 픽셀 덩어리만 output으로 출력합니다.

 

semantic segmentation을 위해서 sliding window라는 아이디어를 생각해 볼 수 있습니다. input image를 아주 작은 단위로 쪼개는 방식인데 위 예제에서는 암소의 머리 주변에서 영역 세 개를 추출했습니다. 그리고 이 작은 영역만을 가지고 classification 문제를 푸는 방식입니다. 이러한 방식은 매우 비효율적이기 때문에 좋은 아이디어는 아닙니다. 모든 pixel에 대해서 작은 영역으로 쪼개고 forward/backward pass를 진행하는 것은 매우 비효율적이고 서로 다른 영역이라도 인접해있으면 어느 정도 겹쳐있기 때문에 feature들을 공유할 수 있는데 이 방식은 그러지 못합니다. 그래서 안 좋은 방식이지만 가장 먼저 생각할 수 있는 방식입니다.

 

그래서 새로 등장한 방식입니다. 이미지 영역을 나누고 독립적으로 분류하는 방법이 아닙니다. 전체 input image를 CNN연산하는 방식입니다. zero padding 등을 이용해 input image의 크기 손실을 일으키지 않고 CNN을 진행합니다. 위 예시에서 C는 category의 수가 되고 output tensor는 input image의 모든 픽셀 값에 대해 classification score를 매긴 값이 됩니다. 이 네트워크를 학습시키려면 모든 pixel의 classification loss를 계산하고 평균값을 취한 후 기존 backprop을 수행하면 됩니다.

이 모델은 parameter만 잘 학습된다면 좋은 model이 될 수 있는데 문제가 있습니다. input image의 spatial size를 계속 유지시키는 방식인데 비용이 아주 많이 듭니다. 고해상도의 image가 들어온다면 계산량과 메모리가 엄청 커서 감당할 수 없습니다.

 

 그래서 이런 문제를 해결하기 위해 feature map을 down/up sampling을 합니다. max pooling, stride 등을 이용해 feature map을 down sampling 합니다. 이 네트워크는 FC-layer가 없고 up sampling을 통해 마지막에 spatial resolution을 다시 키웁니다. 결국 input image와 동일한 크기가 됩니다. 이 방법을 사용하면 계산 효율이 좋아집니다. 이렇게 network가 lower resolution을 처리하도록 하여 network를 더 깊게 만들 수 있습니다.

 

network에서 upsampling하는 방식들에 대해 설명합니다. 먼저 nerarest neighbor 방식이 있는데 이는 그냥 값을 복사하는 방식입니다. bed of nails은 unpooling region에만 값을 복사하고 다른 곳에는 0을 채워 넣는 방식입니다.

 

이번에는 max unpooling입니다. bed of nails와 유사하지만 같은 자리에 값을 넣는 것이 아닌 가장 큰 값이 있던 위치에  값을 넣는 방식입니다. 이 방식이 더 좋은 성능을 보이는데 feature map의 공간정보를 잃지 않고 좀 더 디테일하게 다룰 수 있기 때문입니다. 그리고 가장 큰 값이 있던 위치를 기억하는 것은 그렇게 큰 비용이 드는 작업은 아니기 때문에 좋은 성능을 보입니다.

 

이번에는 transpose convolution이 등장합니다. 이도 upsampling하는 방식 중 하나로 이전까지는 나온 방법은 고정된 함수이고 별도로 학습되지 않습니다. 하지만 transpose convolution은 feature map을 upsampling 할 때 어떻게 할지를 학습합니다. input에 위치한 값과 weight filter를 그냥 곱합니다. 그리고 해당 위치에 값을 저장합니다. Convolution과 같이 stride도 사용됩니다. 이런 transpose convolution은 filter가 겹치는 부분이 나오는데 이 경우 간단하게 두 값을 더하면 됩니다. 예를 들어 input * W1 + input * W2와 같이 그냥 더해주면 됩니다. 이렇게 transpose convolution라는 feature map 크기를 늘리는, upsampling 하는 방법이 있는데 deconvolution, upconvolution, fractionally strided convolution이라고 불리기도 합니다.

 

input image를 down sampling, up sampling을 통해 학습할 수 있습니다.

 

이번에는 classification + localization입니다. 실제 이미지가 어떤 카테고리에 속하지는, 실제 객체가 어디에 있는지에 대한 정보를 얻는 방법입니다. 실제로 이미지를 고양이로 분류하는 것 뿐만 아니라 고양이의 위치를 네모 박스로 그리는 방식입니다. 이는 object detection과는 다릅니다. localization은 이미지 내에서 내가 관심 있는 객체가 하나라고 가정을 하고 진행하는 방식입니다. 그래서 input image에서 객체 하나만 찾아서 label을 매기고 위치를 찾아냅니다.

 

image를 input으로 받고 output layer 직전에 FC-layer가 2개 있습니다. 첫 FC-layer는 class score로 연결되서 카테고리를 결정합니다. 그래서 loss도 softmax를 쓰면 됩니다. 다른 FC-layer는 원소 4개를 가진 vector와 연결되어 있습니다. 이 4개의 출력 값은 width/hieght/x/y 처럼 bounding box의 위치를 나타냅니다. 그래서 loss는 L1, L2, smooth L1 등과 같은 regression loss를 사용하면 됩니다. 그래서 loss는 두 가지가 존재합니다. 이 두 loss를 합친 loss를 multi-task loss라 합니다. 이 서로 다른 두 loss를 잘 더해서 사용하기 위해선 hyperparameter가 필요합니다. 사실 적절한 hyperparameter를 사용한다면 좋은 성능을 보이지만 그 값을 찾는 것은 쉽지 않습니다. 그래서 일반적으로 loss로 결과를 비교하지 않고 새로운 지표를 도입해 평가를 합니다. 이 평가를 통해 적절한 hyperparameter를 찾아갑니다. 또 하나의 좋은 방법은 network를 고정하고 FC-layer만 학습을 진행합니다. 그러고 수렴하게 되면 그때 전체 network를 fine-tune 하는 방법도 있습니다.

 

이번에는 사람의 pose를 평가하는 model입니다. input은 사람 image가 들어갑고 output은 각 관절에 해당하는 14개의 좌표 값이 나옵니다. 예측된 14개의 점에 대해서 regression loss를 계산하고 backprop을 해 학습시킵니다. 가장 간단하게 L2 loss를 사용하기도 합니다.

 

이번에는 object detection입니다. 이 object detection도 classification과 같이 고정된 category가 존재합니다. 예를 들어 고양이, 개, 나무 등이 있습니다. 하지만 object detection은 classification + location과는 다르게 input image가 주어지면 image에 나타나는 객체들만큼 box를 생성하고 category를 분류합니다.

 

이러한 object detection은 image에 존재하는 객체의 수에 따라 output의 수가 달라집니다. 각 객체의 좌표를 출력해야 하므로 output이 달라집니다.

 

 object detection에서 regression문제를 풀기는 쉽지 않습니다. 그래서 사람들이 시도하던 방식은 sliding window입니다. sliding window를 이용하면 input image로부터 다양한 영역을 나눠서 처리할 수 있습니다. 가령 이미지의 왼쪽 밑에서 작은 영역을 추출해 그 영역만 CNN에 input으로 넣습니다. 그 결과 CNN은 작은 영역에 대해서 classification을 수행합니다. 위 예시를 보면 category가 개, 고양이가 있는데 여기에 background도 추가를 해줍니다. 이는 아무런 category에 속하지 않는다는 것을 의미합니다. 이러한 방식의 sliding window는 문제가 있습니다. 영역을 어떻게 추출할지가 문제가 됩니다. 이미지에 object가 몇 개가 존재할지, 어디에 존재할지를 알 수 없고 그 객체의 크기도 알 수 없는데 이렇게 brute force 하게 sliding window를 하는 것은 너무나 많은 경우의 수가 존재하고 연산량도 너무 커집니다.

 

그래서 sliding window 대신에 region proposal이라는 방식이 등장합니다. 이 방식은 deep learning을 사용하지 않습니다. region proposal network는 전통적인 신호처리 기법인데 object가 있을 법한, 가령 1000개의 box를 제공합니다. 이미지 내에서 객체가 있을 법한 후보 region proposal을 찾아내는 다양한 방법이 있지만 region proposal network는 이미지 내에 뭉텅진(blobby) 곳들을 찾아냅니다. 이 방식은 비교적 빠르게 동작합니다. 이렇게 객체가 있을 법한 region proposal들을 CNN의 input으로 넣어주면 계산량을 다루기 훨씬 쉽고 연산량이 줄어듭니다.

 

이제 R-CNN이 등장합니다. input image가 주어지면 region proposal을 얻기 위해 region proposal network를 진행합니다. region proposal은 region of interest(ROI)라 불립니다. region proposal network 중 selective search 방식을 이용해 2000개의 ROI를 얻습니다. 이렇게 얻은 ROI의 사이즈들은 각양각색입니다. 이 ROI들이 CNN으로 들어간다면 classification을 위해 FC-Layer에 들어가는데 이때 사이즈가 다르면 문제가 생깁니다. 그래서 동일한 크기로 변형시켜야 합니다. 그래서 warped image region을 통해서 ROI를 동일한 크기로 변형시키고 CNN에 넣어줍니다.

그렇게 나온 결과를 classification을 하는데 이 경우 SVM을 이용합니다. R-CNN은 region proposal의 보정을 위해 regression을 거칩니다. selective search의 region proposal이 대게는 정확하지만 그렇지 못한 경우도 있기 때문에 R-CNN은 box의 category도 예측을 하고 box를 보정할 수 있는 offset 값 4개도 예측해 이 두 loss를 multi task loss로 두고 한 번에 학습합니다. 그렇다고 R-CNN이 region proposal을 학습하는 것은 아닙니다. selective search를 씁니다. 이러한 R-CNN을 학습하기 위해서는 label된, box처리된 data들이 필요합니다.

 

 

R-CNN은 많은 문제가 있습니다. 계산 비용이 높습니다. R-CNN은 2000개의 region proposal이 있고 각각 독립적으로 CNN의 input으로 들어갑니다. 그리고 region proposal은 학습되지 않으며 이가 나중에는 문제가 될 수 있습니다. 그리고 R-CNN는 학습 자체가 오래걸립니다. CNN에서 나온 feature를 디스크에 덤핑 시키는데 용량이 매우 큽니다. 논문에선 전체 학습 시간이 81시간이라고 합니다. 각 region proposal 마다 CNN을 수행해야 하므로 수천번의 forward pass가 요구됩니다.

 

그래서 Fast R-CNN이 등장합니다. Fast R-CNN은 각 ROI마다 CNN을 수행하지 않습니다. 전체 이미지에 CNN을 수행합니다. 그 결과 전체 이미지에 대한 고해상도 feature map을 얻을 수 있습니다. fast RCNN에는 여전히 selective search와 같은 방법으로 region proposal을 계산합니다. CNN feature map에 ROI를 projection 시키고 전체 이미지가 아닌 feature map에서 뜯어옵니다. 이렇게 되면 CNN의 feature를 여러 ROI가 공유할 수 있습니다. 이전에는 ROI마다 CNN을 진행해 서로 feature map이 독립적으로 존재했습니다. 이제 사이즈를 맞춰 FC-layer에 들어갑니다. 사이즈를 맞춰주는 부분이 "ROI pooling layer"입니다. FC-layer을 거쳐 classification score와 linear regression offset을 계산할 수 있습니다. Loss 또한 합쳐 multi task loss로 backprop을 진행합니다. ROI Pooling은 max pooling과 방법이 유사합니다.

 

Fast R-CNN을 통해 속도가 상당히 향상된 모습을 볼 수 있습니다. 하지만 이런 Fast R-CNN은 여전히 문제가 있습니다. 2000개의 region proposal을 selective search 방식으로 계산하는데 2초가량 걸립니다. 만약 region proposal을 거친 후 CNN연산을 하는 경우면 모든 region proposal이 공유되기 때문에 CNN 연산만 진행하면 되는데 이는 1초도 안 걸립니다. 하지만 Fast R-CNN은 CNN을 한 후 region proposal을 뽑아내기 때문에 시간차가 존재하고 병목현상이 일어나게 됩니다.

 

Faster R-CNN은 병목문제를 해결하기 위해 등정합니다. network가 직접 region proposal을 만들 수 있도록 합니다. input image 전체가 network로 들어가서 feature map을 만들고 별도로 존재하는 region proposal network로 들어갑니다. region proposal network는 feature map을 가지고 region proposal을 만듭니다. 만들어진 region proposal을 이용해 그다음은 Fast R-CNN과 동일합니다. Faster R-CNN은 4개의 loss를 한 번에 학습합니다. 이 loss들의 균형을 맞추는 것을 까다롭습니다. 일단 region proposal network에 2개의 loss가 있습니다. 하나는 이곳에 객체가 있는지 없는지를 예측하는 loss, 그리고 나머지 loss는 예측한 box에 관한 것입니다. 그리고 최종 output에서도 loss가 있는데 하나는 region proposal에 대한 classification을 하는 것, 나머지 하나는 box regression입니다. 앞서 만든 region proposal을 보정해주는 역할을 합니다. region proposal network에 ground truth 없이도 학습이 가능한 이유가 있습니다. ground truth object와 일정 threshold 이상 겹치는 proposal이 있을 것인데 이런 region proposal에는 positive라 예측을 하고 아닌 region proposal은 negative로 예측을 한다면 ground truth 없이도 학습이 가능합니다.

 

Faster R-CNN을 사용한 결과 속도가 향상된 것을 볼 수 있습니다. 즉 model에 region proposal network를 포함해 병목현상이 줄어든 것을 볼 수 있습니다.

 

이번에는 object detection중 다른 방법입니다. feed forward를 오직 한 방향으로 수행하는 network들입니다. YOLO와 SSD 둘 다 feed forward를 오직 한 방향으로만 수행합니다. 각 task를 따로 계산하지 말고 하나의 regression 문제로 풀어나갑니다. 거대한 CNN을 통과하면 모든 것을 담은 예측 값이 한 번에 나옵니다. input image가 있으면 image를 큼지막하게 나눕니다. 가령 7x7 grid만큼 나눕니다. 각 grid cell 내부에는 base box가 존재합니다. 위 경우 base box가 세 가지가 있습니다(가로로 긴, 세로로 긴, 정사각형). 실제로는 세 개 이상 사용합니다. 이제 이 grid cell에 대해서 box가 있고 이를 기반으로 예측을 수행합니다. box의 offset을 예측할 수 있습니다. 실제 위치가 되기 위해서 base box를 얼마큼 옮겨야 하는지 학습하면 됩니다. 그리고 각 box에 대해서 classification score를 계산합니다. 그 box안에 객체가 있을 점수입니다. 네트워크에 input image가 들어오면 7x7 grid마다 (5B + C) 개의 tensor를 갖습니다. 여기서 B는 base box의 offset(4개)과 confidence score(1개)로 구성됩니다. 그리고 C는 C개의 카테고리에 대한 classification score입니다.

 

마지막 Instance segmentation입니다. input image가 주어지면 객체 별로 객체의 위치를 알아냅니다. object detection문제와 유사힙니다. 하지만 객체별로 box를 예측하는 것이 아니라 객체 별 segmentation mask를 예측해야 합니다. 이미지에서 각 객체에 해당하는 픽셀을 예측하는 문제입니다. instance segmentation은 semantic segmentation과 object dectection을 합친 모습입니다.

 

 

mask R-CNN이 등장합니다. mask R-CNN은 여러 stage를 거칩니다. mask R-CNN은 input image가 CNN과 region proposal network를 거칩니다. 여기까지는 Faster R-CNN과 유사합니다. 그리고 Fast/Faster R-CNN에서 했던 것처럼 feature map에서 ROI만큼 뜯어냅니다. 그다음 classification/box regression 하는 것이 아니라 각 box마다 segmentation mask를 예측하도록 합니다. feature map으로부터 ROI pooling을 수행하면 두 갈래로 나눠집니다. 첫 갈래는 region proposal이 어떤 category에 속하는지를 계산합니다. 그리고 region proposal의 좌표를 보정해주는 box regression도 예측합니다. 두 번째 갈래는 semantic segmentation을 위한 mini network처럼 생겼습니다. 각 픽셀마다 객체인지 아닌지를 분류합니다. mask R-CNN은 오늘 배운 모든 방법을 전부 합친 모양입니다.