Link

합성곱 신경망

이번 챕터에서는 합성곱 신경망Convolutional Neural Networks, CNN에 대해서 다뤄보도록 하겠습니다. 앞서 우리는 FCfully-connected 계층을 활용하여 MNIST 분류 문제를 해결하였습니다. CNN은 딥러닝의 여러 분야에 활용될 수 있지만, 특히 컴퓨터 비전computer vision 문제에서 활약하는 아키텍처입니다. 따라서 이번 챕터를 통해 우리는 좀 더 나은 방법을 활용하여 MNIST 분류 문제를 해결해보도록 하겠습니다.

전통적인 방식

딥러닝 이전의 컴퓨터 비전에서도 합성곱 방식은 널리 사용되어 왔습니다. 책의 처음에서 딥러닝을 소개할 때, 기존 전통적인 방식의 머신러닝과 가장 큰 차이점 중의 하나는 ‘손으로 깎아서 만든 특징hand-crafted feature‘의 활용 여부였습니다. 따라서 만약 사진에서 어떤 물체를 인식하는데 만약 경계를 추출하는 것이 중요하다면, 다음의 그림과 같이 미리 정해진 합성곱 커널(또는 필터)을 사용하면 원하는 형태의 패턴이 추출 가능했습니다.[1] 즉, 합성곱 커널의 종류에 따라 추출할 수 있는 특징의 패턴은 바뀌기 때문에 미리 세운 가설에 따라 커널을 설계하고 적용하는 형태로 프로세스가 진행되었습니다.

[1]: 소벨Sobel 필터를 사용해서 물체의 경계선을 추출한 모습

합성곱 연산

그럼 합성곱 커널을 실제 어떻게 적용하여 연산을 수행 할 수 있을까요? 다음의 그림과 같이 $k_{1,1}$ 부터 $k_{3,3}$ 으로 이루어진 커널이 있을 때, 이미지에 각 위치와 곱셈 연산을 한 후 전부 더한 결과가 $y_{1,1}$ 이 됩니다.

위 그림을 수식으로 나타내면 다음과 같습니다.

\[\begin{aligned} y&=x_{1,1}\times{k_{1,1}}+\cdots+x_{3,3}\times{k_{3,3}} \\ &=\sum_{i=1}^{h=3}{ \sum_{j=1}^{w=3}{ x_{i,j}\times{k_{i,j}} } } \end{aligned}\]

이와 같은 연산이 앞의 그림에서는 가로 4번 세로 4번 총 16번 이루어지게 됩니다. 눈 여겨 볼 점은 입력이 $5\times5$ 의 행렬이었고, $3\times3$ 의 커널이 주어졌을 때, 입력보다 크기가 줄어든 $4\times4$ 행렬이 출력으로 반환되는 점입니다.

이 챕터에서 편의를 위해 앞으로 이러한 합성곱 연산을 $\bigotimes$ 로 나타내도록 하겠습니다. 그럼 다음의 그림과 같이 표현될 수 있습니다.

이제 좀 더 완벽한 이해를 쉽게 돕기 위해서, 앞 그림에서의 합성곱 연산이 전체 입력에 순차적으로 적용되는 모습을 그림으로 차례대로 나타내어 보겠습니다. 그림에서 입력 행렬에 초록색에 해당하는 부분에 합성곱 커널에 의한 연산이 이루어지면 출력에서 초록색에 해당하는 부분의 값이 구해집니다.

그런데 아쉽게도(?) $3\times3$ 커널이 적용되면 출력 행렬의 크기가 입력 행렬의 크기보다 줄어드는 것을 볼 수 있습니다. 만약 출력의 크기를 입력의 크기와 같게하고 싶다면 어떻게 하면 될까요? 입력 행렬 주변에 패딩padding을 추가하여 이 문제를 해결할 수 있습니다. 다음의 그림에서와 같이 주어진 입력 행렬에 한 칸씩 상하좌우에 패딩을 둘러주어 출력 행렬의 크기가 입력 행렬과 같아지도록 할 수 있습니다. 패딩을 채워넣는 전략은 여러가지 방법이 있지만, 보통 0으로 된 값을 채워넣습니다.

패딩이 적용된 이후에도 앞서 합성곱 연산의 경우와 똑같은 원리로 연산이 적용됩니다.

패턴 추출의 원리

이제까지 합성곱 커널에 의한 합성곱 연산이 어떻게 이루어지는지 수식과 그림을 통해 살펴보았습니다. 그럼 이 연산이 어떻게 패턴을 추출해낼 수 있는지 직관적으로 설명하고자 합니다. 다음의 그림에서 초록색 또는 노란색으로 색칠된 부분은 큰 값이 존재하는 영역을 의미합니다. 그럼 숫자 2와 같은 패턴을 추출하고자 할 때, 두 방향의 대각선 패턴과 가로 직선 패턴을 추출하는 것이 중요할 것이라는 가정을 세웠다고 생각해보도록 해보죠. 각 패턴을 추출하기 위한 커널을 적용한 결과는 다음과 같을 것입니다.

이를 통해 우리는 어떤 패턴이 어디에 나타나는지 확인할 수 있습니다. 예를 들어 좌상단에서 우하단을 가로지르는 대각선 패턴의 경우에는 입력 행렬의 우상단에 나타나는 것을 확인할 수 있습니다. 이처럼 필요한 각 패턴의 추출 결과를 모아서 결과를 종합해보면, 입력 행렬에는 2라는 모양이 존재하고 있다고 결론내릴 수 있을 것입니다.

전통적인 방식의 머신러닝에서는 이처럼 가정을 통해 미리 설정한 합성곱 커널을 사용해서 패턴을 추출합니다. 하지만 딥러닝에서는 모델의 출력 $\hat{y}$ 과 타겟 값 $y$ 이 같아지도록 패턴을 추출할 수 있는 커널이 자동으로 학습됩니다. 만약 모델에서 특징을 추출하기 위해, 양 대각선 방향과 가로 직선 방향의 패턴을 위한 커널이 되어야 손실 값이 낮아진다면, 경사하강법gradient descent에 의해서 자동으로 해당 패턴을 위한 커널들이 찾아지도록 학습될 것입니다. 이렇게 학습된 모델을 활용하면 앞서 예제에서처럼 2와 같은 모양의 패턴들이 잘 인식될 것입니다.

다시 정리하면, 전통적인 방식에선 앞서의 예제와 같이 손으로 깎아서 만든 특징hand-crafted feature을 활용하는데 합성곱 연산이 활용되었습니다. 하지만 딥러닝에서는 합성곱 계층convolutional neural network, CNN을 활용하여 최적의 패턴 추출 방법을 자동으로 학습하고, 이렇게 학습된 커널을 활용하여 더 나은 패턴 추출을 수행합니다.

채널

앞서 예제와 같이 여러가지 특징들의 패턴을 동시에 추출하고 싶을 때, 여러개의 커널을 적용할 수 있습니다. 우리는 이렇게 사용되는 커널의 숫자를 출력 채널output channel의 숫자라고 부르기도 합니다. 또한 특징을 추출하고자 하는 입력이 여러개의 채널을 가질 수도 있습니다. 이것을 입력 채널input channel이라고 부릅니다. 예를 들어 컬러 이미지의 경우에는 빨강, 초록, 파랑 3가지 색깔로 자연색을 표현하기 때문에 RGB 각 색깔 별로 채널을 갖게 되어, 3가지 채널을 갖게 됩니다.

앞의 그림에서처럼 커널의 갯수가 최종 출력물의 채널 갯수가 됩니다. 이때 각 커널은 입력 채널에 대해서 합성곱 연산을 수행하고 모두 더해서 출력 채널에 값을 표현하게 됩니다.

계층 입출력 텐서 형태

결과적으로 합성곱 계층convolutional layer의 입출력 텐서의 형태는 보통 다음과 같은 형태를 띄게 됩니다.

\[\begin{gathered} y=\text{conv}(x), \\ \text{where }\begin{cases} |x|=(N, c_{\text{in}}, x_{\text{height}}, x_{\text{width}}) \\ \begin{aligned} |y|&=(N, c_{\text{out}}, y_{\text{height}}, y_{\text{width}}) \\ &=(N, c_{\text{out}},x_{\text{height}}-k_{\text{height}}+1,x_{\text{width}}-k_{\text{width}}+1). \end{aligned} \end{cases} \end{gathered}\] \[\begin{aligned} N&=\text{batch size} \\ (x_{\text{height}}, x_{\text{width}})&=\text{input size} \\ c_{\text{in}}&=\text{\# input channels} \\ c_{\text{out}}&=\text{\# output channels} \\ (k_{\text{height}}, k_{\text{width}})&=\text{kernel size} \\ (y_{\text{height}}, y_{\text{width}})&=\text{output size} \end{aligned}\]

앞의 수식에 따라서, 앞서 예제에서 $4\times4$ 의 입력 행렬과 $3\times3$ 의 커널이 주어졌을 때, $(4-3+1)\times(4-3+1)=2\times2$ 크기의 출력 행렬을 얻을 수 있음을 보았습니다.

만약 패딩이 추가된다면 수식을 좀 더 바뀌게 되는데요. 패드를 추가하였을 때의 입출력 텐서 형태를 계산하기 위한 수식은 다음과 같습니다.

\[\begin{gathered} y=\text{conv2d}(x), \\ \text{where }\begin{cases} |x|=(N, c_{\text{in}}, x_{\text{height}}, x_{\text{width}}) \\ \begin{aligned} |y|&=(N, c_{\text{out}}, y_{\text{height}}, y_{\text{width}}) \\ &=( N, c_{\text{out}}, x_{\text{height}}+2\times{p_{\text{height}}}-k_{\text{height}}+1, x_{\text{width}}+2\times{p_{\text{width}}}-k_{\text{width}}+1 ). \end{aligned} \end{cases} \end{gathered}\] \[\begin{aligned} b&=\text{batch size} \\ (x_{\text{height}}, x_{\text{width}})&=\text{input size} \\ c_{\text{in}}&=\text{\# input channels} \\ c_{\text{out}}&=\text{\# output channels} \\ (k_{\text{height}}, k_{\text{width}})&=\text{kernel size} \\ (y_{\text{height}}, y_{\text{width}})&=\text{output size} \\ (p_{\text{height}}, p_{\text{width}})&=\text{pad size} \\ \end{aligned}\]

이 수식에 따라 앞서 예제에서와 같이 $4\times4$ 입력 행렬에 패딩이 상하좌우 한 칸씩 추가되고 $3\times3$ 커널이 주어진다면, $(4+2\times1-3+1)\times(4+2\times1-3+1)=4\times4$ 출력 행렬을 얻을 수 있습니다.

이와 같은 합성곱 계층의 입출력 텐서 형태 계산은 추후 실제 프로젝트를 수행할 때, 매우 유용하게 사용될 수 있습니다. 특히 잠시후에도 다루겠지만, 합성곱 계층은 입출력의 형태 계산이 까다롭다는 단점이 있기 때문에, 모델 구조를 설계할 때 계층간 입출력 텐서 크기를 주의깊게 살펴야 합니다. 따라서 이 수식들을 숙지하고 있다면, 모델 구조 설계할 때 어려움이 줄어들 것입니다.

합성곱 계층의 특징과 장단점

앞서 우리가 주로 사용하였던 선형 계층linear layer의 경우에는 입력 벡터의 각 차원이 정해진 의미를 갖고 있었습니다. 예를 들어 엑셀 파일과 같은 테이블 데이터tabular dataset를 다룰 경우, 각 열column은 특정 의미의 값에 매핑 되어 있기 마련입니다.

이름 몸무게 나이
홍길동 183 77 32
홍당무 175 70 28

그런데 만약 실수로 특정 샘플의 일부 값들이 한 칸씩 옆으로 밀려 있었다면 어떻게 될까요?

이름 몸무게 나이
홍길동 183 77 32
홍당무 28 175 70

전혀 다른 의미의 샘플이 되거나, 아예 데이터로서 의미를 잃어버릴 수 있습니다. 하지만 이미지의 세계에선 이와 같은 일들이 빈번하게 일어납니다. 예를 들어 MNIST 이미지 샘플을 오른쪽으로 한 칸씩 이동시키더라도 샘플의 의미는 전혀 변하지 않으며, 우리가 숫자를 알아보는데 지장도 없으니, 모델이 인식하는데에도 전혀 차질이 없어야 할 것입니다. 하지만 선형 계층은 태생부터 이와 같은 이미지의 변화를 받아들이기 힘든 구조이며, 한 칸 이동한 그림은 모델 입장에서 전혀 다른 새로운 샘플이 됩니다. 즉, 새롭게 다시 학습해야 하는 대상이 됩니다. 하지만 합성곱 계층은 위치에 상관 없이 특징의 패턴을 인식할 수 있기 때문에, 앞서와 같이 한 칸 이동한 그림의 경우에도 큰 어려움 없이 해결할 수 있게 됩니다.

또한 선형 계층의 경우에는 입력과 출력 벡터의 크기가 정해지면 내부 가중치 파라미터의 크기가 정해지는데 반해, 합성곱 계층의 경우에는 입출력 크기와 상관 없이 내부 커널의 크기에 따라 가중치 파라미터의 크기가 정해지므로, 훨씬 더 적은 파라미터 수를 가지게 됩니다. 모델이 더 적은 파라미터 수를 갖게 되면, 속도나 메모리 측면에서도 이득일 뿐만 아니라, 최적화에 있어서도 훨씬 난이도가 낮아지게 됩니다. 마지막으로 선형 계층에 비해서 파라미터 수가 작을 뿐만 아니라, 병렬 연산으로 구성하기 쉬운 구조이므로 학습과 추론 속도 면에서도 훨씬 월등합니다.

하지만 합성곱 계층의 경우에는 입력과 출력 크기가 고정되어 있지 않다는 특징이 단점으로 작용할 수 있습니다. 선형 계층의 경우에는 애초에 계층을 선언할 때, 그 크기를 입력해주어야 하므로, 입출력의 크기를 직관적으로 확인하기 쉽습니다. 하지만 합성곱 계층의 경우에는 앞서 입출력 크기를 계산하던 복잡한 수식에서 알 수 있듯이, 입출력의 크기를 직관적으로 확인하기 어려워, 합성곱 계층을 활용하여 전체 신경망을 구현할 때 난이도가 높아지게 됩니다.