logo

합성곱층 📂머신러닝

합성곱층

정의

W\mathbf{W}k×kk \times k 행렬이라고 하자. Mn×n=Mn×n(R)M^{n\times n} = M^{n\times n}(\mathbb{R})을 크기가 n×nn \times n인 실수행렬들의 집합이라고 하자. 합성곱층convolutional layer CW:MnnM(nk+1)×(nk+1)C_{\mathbf{W}} : M^{nn} \to M^{(n-k+1) \times (n-k+1)}이란 다음과 같이 정의되는 함수이다. XMn×n\mathbf{X} \in M^{n\times n}Y=CW(X)\mathbf{Y} = C_{\mathbf{W}}(\mathbf{X})에 대해서,

Yij=[w11w12w1kw21w22w2kwk1wk2wkk][Xi,jXi,j+1Xi,j+k1Xi+1,jXi+1,j+1Xi+1,j+k1Xi+k1,jXi+k1,j+1Xi+k1,j+k1]=q=1kr=1kWqrXi+q1,j+r1 \begin{align*} Y_{ij} &= \begin{bmatrix} w_{11} & w_{12} & \cdots & w_{1k} \\ w_{21} & w_{22} & \cdots & w_{2k} \\ \vdots & \vdots & \ddots & \vdots \\ w_{k1} & w_{k2} & \cdots & w_{kk} \end{bmatrix} \cdot \begin{bmatrix} X_{i, j} & X_{i, j+1} & \cdots & X_{i, j+k-1} \\ X_{i+1, j} & X_{i+1, j+1} & \cdots & X_{i+1, j+k-1} \\ \vdots & \vdots & \ddots & \vdots \\ X_{i+k-1, j} & X_{i+k-1, j+1} & \cdots & X_{i+k-1, j+k-1} \end{bmatrix} \\ &= \sum_{q=1}^{k} \sum_{r=1}^{k} W_{qr} X_{i+q-1, j+r-1} \end{align*}

XijX_{ij}X\mathbf{X}ii행, jj열의 성분이다.

설명

합성곱층은 주어진 W\mathbf{W}에 대해서, X\mathbf{X}2차원 이산 합성곱 WX\mathbf{W} \ast \mathbf{X}로 보내는 사상이다. W\mathbf{W}를 부르는 말은 다양한데, 커널kernel, 필터filter, 윈도우window 등이 있다. 위 정의에서는 정방행렬인 것으로 정의했지만, W\mathbf{W}k1×k2k_{1} \times k_{2} 행렬로, Mn×nM^{n \times n}Mn1×n2M^{n_{1} \times n_{2}}로 일반화하여 생각해도 무방하다. 합성곱층에서 출력을 계산하는 과정을 움짤로 보면 아래와 같다.1

합성곱층과 활성화함수를 합성한 함수를 합성곱 신경망convolutional neural network, CNN이라 한다. CNN은 주로 이미지과 관련된 작업에서 좋은 성능을 보여준다. MLP의 경우에는 값이 한 층 한 층을 지날 때 마다 완전연결층으로 보내지기 때문에, 데이터의 차원이 크고 층이 깊으면 신경망의 파라미터가 엄청나게 많아진다는 단점이 있다. 반면에 합성곱층에서는 파라미터의 수가 입력 데이터의 크기와 상관없이 커널의 크기에만 의존하므로, 선형층과 비교해서 파라미터의 수를 확연히 줄일 수 있다는 장점이 있다.

역사적으로는 시신경이 대뇌에서 어떻게 작용하는지를 모방하여 제안되었다.

스트라이드

커널이 WRk×k\mathbf{W} \in \mathbf{R}^{k \times k}으로 주어진 합성곱층 CWC_{\mathbf{W}}에 대해서, Y=CW\mathbf{Y} = C_{\mathbf{W}}가 아래와 같이 정의될 때, 순서쌍 (s1(s_{1}, s2)s_{2})스트라이드stride라고 한다. XMn×n\mathbf{X} \in M^{n \times n}에 대해서,

Yij=q=1kr=1kWqrXs1(i1)+q,s2(j1)+r Y_{ij} = \sum_{q=1}^{k} \sum_{r=1}^{k} W_{qr} X_{s_{1}(i-1)+q, s_{2}(j-1)+r}

이때 iijj의 범위는,

i=1,2,,n(k1)s1+1,j=1,2,,n(k1)s2+1 i= 1, 2, \dots, \left\lfloor \frac{n-(k-1)}{s_{1}} \right\rfloor + 1, \quad j=1, 2, \dots, \left\lfloor \frac{n-(k-1)}{s_{2}} \right\rfloor + 1

\left\lfloor \cdot \right\rfloor바닥 함수이다.

합성곱을 직관적으로 설명하자면 커널을 한 칸씩 옮겨가며 데이터 X\mathbf{X}와 겹치는 부분에 대해서 내적을 하는 것이다. 그런데 여기에서 커널이 반드시 한 칸씩 움직이라는 법은 없다. 즉 스트라이드란 커널이 한 번에 움직이는 칸 수를 말한다. 별 말이 없으면 대개 stride=(1,1)\text{stride} = (1, 1)이 기본이고, 코드에도 보통 이것이 기본값이다.

커널의 크기가 k1×k2k_{1} \times k_{2}, 입력 행렬의 크기가 n1×n2n_{1} \times n_{2}, 스트라이드가 (s1,s2)(s_{1}, s_{2})라면 합성곱층의 출력 행렬의 크기는 다음과 같다.

(n1(k11)s1+1)×(n2(k21)s2+1) \left( \left\lfloor \frac{n_{1} - (k_{1}-1)}{s_{1}} \right\rfloor + 1 \right) \times \left( \left\lfloor \frac{n_{2} - (k_{2}-1)}{s_{2}} \right\rfloor + 1 \right)

패딩

순서쌍 (p1,p2)(p_{1}, p_{2})에 대해서, 다음과 같은 함수를, 혹은 순서쌍 자체를 패딩padding이라 한다.

padding:Mn×n(R)Mn+2p1×m+2p2(R)X[Op1×p2Op1×mOp1×p2On×p2XOn×p2Op1×p2Op1×mOp1×p2] \begin{align*} \operatorname{padding} : M^{n \times n}(\mathbb{R}) &\to M^{n+2p_{1} \times m+2p_{2}}(\mathbb{R}) \\ \mathbf{X} &\mapsto \begin{bmatrix} O_{p_{1} \times p_{2}} & O_{p_{1} \times m} & O_{p_{1} \times p_{2}} \\ O_{n \times p_{2}} & \mathbf{X} & O_{n \times p_{2}} \\ O_{p_{1} \times p_{2}} & O_{p_{1} \times m} & O_{p_{1} \times p_{2}} \end{bmatrix} \end{align*}

위의 꼴은 블록 행렬이고, OO영행렬이다. 쉽게 말해서 행렬의 위 아래에 값을 더 채워넣는 것이다. 패딩을 주는 이유는 합성곱층의 공역 Mnk+1×nk+1M^{n-k+1 \times n-k+1}의 차원이 정의역 Mn×nM^{n \times n}의 차원보다 작기 때문이다. 이 말은 어떤 이미지를 합성곱층에 반복해서 입력하면 이미지의 크기가 점점 작아진다는 의미이다. 패딩을 주면 이를 방지할 수 있다. 합성곱층에 패딩을 준다는 말은 입력 X\mathbf{X}와 합성곱 CWC_{\mathbf{W}} 사이에 패딩을 합성한다는 의미이다.

CWpadding(X) C_{\mathbf{W}} \circ \operatorname{padding} (\mathbf{X})

즉 미리 X\mathbf{X}를 키워놓으면, CWC_{\mathbf{W}}를 거쳐 크기가 작아져도 원래의 크기를 유지할 수 있다. kk홀수일 때, p=(k1)/2p = (k-1)/2으로 패딩을 주면 입력 행렬의 크기가 유지된다.

위에서는 패딩을 행렬의 상하좌우에 00을 추가하는 것으로 정의했지만 채워넣는 값이 꼭 00일 필요는 없다. 실제로 파이토치에는 다양한 방법의 패딩이 구현되어있다. 특히나 00을 채워넣은 패딩을 제로 패딩zero padding이라 한다.

커널의 크기가 k1×k2k_{1} \times k_{2}, 입력 행렬의 크기가 n1×n2n_{1} \times n_{2}, 스트라이드가 (s1,s2)(s_{1}, s_{2}), 패딩이 (p1,p2)(p_{1}, p_{2})라면 합성곱층 CWpaddingC_{\mathbf{W}} \circ \operatorname{padding}의 출력 행렬의 크기는 다음과 같다.

((n1+2p1)(k11)s1+1)×((n22p2)(k21)s2+1) \left( \left\lfloor \frac{(n_{1} + 2p_{1}) - (k_{1}-1)}{s_{1}} \right\rfloor + 1 \right) \times \left( \left\lfloor \frac{(n_{2} - 2p_{2}) - (k_{2}-1)}{s_{2}} \right\rfloor + 1 \right)

채널

커널이 행렬이 아니라 텐서일 수도 있다. W\mathbf{W}가 크기가 k×k×ck \times k \times c인 텐서일 때, ccW\mathbf{W}의 채널channel이라 한다. 입력 행렬의 크기가 n×nn \times n이고 커널의 크기가 k×k×ck \times k \times c일 때, Y=CW(X)\mathbf{Y} = C_{\mathbf{W}}(\mathbf{X})의 크기는 (nk+1)×(nk+1)×c(n-k+1) \times (n-k+1) \times c이다. 함숫값은 아래와 같이 계산된다.

Yij=q=1kr=1kWqrXi+q1,j+r1 Y_{ij\ell} = \sum_{q=1}^{k} \sum_{r=1}^{k} W_{qr\ell} X_{i+q-1, j+r-1}

이때 ii, jj, \ell 범위는, 스트라이드가 (s1,s2)(s_{1}, s_{2})일 때,

i=1,2,,n(k1)s1+1,j=1,2,,n(k1)s2+1=1,,c i= 1, 2, \dots, \left\lfloor \frac{n-(k-1)}{s_{1}} \right\rfloor + 1, \quad j=1, 2, \dots, \left\lfloor \frac{n-(k-1)}{s_{2}} \right\rfloor + 1 \\[1em] \ell = 1, \dots, c