아는 만큼 보인다

[논문 읽기] MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications 2017 이해하기 본문

머신러닝&딥러닝

[논문 읽기] MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications 2017 이해하기

계토 2023. 11. 5. 19:49

이번 POC에서 생각보다 퍼포먼스가 좋았던 MobileNet 시작! 그냥 비교용으로 구축해봤을 뿐인데 생각보다 잘해서 좀 놀라웠다.

MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications [Link]

 

MobileNet이 해결하고자 하는 문제, MobileNet의 동기

딥러닝 모델 분야에서는 일반적으로 더 깊고 복잡한 네트워크를 이용해 더 높은 정확도를 얻고자 한다. 그러나 이러한 방향은, 모델 크기나 속도를 고려했을 때 모델을 항상 더 '효율적(efficient)'으로 만들어주진 않는다. 그러나 실제 real-world application을 고려하면, 높은 정확도를 '빠르게', '작은 모델로' 달성하는 것이 중요하다. 

 

이러한 동기로, 모바일이나 임베디드 환경 등 리소스가 제한된 환경에서의 적용을 고려한 '효율적' 모델, MobileNet이 제안되었다. '속도'와 '크기' 모두를 고려했다고 소개되어 있다. 

 

MobileNet 핵심 구조 - Depthwise separable convolution

MobileNet은 'depthwise separable convolution'에 기반한 모델이다. 이는 일반적인 convolution layer를 2개의 단계-depthwise convolution과1x1 pointwise convolution-로 분리한 layer이다. 이게 무엇인지 이해하기 위해 일반적인 convolution layer와 비교해보자. 참고로 아래 그림의 출처는 여기이다.

이미지 출처: https://eli.thegreenplace.net/2018/depthwise-separable-convolutions-for-machine-learning/

 

왼쪽은 일반적인 convolution layer의 연산 방법을 보여준다. input의 height와 width는 8x8이고, channel(depth)는 3이다. convolution을 수행하는 filter는 3x3 크기이며 channel의 수는 input channel과 같은 값인 3이 된다. 그림에서 볼 수 있듯이, filter는 input의 3x3x3 부분에 대한 dot product를 하나씩 계산하며 input을 한번 훑어준다. input의 3x3x3 부분과 3x3x3 filter가 만나 1개의 dot product 결과물이 생성된다. 이 때 filtering(각 channel에 대한 convolution)과 combining(여러 채널의 결과를 합침)이 동시에 일어난다.

 

Depthwise separable convolution은 filtering과 combining을 분리했다. Depthwise convolution은 'filtering' 역할을, pointwise convolution은 combining을 담당하게 된다.

 

Depthwise convolution에서는 1개의 input channel에 1개의 single filter를 적용한다. 즉, 3x3x3 filter가 한번에 돌아다니는 대신, 1개의 3x3x1가 1개의 input channel에 적용된다. 그래서 3개의 3x3 filter가 3개의 input channel '각각' 적용되어 총 3개의 output layer가 만들어지고, 이게 concatenate되어 depth 3의 중간 결과물이 생성된다.

 

여기 1x1x3 filter를 적용함으로써 3개의 filter로부터의 결과를 1개의 값으로 combining할 수 있게 되는 것이다! 

 

이러한 분리 작업은 계산량과 모델 크기를 획기적으로 줄여준다.

 

Standard convolution의 계산량: stride 1에 padding을 적용했을 때(즉 input과 output의 height x weight가 같음), standard convolution의 계산량은 Dk · Dk · M · N · Df · Df (Dk: filter 의 height & width / kernel size; M:input의 channel; Df: input의 height & width; N: output의 channel)이다. 논문에도 설명되어 있긴 한데, 단순하게 생각해볼 수 있다. Dk x Dk x M 크기의 filter가 있다고 하자. 1개의 dot product output을 만드려면 Dk · Dk · M 만큼 곱하기가 필요하다(이후 sum을 통해 한 개의 값이 된다). 이 과정을 Df · Df · N (output의 height x width x channel)번을 해야한다. 그래서 연산량이 Dk · Dk · M · N · Df · Df 가 되는 것이다. 곱하기를 몇 번해야하는지를 기준으로 잘 그려서 해보면 이해할 수 있다. 

 

Depthwise separable convolution의 계산량: 같은 조건을 적용하면, 계산량은 Dk · Dk · M · Df · Df + M · N · Df · Df 이 된다. 우선 depthwise convolution에서는 각 input channel에 1개의 single filter를 적용한다. 1개의 Dk x Dk filter는 1개의 dot product output을 만들기 위해 Dk · Dk 만큼의 연산이 필요하다. Df · Df 의 한 output channel을 만들려면 Dk · Dk · Df · Df 만큼 연산하게 되고, input channel 수 만큼 이걸 반복해야 하므로 Dk · Dk · M · Df · Df 이 되는 것이다. 한편 pointwise convolution은 1개의 dot product output을 만드는 데에 M만큼의 연산만 필요하며(1x1 convolution을 M번, input channel 수만큼 하게 되므로), 이걸 output dimension인 Df · Df · N 만큼 반복하면 된다. 이에 pointwise convolution의 연산량은 M · N · Df · Df이 되며, depthwise separable convolution의 연산량은 Dk · Dk · M · Df · Df + M · N · Df · Df 이 된다. 

 

최종적으로 우리는 아래의 식처럼 1/N + 1/Dk^2 만큼의 계산량 감소를 확인할 수 있다. 논문에 소개된 대로 kernel size 3인 3x3 depthwise separable convolution을 사용하게 되면 연산량이 1/N + 1/9 수준으로 감소한 것이 되므로, standard convolution에 비해 8-9배 정도 계산량이 덜 드는 셈이 된다.

 

출처: 논문

구체적으로 batch normalization 과 activation function을 포함하여 실제로 사용되는 구조의 차이를 살펴보면 다음과 같다.

출처: 논문

좌측은 standard convolution layer과 달리 우측 depthwise separable layer는 batch normalization과 relu가 총 두번, depthwise와 pointwise layer 다음에 각각 적용된다. 이게 핵심 building block이고, 이것들을 차곡차곡 쌓으면 MobileNet architecture를 만들 수 있다! 

 

MobileNet 추가 경량화를 위한 두 파라미터 - Width Multiplier & Resolution Mutiplier

이미 많이 경량화된 모델이지만 더 가벼운 모델이 필요할 수 있다. 이 때 모델의 depth를 희생하지 않고 모델의 크기와 속도를 조절하는 방법이 있다. Width Multiplier (alpha)와 Resolution Multiplier (rho)이다.

 

Width Multiplier는 filter의 수, 즉 input의 channel 수와 output의 channel 수를 일괄적으로 조정하는 파라미터이다. 0에서 1사이의 값을 가지며, 0.5 로 설정하면 전체 구조에서 filter의 수가 반으로 된다. 약 alpha^2 만큼 속도/파라미터 수가 줄어든다. 

 

Resolution Multipler는 kernel 의 크기를 조절하는 파라미터이다. 역시 0에서 1사이의 값을 가진다.

 

두 파라미터를 적용했을 때의 최종 계산량은 아래와 같다. 

출처: 논문

 

 

 

 

이런 접근법을 통해 논문에서는 정확도와 size & speed의 trade-off 를 '합리적인' 수준으로 지켜냈음을 보여준다. ~! 이하 실험에 대한 내용은 생략하겠다.

 

소감

- 얘는 오히려 구현은 어렵지 않은데 depthwise separable convolution 자체를 이해하는 게 처음엔 어려웠다. 다시 standard convolution을 뒤져보고, 감사히 본문에 첨부된 다른 블로그의 사진을 본 뒤에야 이해할 수 있었다. 원 논문의 그림은 생각보다 도움이 안 됐다ㅜㅜ 

 

- next는 MobileNet V2다..~!