2020. 6. 13. 21:27ㆍResearch
MobileNet(MobileNet V1)은 모바일 기기에서 서빙 가능한 가벼운 모델을 만들겠다는 동기로 진행된 연구이다.
MobileNet의 핵심은 연산량과 파라미터 수를 줄이는 역할을 하는 depthwise separable convolution이다. 사실 이것만 이해해도 MobileNet을 이해했다고 볼 수 있다.
Depthwise Separable Convolution
위의 그림이 depthwise separable convolution이며, depthwise convolution과 pointwise convolution이 연속적으로 이어진 형태이다. 이러한 형태의 convolution이 어떤 이점이 있는 지를 살펴보기 위해 일반적인 convolution, depthwise convolution, pointwise convolution 각각을 살펴볼 필요가 있다[2].
1. 일반적인 Convolution 연산
위의 그림은 일반적인 convolution 연산의 모습이다. 필터 크기는 $K \times K$이고 이미지의 높이 너비는 $F$, 입력 채널 수는 $N$, 출력 채널 수(= 필터 수)는 $M$이다. 이 경우 총 연산량은 $F^2 * K^2 * N * M$이다.
2. Depthwise convolution (공간 방향의 convolution)
Depthwise convolution은 입력 feature map의 각 채널마다 각기 다른 커널을 사용한다. 채널마다 다른 필터가 적용되기 때문에 출력 채널의 수는 입력 채널의 수와 동일하다. (∵ 필터 수 = 출력 채널 수)
총 연산량을 계산해보면 $F^2 * K^2 * N$이다. (일반적인 convolution보다 연산량이 적어지는 이유는 채널 axis로 연산이 이루어지지 않기 때문이다.)
3. Pointwise convolution (= 1x1 convolution) (채널 방향의 convolution)
1x1 conv는 GoogLeNet 포스팅에서 다루었듯이 연산량을 줄이는데 효과적이며, 필터 수를 줄여서 차원 축소를 할 수 있다고 하였다. pointwise convolution에서는 depthwise convolution과 반대로 채널 방향으로 연산을 수행하고, 공간 방향으로는 연산을 하지 않는다. 총 연산량을 계산하면 $F^2 * 1^2 * N * M$이 나온다.
4. Depthwise Separable Convolution (채널 방향 + 공간 방향)
일반적인 convolution에서는 채널 방향과 공간 방향의 convolution을 동시에 수행한다. 반면, depthwise separable convolution은 공간 방향의 depthwise convolution과 채널 방향의 pointwise convolution을 따로 수행하여 합치는 방식이다. 아래 표를 보면 각 op의 연산량이 정리되어 있는데 기본 conv와 depthwise separable conv의 연산량 비율은 $K^2 * M : K^2 + M$이다. 만약 커널 사이즈 $K =2$, 입력 채널 수 $M = 64$로 잡는다면, 무려 18배의 연산량 차이가 난다.
기본적인 Convolution | $F^2 * K^2 * N * M$ |
Depthwise Convolution | $F^2 * K^2 * N$ |
Pointwise Convolution | $F^2 * 1^2 * N * M$ |
Depthwise Separable Convolution | $(F^2 * K^2 * N) + (F^2 * 1^2 * N * M)$ |
MobileNet에서는 아래 그림의 오른쪽과 같이 (3x3 Depthwise Conv + BN + ReLU) + (1x1 Conv + BN + ReLU) 형태로 depthwise separable convolution layer를 구성하였다. (왼쪽은 일반적인 Conv + BN + ReLU 조합의 모습이다.)
MobileNet 구조
위의 표는 MobileNet의 전체 아키텍쳐를 보여준다. "Conv dw"은 depthwise separable convolution을 의미하며, "s1"은 stride = 1, "s2"는 stride = 2를 의미한다. 위의 구조에서 눈에 띄는 점은 pooling layer를 따로 사용하지 않다는 점인데, pooling 대신에 convolution의 stride를 2로 잡아서 차원 축소 및 정규화의 효과를 낸다.
Reference
[1] https://mc.ai/review-xception-with-depthwise-separable-convolution-better-than-inception-v3-image/
[2] https://www.slideshare.net/ssuser06e0c5/convolution-77257148