반응형

towardsdatascience.com의 [기사] 내용을 정리함.

다음 [링크1] 의 내용을 참조함.

A Basic Introduction to Separable Convolutions

    [MobileNet]의 구조를 살펴본 사람이면 누구나 분할 합성곱(separable convolution)의 개념을 마주친다. 하지만 분할 합성곱이 무엇이고 일반적인 합성곱과는 어떤 차이가 있을까?

    분할 합성곱은 공간 분할 합성곱(spatial separable conv), 깊이 분할 합성곱(depthwise separable conv)의 두가자 주요 타입이 있다.


Spatial Separable Convolutions

    개념적으로 공간 분할 합성곱은 깊이 분할 합성곱보다 쉽다. 그리고 하나의 합성곱을 두개로 나누는 개념을 나타낸다.
    불행하게도 공간 분할 합성곱은 딥러닝에서 아주 많이 사용되지 않는 중대한 몇가지 제약이 있다.

    공간 분할 합성곱은 이미지와 커널의 공간적 차원(spatial dimentions)인 폭과 넓이를 다루기 때문에 붙여진 이름이다.(다른 차원은 깊이 차원으로 각 이미지의 채널의 수이다.)

    공간 분할 합성곱은 간단하게 커널을 더 작은 커널 둘로 나눈다. 대부분의 일반적인 경우는 3X3 커널을 3X1과 1X3커널로 아래와 같이 나눈다.



Image 1: Separating a 3x3 kernel spatially

    d이제 9번 곱셈으로 하나의 합성곱을 수행하는 것 대신, 동일 효과를 달성하기 위해 각각 3번의 곱셈으로 두번 합성곱한다(전체 6번). 더 적은 곱셈으로 계산 복잡도는 내려가고 네트워크는 더 빨리 실행될 수 있다.



Image 2: Simple and spatial separable convolution

    공간적으로 분리되어질 수 있는 가장 유명한 합성곱중 하나는 가장자리(edge) 탐지를 위해 사용하는 Sobel kernel이 있다.



Image 3: Separating the Sobel kernel

    공간 분할 합성곱의 주요 이슈는 모든 커널이 더 작은 커널 두개로 나눠질 수 없다는 것이다. 이것은 네트워크가 채택할 수 있는 모든 가능한 커널 때문에 훈련시 특히 귀찮아 진다. 그래서 공간 분할 합성곱은 더 작은 커널 두개로 나누어질 수 있는 작은 부분중 하나만을 사용할 수 있게 된다.


Depthwise Separable Convolutions

    공간 분할 합성곱과는 다르게 깊이 분할 합성곱은 더 작은 커널로 인수화(factored)되지 않는 커널로 동작한다. 따라서, 깊이 분할 합성곱이 더 일반적으로 사용된다. 이것은 keras.layers.SeparableConv2D 또는 tf.layers.separabel_conv2d에서 보이는 분할 합성곱의 타입이다.

    깊이 분할 합성곱은 단지 공간적 차원을 다루는 것이 아닌 깊이 차원-채널의 수-까지 다루기 때문에 붙여진 이름니다. 입력 이미지는 RGB의 3개 채널을 갖을 것이다. 몇번의 합성곱 이후, 이미지는 여러개의 채널을 갖게 된다. 해당 이미지의 특정 해석으로 각 채널을 이미지화 할 수 있다. 일례로, 'red' 채널은 각 픽셀의 'redness'를, 'blue' 채널은 각 픽셀의 'blueness'를 그리고 'green' 채널은 각 픽셀의 'greenness'를 나타낸다. 64 채널을 가진 이미지는 해당 이미지의 64가지 다른 해석을 갖는다.

    공간 분할 합성곱과 유사하게 깊이 분할 합성곱은 커널을 깊이 분할 합성곱과 점 합성공(pointwise convolution)두번 합성곱을 하는 2개의 분리된 커널로 나눈다.


Normal Convolution:

    우선 일반 합성곱(Normal Convolution)이 어떻게 동작하는지 알아보자.

    만약 2차원 관적에서 합성곱이 어떻게 동작하는지 알지 못한다면, 다음 [링크1],[링크2]를 참고하라.

    그러나 일반적으로 이미지는 2차원이 아니다. 일반적으로 이미지는 너비와 높이뿐만 아니라 깊이도 있다. 12 X 12 크기의 RGB이미지, 12 X 12 X 3 픽셀의 입력이미지가 있다고 가정해보자.

    패딩(padding)없이 스트라이드(stride) 1로 이미지에 5 X 5 합성곱을 해보자. 만약 단지 이미지의 너비와 높이만 고려했다면, 합성공 절차는 12 X 12 - (5 X 5) -> 8 X 8 과 같다. 5 X 5 커널은 매번 하나의 숫자를 출력하면서 25 픽셀과 스칼라곱이 발생한다. 결국은 패딩이 없기 때문에 (12 - 5 + 1 = 8), 8 X 8 픽셀 이미지가 된다.

    그러나, 이미지가 3개의 채널을 가지기 때문에, 합성곱 커널도 3개의 채널이 필요하다. 이는 5 X 5 = 25번 곱샘하는 것 대신, 실제로는 5 X 5 X 3 = 75번 곱셈을 커널이 움직이는 매번 한다.

    단지 2차원 해석과 같이, 한개의 숫자를 출력하면서 매번 25픽셀에 대해 스칼라 행력 곱(scalra matrix multiplication)을 한다. 5 X 5 X 3 커널을 지난 이후에는 12 x 12 X 3 이미지는 8 X 8 X 1이미지로 바뀐다.



Image 4: A normal convolution with 8x8x1 output

    만약, 출력이미지에서 채널수를 증가시키고 싶다면? 만약 출큭 크기를 8 X 8 X 256으로 만들고 싶다면?

    256개의 8 X 8 X 1 이미지를 생성하기 위해 256개의 커널을 생성하고 8 X 8 X 256 이미지 출력을 만들기 위해 그것들을 쌓을 수 있다.



Image 5: A normal convolution with 8x8x256 output

    이것이 일반적인 합성곱이 동작하는 방식이다. : 글쓴이는 이를 12 X 12 X 3 - (5 X 5 X 3 X 256) -> 12 X 12 X 256 (여기서 5 X 5 X 3 X 256은 높이, 너비, 채널, 출력수이다)와 같은 함수로 생각하면 좋겠다는 표현을 했다. 이것은 행렬 곱이 아니다. 커널로 전체 이미지를 곱하고 있지 않지만 커널이 이미지를 이동하고 각각 작은 부분을 곱하고 있다.

    깊이 분할 합성곱은 이 부분을 두 부분으로 나눈다. : 깊이 합성공(depthwise conv)와 점 합성곱(pointwise conv).


Part1 - Depthwise Convolution"

    첫번째 부분인 깊이 합성곱에서 입력 이미지에 깊이 변화없이 합성곱을 한다. 이것을 5 X 5 X 1 모양의 3개의 커널로 진행한다.

[Youtube]



Image 6: Depthwise convolution, uses 3 kernels to transform a 12x12x3 image to a 8x8x3 image

    각 5 X 5 X 1 커널은 이미지의 한 채널을 반복한다.(전체 채널이 아니다~). 매 25 픽셀 그룹의 스칼라 곱을 구하고 8 X 8 X 1 이미지를 출력한다. 이 이미지를 쌓아서 8 X 8 X 3 이미지를 만든다.


Part2 - Pointwise Convolution:

    기본적인 합성곱이 12 X 12 x 3 이미지를 8 X 8 X 256 이미지로 변환했지만, 현재 깊이 합성곱은 12 x 12 X 3 이미지를 8 X 8 X 3 이미지로 변환했다. 이제 각 이미지의 채널수를 늘려야 한다.

    점 합성곱은 1 X 1 커널을 사용하기 때문에 혹은 커널이 모든 점을 반복하기 때문에 이름지어 졌다. 이 커널은 아무리 많아도 입력 이미지가 가진 채널 수의 깊이를 갖는다; 예제의 경우, 3이다. 즉 1 X 1 X 3 커널을 8 X 8 X 3 이미지에 반복시켜 8 X 8 X 1 이미지를 얻는다.



Image 7: Pointwise convolution, transforms an image of 3 channels to an image of 1 channel

    최종 이미지인 8 X 8 X 256의 모습을 얻기 우해 각각 8 X 8 X 1 이미지를 출력하는 1 X 1 X 3 커널 256개를 만들 수 있다.



Image 8: Pointwise convolution with 256 kernels, outputting an image with 256 channels

    위와 같이 깊이 합성곱과 점 합성곱으로 기존 합성곱을 2개로 나누었다. 좀 더 추상적인 방법으로, 만약 원본 합성곱 함수가 12 X 12 X 3 - (5 X 5 X 3 X 256) -> 12 X 12 X 256이면, 12 X 12 X 3 - (5 X 5 X 1 X 1) -> (1 X 1 X 3 X 256) -> 12 X 12 X 256인 새로운 합성곱으로 표현할 수 있다.


깊이 분할 합성곱을 만들기 위한 핵심은?

    기본 합성곱에서 계산되어야 하는 곱셈의 수를 계산해보자. 8 X 8번 움직이는 5 X 5 X 3 커널이 256개 있으므로 256 X 3 X 5 X 5 X 8 X 8 = 1,228,800번의 곱셈이 있다.

    그러면 분할 합성곱은 어떨까? 깊이 합성곱에서 8 X 8번 움직이는 5 X 5 X 1 커널이 1개이므로 3 X 5 X 5 X 8 X 8 = 4,800번의 곱셈이 있다. 점 합성곱에서는 8 X 8 번 움직이는 1 X 1 X 3 커널이 256개 이므로 256 X 1 X 1 X 3 X 8 X 3 = 49,152번의 곱셍이 있다. 모두 더해보면 53,952번의 곱셈이 있다.

    이와 같이 적은 계산으로 네트워크는 더 빠른 시간안에 더 많이 처리할 수 있게 된다.

어떻게 동작하는 것일까? 글쓴이는 이 설명을 처음 접했들 때, 직관적으로 이해가 되지 않았다고 한다. 두가지 합성곱이 동일한 작업을 하는 것이 아닌가? 양쪽 모두, 5 X 5 커널을 통해 이미지를 전달하고 이를 하나의 채널로 축소한다. 그리고 256 채널로 확장한다. 어떻게 하나가 다른 것보다 두배이상 빠를 수 있을까?

    주요 차이점은,

  • 일반적인 합성곱에서는

    : 이미지를 256번 변환하고 있고 매 변환은 5 X 5 X 3 X 8 X 8 = 4800번의 곱셈을완전하게 사용한다.
  • 분할 합성곱에서는

    : 이미지를 단 한번반 변환한다.
    • 깊이 합성곱은 반복적인 이미지 변환없이 간단하게 변환된 이미지를 256채널로 늘린다. 이로써 컴퓨팅 파워를 줄일 수 있다.

    Keras와 Tensorflow에서는 depth multiplier라는 인자를 사용할 수 있다. 이 값을 변경하여 깊이 합성곱에서의 출력 채널수를 변결할 수 있다. 기본값은 1이다.

    예를 들면, depth muliplier를 2로 설정하면, 각 5 X 5 X 1 커널은 8 X 8 X 2의 이미지를 출력할 것이다. 그리고 8 X 8 X 3 대신 8 X 8 X 6의 깊이 합성곱 출력을 만든다.

    깊이 분할 합성곱의 단점은 분명히 있다. 깊이 분할 합성곱은 합성곱내 파라미터의 수를 줄이기 때문에 만약 네트워크가 작다면 결구 너무 작은 파라미터가 되고 네트워크는 훈련동안 적절한 학습을 할 수 없게 된다. 그러나 적절하게 사용하면, 큰 효율성 감소 없이 효율을 좋게 만들기 때문에 꽤 인기있다.


1 X 1 Kernels:

    마지막으로 점 합성곱이 1 X 1 커널 개넘을 사용하기 때문에 1 X 1 커널의 사용법을 간단하게 살펴보자

    1 X 1 커널 또는 오히려 n 1 X 1 X m 커널(여기서 n은 출력 채널의 수이고 m은 입력 채널의 수이다.)은 분할 합성곱 이외에서도 사용될 수 있다. 1 X 1 커널의 한가지 명확한 목적은 이미지의 깊이를 늘이거나 줄이는 것이다. 만약 사용하고자 하는 합성곱이 너무 많거나 너무 적은 채널을 가지고 있다면, 1 X 1 커널이 도움이 된다.

    글쓴이의 경우 주요 목적은 비선형성(non-linearlity)를 적용하는 것이다. 신경망의 각 레이어 다음에 활성화 레이어를 적용할 수 있다. ReLU, PReLU, Softmax 또는 다른 레이어든지 활성화 레이어는 합성곱 레이어와는 다르게 비선형이다. 직선의 선형 조합은 여전히 직선이다.일반적으로 깊은 네트워크가 넓은 네트워크에 비해 좋은 것 처럼 비선형 레이어는 모델의 가능성을 확대한다. 파라미터와 계산 수의 큰 증가 없이 비선셩의 수를 증가시키기 위해, 1 X 1 커널을 적용한 후 활성화 레이어를 추가한다. 이렇게 하면 네트워크를 깊게 만들 수 있다.

반응형

+ Recent posts