畳み込み層
定義
$\mathbf{W}$を$k \times k$行列としよう。$M^{n\times n} = M^{n\times n}(\mathbb{R})$をサイズが$n \times n$の実数行列の集合としよう。畳み込み層convolutional layer$C_{\mathbf{W}} : M^{nn} \to M^{(n-k+1) \times (n-k+1)}$は次のように定義される関数である。$\mathbf{X} \in M^{n\times n}$と$\mathbf{Y} = C_{\mathbf{W}}(\mathbf{X})$に対して、
$$ \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} \odot \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*} $$
$X_{ij}$は$\mathbf{X}$の$i$行、$j$列の成分である。
説明
畳み込み層は、与えられた$\mathbf{W}$に対して、$\mathbf{X}$を2次元離散畳み込み$\mathbf{W} \ast \mathbf{X}$に送る写像である。$\mathbf{W}$を呼ぶ言い方は様々で、カーネルkernel、フィルターfilter、ウィンドウwindowなどがある。上の定義では正方行列として定義したが、$\mathbf{W}$を$k_{1} \times k_{2}$行列として、$M^{n \times n}$を$M^{n_{1} \times n_{2}}$として一般化して考えても問題ない。畳み込み層で出力を計算するプロセスをアニメーションで見ると以下の通りである。1
畳み込み層と活性化関数を合成した関数を畳み込みニューラルネットワークconvolutional neural network, CNNと呼ぶ。CNNは主にイメージに関連する作業で良い性能を示す。MLPの場合、値が層を通過するたびに全結合層に送られるため、データの次元が大きく層が深いとニューラルネットワークのパラメータが非常に多くなるという短所がある。一方で畳み込み層ではパラメータの数が入力データの大きさに関係なくカーネルのサイズにのみ依存するため、線形層と比較してパラメータの数を劇的に減らすことができるという長所がある。
歴史的には視神経が大脳でどのように作用するかを模倣して提案された。
ストライド
カーネルが$\mathbf{W} \in \mathbf{R}^{k \times k}$で与えられた畳み込み層$C_{\mathbf{W}}$に対して、$\mathbf{Y} = C_{\mathbf{W}}$が以下のように定義されるとき、順序対$(s_{1}$、$s_{2})$をストライドstrideという。$\mathbf{X} \in M^{n \times n}$に対して、
$$ Y_{ij} = \sum_{q=1}^{k} \sum_{r=1}^{k} W_{qr} X_{s_{1}(i-1)+q, s_{2}(j-1)+r} $$
このとき$i$と$j$の範囲は、
$$ 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$はフロア関数である。
畳み込みを直感的に説明すると、カーネルを1カ所ずつ移動させながらデータ$\mathbf{X}$と重なる部分に対して内積を行うということである。しかしこの時にカーネルが必ずしも1カ所ずつ動くという法律はない。つまりストライドとはカーネルが1回の動きで進行する距離を意味する。特に言及がなければ通常$\text{stride} = (1, 1)$が基本であり、コードでも通常これがデフォルト値である。
カーネルのサイズが$k_{1} \times k_{2}$、入力行列のサイズが$n_{1} \times n_{2}$、ストライドが$(s_{1}, s_{2})$ならば畳み込み層の出力行列のサイズは次のようになる。
$$ \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) $$
パディング
順序対$(p_{1}, p_{2})$に対して、次のような関数、または順序対自体をパディングpaddingという。
$$ \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*} $$
上の形はブロック行列であり、$O$は零行列である。簡単に言えば行列の上と下に値を追加して埋めることである。パディングを与える理由は畳み込み層の共域$M^{n-k+1 \times n-k+1}$の次元が定義域$M^{n \times n}$の次元より小さいためである。この言葉はある画像を畳み込み層に繰り返して入力すると画像のサイズが徐々に小さくなることを意味する。パディングを与えるとこれを防ぐことができる。畳み込み層にパディングを与えるということは入力$\mathbf{X}$と畳み込み$C_{\mathbf{W}}$の間にパディングを合成するという意味である。
$$ C_{\mathbf{W}} \circ \operatorname{padding} (\mathbf{X}) $$
つまりあらかじめ$\mathbf{X}$を拡大しておくことで、$C_{\mathbf{W}}$を通過してサイズが小さくなっても元のサイズを維持できる。$k$が奇数の時、$p = (k-1)/2$でパディングを与えると入力行列の大きさが変わらない。
上ではパディングを行列の上下左右に$0$を追加することで定義したが、埋める値が必ずしも$0$である必要はない。実際にPyTorchには様々な手法のパディングが実装されている。特に$0$を埋めたパディングをゼロパディングzero paddingという。
カーネルの大きさが$k_{1} \times k_{2}$、入力行列の大きさが$n_{1} \times n_{2}$、ストライドが$(s_{1}, s_{2})$、パディングが$(p_{1}, p_{2})$ならば畳み込み層$C_{\mathbf{W}} \circ \operatorname{padding}$の出力行列の大きさは次のようになる。
$$ \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) $$
チャンネル
カーネルが行列ではなくテンソルであることもある。$\mathbf{W}$が大きさが$k \times k \times c$のテンソルである場合、$c$を$\mathbf{W}$のチャネルchannelという。入力行列のサイズが$n \times n$でカーネルのサイズが$k \times k \times c$の時、$\mathbf{Y} = C_{\mathbf{W}}(\mathbf{X})$の大きさは$(n-k+1) \times (n-k+1) \times c$である。函数値は以下のように計算される。
$$ Y_{ij\ell} = \sum_{q=1}^{k} \sum_{r=1}^{k} W_{qr\ell} X_{i+q-1, j+r-1} $$
この時$i$, $j$, $\ell$の範囲は、ストライドが$(s_{1}, s_{2})$の時、
$$ 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 $$