Convolutional Neural Network (CNN)の数理をまとめました。
本稿の目標は、Kerasの以下のメソッド
keras.layers.convolutional.Conv2D()
model.add(Activation('relu'))
model.add(Activation('softmax'))
model.fit()
が、どのようなアルゴリズムでデータを解析しているかを理解することです。
画像を入力する場合、実際の入力データは3階のテンソル(横ピクセルの値、縦ピクセルの値、RGBチャンネル)ですが、本稿では理解を簡単にするため、入力データを1階のテンソル(ベクトル)、つまりRチャンネルの横ピクセルのみとします。
執筆にあたり、「高卒でもわかる機械学習」を参考にさせて頂きました。
公式
偏微分の連鎖則(Chain Rule)
$f$ が $x_1, x_2, \cdots x_n$ の関数であり、 $x_i$ が $u_1, u_2, \cdots u_n$ の関数であるとき、以下の公式が成立する。
\frac{\partial f(x_1, x_2, \cdots x_n)}{\partial u_i} = \sum_k \frac{\partial x_k(u_1, u_2, \cdots u_n)}{\partial u_i}\frac{\partial f}{\partial x_k}
関数の定義
識別関数
- $l \ (0 \leq l \leq L)$:
第 $l$ 層。入力層を第 $0$ 層、出力層を第 $L$ 層とする。 - $N^{(l)}$:
第 $l$ 層のユニットの総数。画像データを入力する場合、縦(または横)のピクセル数が第 $0$ 層(入力層)のユニットの総数 $N^{(0)}$ となる。 - $x^{(l)}_{i} \ (1 \leq i \leq N^{(l)})$ :
第 $l$ 層 $i$ 番目のユニットの出力値。画像データを入力する場合、赤(または青、緑)のチャンネルにおける縦(または横)から $i$ 番目のピクセルの値(0~255)が第 $0$ 層 $i$ 番目のユニットの値 $x^{(0)}_{i}$ となる。 - $w^{(l)}_{ij} \ (1 \leq i \leq N^{(l)}, \ 1 \leq j \leq N^{(l-1)})$:
第 $l$ 層 $i$ 番目のユニットに紐付いている第 $l-1$ 層 $j$番目の重み(「フィルタ」とも呼ばれる)。
上記のように変数を定義したとき、第 $l$ 層 $i$ 番目のユニットの識別関数 $u^{(l)}_i$は
\begin{eqnarray}
u^{(l)}_i
&\equiv&
w^{(l)}_{i1}x^{(l-1)}_{1} + w^{(l)}_{i2}x^{(l-1)}_{2} + \dots + w^{(l)}_{in}x^{(l-1)}_{N^{(l-1)}} + b^{(l)}_i
\qquad
( b^{(l)}_i = \mathrm{Const})\\
&=&
\sum_{k=1}^{N^{(l-1)}} w^{(l)}_{ik}x^{(l-1)}_{k} + b^{(l)}_i \\
&\equiv&
\sum_k w^{(l)}_{ik}x^{(l-1)}_{k} + b^{(l)}_i
\tag{1.1}
\end{eqnarray}
と表すことができる。ここで、定数$b^{(l)}_i$ は「バイアス」と呼ばれる。このような演算を「畳み込み」と呼び、Kerasではkeras.layers.convolutional.Conv2D()
で上記の計算を行っている。
活性化関数
識別関数 $u^{(l)}_i$を基に出力値 $x^{(l)}_i$ を決定する関数(活性化関数)$f$ を以下のように定義する。
x^{(l)}_i \equiv f(u^{(l)}_i) \tag{1.2}
誤差関数(損失関数)
出力値 $x^{(L)}_i$ に対する教師データを$t_i$と したときの誤差関数$E$ を以下のように定義する。
E(x^{(L)}_1, x^{(L)}_2, \cdots x^{(L)}_{N^{(L)}}) \equiv \frac{1}{2} \sum_k (x^{(L)}_k - t_k)^2 \tag{1.3}
勾配降下法による重みの更新式
学習率 $\rho \ (0 \leq \rho \leq 1)$ としたとき、勾配降下法による重みの更新式は
w^{(l)}_{ij}
\leftarrow
w^{(l)}_{ij} - \rho \frac{\partial E}{\partial w^{(l)}_{ij}}
\tag{2.1}
と表すことができる。ここで $(1.1)$ より、
\begin{eqnarray}
\frac{\partial E}{\partial w^{(l)}_{ij}}
&=&
\sum_{k} \frac{\partial u^{(l)}_{k}}{\partial w^{(l)}_{ij}}
\frac{\partial E}{\partial u^{(l)}_{k}} \\
&=&
\sum_{k} \frac{\partial}{\partial w^{(l)}_{ij}}
\left( \sum_{k'} w^{(l)}_{kk'}x^{(l-1)}_{k'} + b^{(l)}_k \right)
\frac{\partial E}{\partial u^{(l)}_{k}} \\
&=&
x^{(l-1)}_{j}
\frac{\partial E}{\partial u^{(l)}_{i}}
\tag{2.2}
\end{eqnarray}
\begin{eqnarray}
\because k \neq i, k' \neq j
&\rightarrow&
\frac{\partial}{\partial w^{(l)}_{ij}}
\left( w^{(l)}_{kk'}x^{(l-1)}_{k'} \right)
= 0 \\
k = i, k' = j
&\rightarrow&
\frac{\partial}{\partial w^{(l)}_{ij}}
\left( w^{(l)}_{kk'} x^{(l-1)}_{k'} \right)
= x^{(l-1)}_{j}
\end{eqnarray}
ここで、誤差関数 $E$ に対する $u^{(l)}_{i}$ の偏微分を
\delta^{(l)}_{i}
\equiv
\frac{\partial E}{\partial u^{(l)}_{i}}
\tag{2.3}
と定義すると、重みの更新式 $(2.1)$ は $(2.2),(2.3)$ より、
w^{(l)}_{ij}
\leftarrow
w^{(l)}_{ij} - \rho
x^{(l-1)}_{j}
\delta^{(l)}_{i}
\tag{2.4}
と表すことができる。
誤差逆伝播法(バックプロパゲーション)
$(1.2), (2.3)$ より、
\begin{eqnarray}
\delta^{(l)}_{i}
&=&
\frac{\partial E}{\partial u^{(l)}_{i}} \\
&=&
\sum_k \frac{\partial x^{(l)}_{k}}{\partial u^{(l)}_{i}}
\frac{\partial E}{\partial x^{(l)}_{k}} \\
&=&
\sum_k \frac{\partial f(u^{(l)}_k)}{\partial u^{(l)}_{i}}
\frac{\partial E} {\partial x^{(l)}_{k}} \\
&=&
f'(u^{(l)}_i) \frac{\partial E} {\partial x^{(l)}_{i}}
\tag{3.1}
\end{eqnarray}
\begin{eqnarray}
\because
k = i
&\rightarrow&
\frac{\partial f(u^{(l)}_k)}{\partial u^{(l)}_{i}}
=
\frac{\partial f(u^{(l)}_i)}{\partial u^{(l)}_{i}}
=
f'(u^{(l)}_i) \\
k \neq i
&\rightarrow&
\frac{\partial f(u^{(l)}_k)}{\partial u^{(l)}_{i}}=0
\end{eqnarray}
$l = L$ のとき、$(1.3)$ より、
\begin{eqnarray}
\frac{\partial E} {\partial x^{(l)}_{i}}
=
\frac{\partial E} {\partial x^{(L)}_{i}}
&=&
\frac{\partial} {\partial x^{(L)}_{i}}
\left(
\frac{1}{2} \sum_k (x^{(L)}_k - t_k)^2
\right) \\
&=&
\frac{\partial} {\partial x^{(L)}_{i}}
\left(
\frac{1}{2} \sum_k (x^{(L)2}_k - 2t_kx^{(L)}_k + t_k^2)
\right) \\
&=&
x^{(L)}_i - t_i
\tag{3.2}
\end{eqnarray}
\begin{eqnarray}
\because
k \neq i
\rightarrow
\frac{\partial} {\partial x^{(L)}_{i}}
(x^{(L)2}_k - 2t_kx^{(L)}_k + t_k^2) = 0
\end{eqnarray}
$(3.1),(3.2)$ より、
\begin{eqnarray}
\delta^{(l)}_{i}
=
f'(u^{(l)}_i) (x^{(L)}_i - t_i)
\tag{3.3}
\end{eqnarray}
$l \neq L$ のとき、$(1.1),(2.3)$ より、
\begin{eqnarray}
\frac{\partial E} {\partial x^{(l)}_{i}}
&=&
\sum_k \frac{\partial u^{(l+1)}_k}{\partial x^{(l)}_i}
\frac{\partial E}{\partial u^{(l+1)}_k} \\
&=&
\sum_k \frac{\partial}{\partial x^{(l)}_i}
\left(
\sum_{k'} w^{(l+1)}_{kk'} x^{(l)}_{k'} + b^{(l+1)}_{k}
\right)
\delta^{(l+1)}_{k} \\
&=&
\sum_k w^{(l+1)}_{ki}
\delta^{(l+1)}_{k}
\tag{3.4}
\end{eqnarray}
\begin{eqnarray}
\because
k' \neq i
\rightarrow
\frac{\partial} {\partial x^{(l)}_{i}}
(w^{(l+1)}_{kk'} x^{(l)}_{k'} ) = 0
\end{eqnarray}
よって $(3.1),(3.4)$ より、
\delta^{(l)}_i
=
f'(u^{(l)}_i) \sum_k w^{(l+1)}_{ki} \delta^{(l+1)}_{k}
\tag{3.5}
$(2.4),(3.3),(3.5)$ より、重みの更新式は
w^{(l)}_{ij}
\leftarrow
w^{(l)}_{ij} - \rho
x^{(l-1)}_{j}
\delta^{(l)}_{i}
\delta^{(l)}_i = \left\{ \begin{array}{ll}
f'(u^{(l)}_i) (x^{(l)}_i - t_i) & (l=L) \\
f'(u^{(l)}_i) \sum_k w^{(l+1)}_{ki} \delta^{(l+1)}_{k} & (l \neq L)
\end{array} \right.
\tag{3.6}
となる。
Kerasではmodel.fit()
で上記の計算を行っている。
活性化関数
ReLU(Rectified Linear Unit)
活性化関数としてReLU(Rectified Linear Unit)を採用した場合、 $f(u^{(l)}_i)$ は以下のように表すことができる。
f(u^{(l)}_i)
\equiv
\mathrm{max}(0,u^{(l)}_i)
=
\left\{ \begin{array}{ll}
u^{(l)}_i & (u^{(l)}_i \geq 0) \\
0 & (u^{(l)}_i < 0)
\end{array} \right.
\therefore
\frac{\partial f(u^{l}_i)}{\partial u_i}
=
f'(u^{(l)}_i)
=
\left\{ \begin{array}{ll}
1 & (u^{(l)}_i \geq 0) \\
0 & (u^{(l)}_i < 0)
\end{array} \right.
\tag{4.1}
Kerasではmodel.add(Activation('relu'))
で上記の計算を行っている。
Softmax
活性化関数としてSoftmaxを採用した場合、 $f(u^{(l)}_i)$ は以下のように表すことができる。
f(u^{(l)}_i)
\equiv
\frac{\exp(u^{(l)}_i)}{\sum_{k} \exp(u^{(l)}_k)}
\begin{eqnarray}
\therefore
\frac{\partial f(u^{l}_i)}{\partial u_i}
&=&
f'(u^{(l)}_i) \\
&=&
\frac{
\frac{\partial \exp(u^{(l)}_i)}{\partial u^{(l)}_i} \sum_{k} \exp(u^{(l)}_k) - \exp(u^{(l)}_i) \frac{\partial}{\partial u^{(l)}_i} \sum_{k} \exp(u^{(l)}_k)
}{\left( \sum_{k} \exp(u^{(l)}_k) \right)^2} \\
&=&
\frac{
\exp(u^{(l)}_i) \sum_{k} \exp(u^{(l)}_k) - \exp(u^{(l)}_i)^2}
{\left( \sum_{k} \exp(u^{(l)}_k) \right)^2} \\
&=&
f(u^{(l)}_i) \left( 1 - f(u^{(l)}_i) \right)
\tag{4.2}
\end{eqnarray}
Kerasではmodel.add(Activation('softmax'))
で上記の計算を行っている。
テンソルでさらに理解を深めたいあなたに
Introduction to Convolution all Neural Networks - Jianxin Wuが参考になりそうです。