1.はじめに
深層学習の勉強を始めました。今回は、誤差逆伝播法について、簡単にまとめてみます。
ニューラルネットワークの出力と正解の誤差から個々の重みをアップデートするには、どうしたら良いでしょうか。
単純に考えれば、1つ1つ重みをちょっと動かし誤差がどう変化するかを見て重みをアップデートする方法がありそうです。
しかし、深層学習では、重みは莫大(平気に1億とか)にあるので、これは現実的ではありません。そうした背景から生まれた、効率的に重みをアップデートする画期的な方法が誤差逆伝播法なのです。
今回は、出力層から順に遡って、どう重みをアップデートして行くかを見てみます。
2.出力層の重みのアップデート
出力層(k層)の重み$w_{jk}$をアップデートするために、$\frac{\partial E}{\partial w_{jk}}$を求めます。
\frac{\partial E}{\partial w_{jk}}=\frac{\partial E}{\partial y_k}*\frac{\partial y_k}{\partial w_{jk}}\\
=\frac{\partial E}{\partial y_k}*\frac{\partial y_k}{\partial v_k}*\frac{\partial v_k}{\partial w_{jk}}\\
2項目は、$y_k=\phi(v_k)$なので、単純に$\phi'(v_k)$です。3項目は、$v_k=w_{0k}+w_{1k}*y_1+w_{2k}*y_2+...+w_{jk}*y_j$なので、$w_{jk}$の係数のみが残り$y_j$です。1項目は、例えばEを二乗誤差 $E=\frac{1}{2}\sum(y_k - t_k)^2$ とすると、$(y_k-t_k)$です。従って、$\frac{\partial E}{\partial w_{jk}}$は下記の様に簡単に求められます。
=(y_k-t_k)*\phi'(v_k)*y_j\\
ここで、この後の説明を分かり易くするために、$\delta_k$を定義します。
\delta_k=\frac{\partial E}{\partial y_k}*\frac{\partial y_k}{\partial v_k}=\frac{\partial E}{\partial v_k}\\
つまり、
\frac{\partial E}{\partial w_{jk}}=\delta_k*y_i
3.出力層ー1の重みのアップデート
今度は、出力層−1(j層)の重み$w_{ij}$をアップデートするために、$\frac{\partial E}{\partial w_{ij}}$を求めます。
\frac{\partial E}{\partial w_{ij}}=\frac{\partial E}{\partial y_j}*\frac{\partial y_j}{\partial w_{ij}}\\
$\frac{\partial E}{\partial y_i}$は入力が複数あるので多変数の連鎖律を使って展開します。
=\sum_k(\frac{\partial E}{\partial v_k}*\frac{\partial v_k}{\partial y_j})*\frac{\partial y_j}{\partial v_j}*\frac{\partial v_j}{\partial w_{ij}}\\
先程、定義した$\delta_k$を適用すると
=\sum_k(\delta_k*w_{jk})*\phi'(v_j)*y_i
つまり、出力層-1(j層)の重みは出力層(k層)の計算結果を元に計算出来ます。
さて、先程同様$\delta_j$を定義します。
\delta_j = \sum_k(\delta_k*w_{jk})*\phi'_j(v_j)
つまり、
\frac{\partial E}{\partial w_{ij}}=\delta_j*y_i
4.出力層-2の重みのアップデート
今度は、出力層−2(i層)の重み$w_{hi}$をアップデートするために、$\frac{\partial E}{\partial w_{hi}}$を求めます。
\frac{\partial E}{\partial w_{hi}}=\frac{\partial E}{\partial y_i}*\frac{\partial y_i}{\partial w_{hi}}\\
=\sum_j(\sum_k(\frac{\partial E}{\partial v_k}*\frac{\partial v_k}{\partial y_j})*\frac{\partial y_j}{\partial v_j}*\frac{\partial v_j}{\partial y_i})*\frac{\partial y_i}{\partial v_i}*\frac{\partial v_i}{\partial w_{hi}}\\
$\delta_k=\frac{\partial E}{\partial v_k}$としたので、
=\sum_j(\sum_k(\delta_k*w_{jk})*\phi'(v_j)*w_{ij})*\phi'(v_i)*y_h\\
$\delta_j =\sum_k (\delta_kw_{jk})\phi'(v_j)$としたので、
=\sum_j(\delta_j*w_{ij})*\phi'(v_i)*y_h\\
つまり、出力層−2(i層)の重みは出力層-1(j層)の計算結果を元に計算出来ます。
この様に、誤差を出力層から逆方向に順番に伝搬させることによって、重みを簡単な計算で芋づる式にアップデートすることが出来るわけです。これが、誤差逆伝播法です。