第1-3回 数学から見るニューラルネットワーク [python]
前回は,最小化すべき誤差関数を求めました.
今回は,その誤差関数を最小化する方法を紹介します.
1 勾配降下法
誤差関数\(E(w)\)の最小値を求めていきます.
ニューラルネットワークは,複数の入力と出力を組み合わせるため,誤差関数は複雑になります.前回書いた分類における誤差関数は次の形です.
\begin{align}
E(w) = – \sum_{n=1}^{N} \sum_{k=1}^{K} d_{n k} log z_{k}(W)
\end{align}
最小値を求める方法として,勾配降下法を用います.
この手法は,ある点における傾きから低い方に下がっていくことで求めます.
概要は過去に記載したことがあるので,こちらをご参照ください.
このような方法で、傾きを求め低い方に一定の割合で進んでいく方法を勾配降下法といいます。勾配降下法には、様々なものがありますが1回微分を用いていきます.
ここで,1つ問題点があります.
傾きを求めるために,誤差関数を重み\(w\)で微分しなければいけません.
1層程度なら,手計算で微分ができるかもしれませんが,層数を増やしていくと関数が複雑化し微分がとても難しくなります.
そこで,次に示す誤差逆伝播法が有効になります.
2 誤差逆伝播法
具体例を混ぜつつ,誤差逆伝播法について紹介します.
確認ですが,求めたいのは各重みに対する勾配\(\frac{\partial E(w)}{\partial w^l_{i j}}\)です.

具体例を通して説明します.
確認になりますが,入力に対するユニットは次式で計算されます.
\begin{align}
u_1^{(2)} = w^{(2)}_{11} z^{(1)}_1 + w^{(2)}_{12} z^{(1)}_2 + w^{(2)}_{13} z^{(1)}_3 \\
u_2^{(2)} = w^{(2)}_{21} z^{(1)}_1 + w^{(2)}_{22} z^{(1)}_2 + w^{(2)}_{23} z^{(1)}_3
\end{align}
さて,まずは求めたい勾配について次のように変形します.
\begin{align}
\frac{\partial E(w)}{\partial w^{(2)}_{1 2}} =
\frac{\partial E(w)}{\partial u^{(2)}_{1}} \frac{\partial u^{(2)}_{1}}{\partial w^{(2)}_{1 2}}
\end{align}
ここで,後者は次のように簡単に計算できます.
\begin{align}
\frac{\partial u^{(2)}_{1}}{\partial w^{(2)}_{1 2}} = z_1^{(2)}
\end{align}
前者について見ていくに当たり,\(E(w)\)に対する\(u_1^{(2)}\)の影響を考えます.
この値は,次の層全てに影響を与えます.
このことから,連鎖律(多変数関数の合成関数の微分)により次のように計算できます.
\begin{align}
\frac{\partial E(w)}{\partial u^{(2)}_{1}} =
\frac{\partial E(w)}{\partial u^{(3)}_{1}}\frac{\partial u^{(3)}_1}{\partial u^{(2)}_{1}} +
\frac{\partial E(w)}{\partial u^{(3)}_{2}}\frac{\partial u^{(3)}_2}{\partial u^{(2)}_{1}}
\end{align}
各項の後者は,活性化関数を\(f(u)\)とすると次のようになります.
\begin{align}
u^{(3)}_1 = \sum w^{(2)}_{1k} z^{(2)}_k &= \sum w^{(2)}_{1k} f(u^{(2)}_k) \\ \frac{\partial u^{(3)}_1}{\partial u^{(2)}_{1}}
&= w^{(2)}_{11} f'(u^{(2)}_1)
\end{align}
前者 \(\frac{\partial E(w)}{\partial u^{(3)}_{1}}\) は,連鎖律を使用すると出力層まで同様の繰り返しになります.つまり,この値を\(\delta\)とすると次のように書けます.
\begin{align}
\frac{\partial E(w)}{\partial u^{(2)}_{1}} &= \delta^{(2)}_1 \\
\delta^{(2)}_1 &=
\delta^{(3)}_1\frac{\partial u^{(3)}_1}{\partial u^{(2)}_{1}} +
\delta^{(3)}_1\frac{\partial u^{(3)}_2}{\partial u^{(2)}_{1}}
\end{align}
つまり,最後の出力層における値がわかれば,連鎖的に\(\delta\)を計算することができます.出力層の活性化関数にソフトマックス関数を使用した場合は,以下の通りです.
\begin{align}
E(w) &= – \sum_k d_k log z_k = – \sum_k d_k log \left( \frac{exp(u_k^{(l)})}{\sum exp(u_i^{(l)})} \right) \\
\delta_j^{(l)} &= \frac{\partial E(w)}{\partial u^{(l)}_{j}} \\
&= – \sum_k d_k \frac{1}{z^{{(l)}}_k} \frac{\partial z^{{(l)}}_k}{\partial u^{(l)}_{j}} \\
&= – d_j \frac{1}{z^{(l)}_j} z^{(l)}_j – \sum_k d_k \frac{1}{z^{(l)}_k} (-z^{(l)}_j z^{(l)}_k) \\
&= z^{(l)}_j – d_j
\end{align}
ここで,\(d_k\)はデータとして与えられる解であり,分類では\([0, \cdots 0, 1, 0 \cdots 0] \)と与えられるため,総和は1となります.
以上から,出力層における勾配を算出し入力側に向かって勾配を計算すれば,各重みにおける勾配を算出することができます.
全勾配の平均で傾きを出せば、勾配降下法は可能です。
\begin{align}
\nabla E (\textbf{w}) = \frac{1}{N} \sum \frac{\partial E}{\partial \textbf{w}}
\end{align}
細かい点は,まだまだありますがニューラルネットワークの概要は以上となります.実装に伴う詳細は,また別で記載します.
次回は,実際にプログラミングし,機械学習を行います.
hide

にほんブログ村