본문 바로가기

데이터 다루기/신경망

[신경망] 18. Deconvolution

728x90
반응형

안녕하세요, 이번 포스팅에서는 Deconvolution에 대해서 배워보도록 하겠습니다.

우선 Deconvolution이 무엇이기를 알기 전에, 어떠한 목적을 가지고 탄생되었는지를 알아야 합니다.

그러기 위해서는 Image Segmentation을 알아야합니다.

Image Segmentation을 통역하면 말 그대로, 이미즈를 분할하는 것입니다.

기존의 CNN은 고양이 사진을 넣으면 그저 고양이를 나타내는 하나의 클래스가 결과값으로 나옵니다.

위의 그림을 보면, 사실 고양이 사진에는, 하늘, 나무들, 초원도 있습니다. 하지만 우리의 관심사는 고양이이기 때문에 고양이만 예측값이 되어 나옵니다. 만약 우리가 한 이미지에서 존재하는 모든 정보를 알고 싶다면 어떻게야 할까요?

이러한 목적을 Image Segmentation이라고 부릅니다.

기존의 CNN은 분류 목적이 강하기 때문에, 하나의 Class만을 추출할 수 있습니다.

그래서 제기된 첫번째 아이디어가 window를 사용하여 모든 픽셀에 대해서 하나씩 차근차근 예측하는것입니다.

예를 들어서, 위의 그림처럼 사각형 윈도우로 그림을 픽셀 하나를 중심으로 가지도록 한칸씩 이동시킵니다. 그리고 윈도우의 중심이 소 위에 있으면, Cow로 예측, 그리고 초원 위에 있으면 Grass로 예측이 됩니다.

하지만 이러한 방법에는 큰 한계점이 있습니다. 얼핏 짐작해보아도, Computational cost가 엄청 크겠죠?? 예를 들어서, 소 위에서 한칸을 움직일 때, 사실상 이미지는 중복된 부분이 굉장히 많지만, 독립적으로 전부 다시 학습해야하기 때문에, 시간이 굉장히 오래 걸릴것입니다.

그래서 "픽셀 하나하나씩 따로 예측하는 것은 시간낭비다" 라고 해서 나온 아이디어는 각각 픽셀들을 한 번에 예측하는 것입니다.

이 아이디어의 특징은, Convolution network를 통과할 때, padding 으로 Input 사이즈를 계속 유지시킵니다. 그리고 마지막에, FC layer를 걸치지 않고, CxHxW Feature맵으로 각각의 픽셀별로 바로 예측합니다.

물론 이 방법에도 큰 문제가 존재합니다. Convolution network를 input 사이즈를 유지하면서 계속 통과시키다보면, 필요한 parameter의 수가 기하급수적으로 늘어나게 되며, memory 과부하 및 computational cost가 커지는 문제점이 발생합니다.

그래서 나온 아이디어가 Deconvolution 입니다. 모든 픽셀들을 한번에 예측하되, 사이즈를 안줄이면 문제점이 존재하므로, 줄였다가 다시 복원시키면 어떨까? 하는 아이디어를 현실화한 것입니다.

쉽게 말해서, 기존의 CNN과 비슷하게 Feature map 사이즈를 줄이고, 나온 결과를 FC layer에 넣는 대신 Deconvolution을 통해 원본 input 사이즈로 복원합니다. 이 때, 앞서서 축소시키는 과정과 대칭이 되게 하는 것이 좋습니다.

Deconvolution을 upsampling이라고 부르기도 합니다.

이제 upsampling의 자세한 과정을 살펴봅시다.

upsampling에는 2가지가 있습니다.

pooling layer를 복원하는 것과, Convolution layer의 stride에 의한 축소를 복원하는 것입니다.

첫번째로, pooling layer를 복원하는 방법은 3가지가 있습니다.

1. Nearest Neighbor Unpooling

Nearest Neighbor Unpooling는 가장 간단한 방법입니다. 2x2를 4x4로 복원 시킬 때, 같은 값으로 복제하는 것 입니다.

2. Bed of Nails Unpooling

Bed of Nails Unpooling는 정해진 위치에만 값을 저장하고, 나머지는 0으로 만드는 방법입니다.

위의 경우에는 왼쪽 위에 값을 저장하고 나머지를 0으로 만들었네요.

3. Max Unpooling

Max Unpooling에서는 앞선 Max Pooling layer에 대하여, max pooling 된 위치를 기억하고, 그 위치에 값을 복원합니다.

이 방법은 Bed of Nails Unpooling에 비해서 정보 손실을 방지할 수 있습니다. 물론, 별도의 메모리를 필요로하지만, CNN에서 매우 작은 비율이므로 아무런 상관이 없다고 합니다.

다음으로 Pooling layer가 아닌 Convolution layer에서 stride로 인해 발생하는 사이즈 축소에 대한 복원입니다.

1. Transpose Convolution

Transpose Convolution 은 행렬을 이용한 방법입니다.

padding = 0, stride = 1 로 3x3 kernel을 4x4 input에 적용시킬 때, 행렬로 나타내면 다음과 같습니다.

3x3 Kernel을 4x16 행렬로 바꾸고, input을 16x1행렬로 분해하고, 2x2 output 을 4x1로 분해하여 계산합니다.

Transpose Convolution은 4x16 행렬을 Transpose해서 Input feature map을 output으로 출력합니다.

최종적으로 Convolution layer 와 Pooling layer로 축소된 이미지가, upsampling 과정을 걸쳐서 원본 이미지의 사이즈와 같게 복원이 되고, 이 출력값으로, 모든 픽셀에 대하여 classification을 진행합니다.

앞선 아이디어에서 제시된 방법에서의 문제점이 다소 해결되는 것을 아실 수 있습니다. (Memory 문제 감소, Computational cost 감소)

반응형