참고자료
Neural Network를 이용하여 이미지를 처리하는 것을 다음과 같이 분류 할 수 있다.
1) Image Classification : 사진의 이미지 객체가 어떤 것인지 구분하는 것(사진 속의 이미지가 고양이인지 강아지인지를 구분)
2) Image Localization : 사진 속 특정 단일 객체에 box를 쳐서 객체가 어디있는지 표시(detection과 구분)
3) Object Detection : 사진 속 여러 객체를 각각 구별하여 각각을 box로 표시
4) Image Segmentation : 사진 속 객체를 box가 아닌 정확한 영역으로 표시 (object detection 보다 세부적). 특정 객체만 표시하는 것이 아니라 이미지 pixel전체에 걸쳐서 객체를 구분하여 각 객체의 영역을 표시.
단순히 이미지를 분류(Classification)하는 것에서 발전하여 입력이미지에서 단일, 또는 다수 객체의 위치와 어떤 클래스를 가지는지를 구별한다. => 이미지 분할
여러 층의 Convolution Layer들을 거치고 나면 특성 맵(feature map) 의 크기가 H/32 W/32 로 줄어드는데 그 특성맵의 한 pixel이 입력 이미지의 32 32 크기를 대표한다. 즉 입력 이미지의 위치 정보를 대략적으로 가지고 있게 된다.
여기서 중요한 것은 이 Convolution Layer들을 거치고 나서 얻게 된 마지막 특성맵의 갯수는 훈련된 클래스의 갯수와 동일하다는 것이다. 21개의 클래스로 훈련된 네트워크라면 21개의 특성맵을 산출해낸다. 각 특성맵은 하나의 클래스를 대표한다. 만약 고양이 클래스에 대한 특성맵이라면 고양이가 있는 위치의 픽셀값들이 높고 강아지 클래스에 대한 특성맵이라면 강아지 위치의 픽셀값들이 높다.
이 대략적인 특성맵들의 크기를 원래 이미지의 크기로 다시 복원해줄 필요가 있다. 이미지의 모든 픽셀에 대해서 클래스를 예측하는 dense prediction을 해 주는 것이 Image Segmentation의 목적이기 때문이다. 이 원래 이미지로 복원하는 과정을 Upsampling이라고 부른다. Upsampling을 통해서 각 클래스에 해당하는 대략적인 특성맵들을 원래 사이즈로 크기를 키워준다. Upsampling된 특성맵들을 종합해서 최종적인 segmentation map을 만들게 된다.
간단히 말해서 각 픽셀당 확률이 가장 높은 클래스를 선정해주는 것이다. 만약 (1,1) 픽셀에 해당하는 클래스당 확률값들이 강아지 0.45, 고양이 0.94, 나무 0.02, 컴퓨터 0.05, 호랑이 0.21 이런 식이라면 0.94로 가장 높은 확률을 산출한 구양이 클래스를 (1,1) 픽셀의 클래스로 예측하는 것이다. 이런 식으로 모든 픽셀이 어느 클레스에 속하는지 판단한다.
그런데 단순히 upsampling만 시행하면 특성맵의 크기는 원래 이미지 크기로 복원되고, 그것들로부터 원래 이미지 크기의 segmentation map을 얻게 되지만 여전히 대략적인 즉 디테일하지 못한 segmentation map을 얻게 된다. 1/32 만큼 줄어든 특성맵들을 단숨에 32배만큼 upsampling을 했기 때문에 당연히 대략적일 수 밖에 없다. 이렇게 단숨에 32배 upsampling하는 방법을 논문에서는 FCN-32s라고 소개하고 있다.
아래 그림을 보자. 실제 상황과 비교해서 FCN-32로 얻은 segmentation map은 많이 뭉뚱그려져 있고 디테일하지 못함을 알 수 있다.
FCN의 개발자들은 좀 더 디테일한 segmentation map을 얻기 위해 skip combining 이라는 기법을 제안한다. 기본적인 생각은 다음과 같은데, convolution과 pooling 단계로 이루어진 이전 단계의 convolution layer들의 특성맵을 참고하여 upsampling을 해주면 좀 더 정확도를 높일 수 있지 않겠냐는 것이다. 왜냐하면 이전 convolution layer들의 특성맵들이 해상도 면에서는 더 낫기 때문이다. 이렇게 바로 전 convolution layer들의 특성맵과 현재 층의 특성맵을 2배 upsampling한 것을 더한다. 그 다음 그것을 16배 upsampling으로 얻은 특성맵들로 segmentation map을 얻는 방법을 FCN-16s라고 부른다. 아래 그림을 참고하자.
그림에서 pool1은 (H/2, W/2), pool2는 (H/4, W/4), pool3, pool4, pool5는 각각 (H/8, W/8), (H/16, W/16), (H/32, W/32) 크기의 특성맵에 해당된다.
pool5의 결과인 conv7을 그대로 32배(32* 32) 확대시킨 것이 FCN-32s이고 가장 성능이 안좋다. 다음 conv7의 특성맵을 2배 확대(upsampling)시키고(H/16, W/16) 여기에 직전 convolution layer 특성맵인 pool4(H/16, W/16)를 더해준 다음 그것을 16배 확대(upsampling)시킨 것이 FCN-16s라고 부른다.
그 다음 FCN-16s의 결과를 다시 2배 upsampling해서(H/8, W/8)해서 직전의 직전맵인 pool3(H/8, W/8)를 더해주고 그것을 8배 확대(upsampling)시킨 것을 FCN-8s라고 부른다.
당연히 성능은 FCN-8s > FCN-16s > FCN-32s의 순으로 좋다.
지금까지 살펴본 모델인 FCN은 추상화된 정보를 다시 원래 이미지의 segmentation으로 풀어나갈때 별도의 복잡한 수학적 계산이 들어가 있지는 않다. 그러나 다른 대부분의 Image Segmentation 모델에서는 별도의 수학적인 연산들을 이용하여 결과를 내게 되는데 이러한 구조를 다른 말로 Encoder-Decoder 구조라고도 하며 아래 그림에서 확인할 수 있다.
<up-sampling(디코딩) 부분>
u자에서 제일 아래부터 시작
1번째 출력 필터 (2 x 2)로 up-Conv (다운샘플링의 crop된 데이터 합침)
+crop 데이터 사용 이유 : convolution을 통해 정보가 날아간 부분을 보정
2번째 출력 필터(3 x 3)로 Conv (필터 수 512 x 256개 필요) -- 패딩x
3번째 출력 필터(3 x 3)로 Conv (필터 수 256 x 256개 필요) -- 패딩x
... ( 반복 ) ...
요약하면
1. Unet은 인코딩(down-sampling)과 디코딩(upsampling)으로 구성
2. 인코딩은 일반적인 CNN처럼 convolution과 pooling으로 데이터를 요약한다.
3. 디코딩은 up-convolution과 pooling을 통해 데이터를 복구한다.
4.PSPNet(Pyramid Scene Parsing Network) : PSPNet은 이미지의 전체적인 문맥(전역 정보)를 더 잘 학습하기 위해 최적화된 모델이다. 먼저 이미지는 기반 모델로 입력되어 feature map을 얻게 되며 이는 여러가지 서로 다른 scale로 downsampling된다. 그후 convolution 작업을 거친 feature map들은 다시 같은 크기로 upsampling된 후 합쳐지게 된다. 마지막으로 또 다른 convolution 층을 통해서 최종 image segmentation 결과를 산출해 낸다. 여기서 서로 다른 크기의 특성 맵들을 통해서 다양한 크기의 개체들을 더욱 잘 분석해 낼 수 있게 된다.
[정리]