ニューラルネットワーク入門④
前回は、ニューラルネットワークの学習において重要である損失関数と勾配降下法について説明しました。前回は重みの更新量は微分を用いて求めましたが、層が深くなってきた場合、計算に時間がかかってしまうという問題があります。今回は、重みの勾配の計算を効率よく行う手法である誤差逆伝播法について説明します。
勾配降下法のおさらい
誤差逆伝播法の説明をする前に、勾配降下法のおさらいをします。勾配降下法とは、現時点の状態から勾配(傾き)を計算して下る方向に進む手法でした。また、勾配降下法の概要を図にすると以下のようになっていました。この図が示していることは、損失を重みで微分することで勾配(傾き)を計算し、その勾配に比例した値を重みの更新量とするということです。
これを数式で表現すると以下のようになります。
\begin{align} \Delta w &= - η\frac{\partial E}{\partial w} \\ &= - η\frac{\Delta E}{\Delta f(u)} \frac{\Delta f(u)}{\Delta u} \frac{\Delta u}{\Delta w} \end{align}
ここで、は重みの更新量、は学習率です。学習率は、求められた勾配からどの程度重みを更新するかを決める係数です。損失関数を重みで偏微分して求めた勾配にマイナスと学習率をかけた値を重みの更新量としています。マイナスをかける理由は、勾配を上る方向から下る方向に変えるためです。
誤差逆伝播法
ニューラルネットワークへ入力した値が、入力層→中間層→出力層の順に伝播することを、順伝播といいます。また、その逆向きに出力層から入力層に向かって伝播することを逆伝播といいます。誤差逆伝播法とは、出力層で求められた誤差を入力層に向かって伝播する手法です。層が何層も重なる場合、純粋に偏微分を行って勾配を求めるよりも高速に効率よく勾配を計算することが出来ます。
誤差逆伝播法の説明の際は、各記号は以下のような意味で用います。
- :損失関数
- :層目のユニットへの重みの行列
- :層目のユニットへの入力のベクトル
- :層目のユニットの出力のベクトル
それでは、誤差逆伝播法の具体的な仕組みについて説明していきます。 上の式は、合成関数の微分から以下のようになります
\begin{align} \Delta w^{(l)} &= - η\frac{\partial E}{\partial w^{(l)}} \\ &= - η\frac{\partial E}{\partial u^{(l)}}\frac{\partial u^{(l)}}{\partial w^{(l)}} \end{align}
ここで、からとなるため(層目のユニットへの入力を層目のユニットへの重みで微分すると、層目のユニットの出力となるため)
\begin{align} \Delta w^{(l)} &= - η\frac{\partial E}{\partial u^{(l)}} \frac{\partial u^{(l)}}{\partial w^{(l)}} \\ &= - η\frac{\partial E}{\partial u^{(l)}} z^{ (l - 1) } \end{align}
となります。
つまり、が分かれば、勾配が分かり、重みの更新量を求めることが出来ます。
ここで、とし、デルタと呼ぶことにします。誤差逆伝播法とは、このデルタを出力層から入力層へ順に求めていく手法です。
また、損失関数を求める過程でという計算が含まれているため、合成関数の微分から以下のように変形することが出来ます。
\begin{align} δ^{(l)} &= \frac{\partial E}{\partial u^{(l)}} \\ &= \frac{\partial E}{\partial u^{(l+1)}} \frac{\partial u^{(l+1)}}{\partial u^{(l)}} \end{align}
ここで、層目のユニットへの入力とその微分は以下のようになります。
\begin{align} u^{(l+1)} = w^{(l)}f(u^{(l)}) \\ \frac{\partial u^{(l+1)}}{\partial u^{(l)}} = w^{(l)} f'(u^{(l)}) \end{align}
また、よりは以下のようになります。
\begin{align} δ^{(l)} &= \frac{\partial E}{\partial u^{(l+1)}} \frac{\partial u^{(l+1)}}{\partial u^{(l)}} \\ &= δ^{(l+1)} w^{(l)} f'(u^{(l)}) \end{align}
したがって、出力層のユニットに対応するのみ通常の方法(誤差関数の微分と活性化関数の微分)で求めてしまえば、あとは入力層に向かってを繰り返していけば、誤差を逆伝播させることが出来ます。
まとめると、以下のようになります。
- 順伝播
\begin{align} z^{ (l+1) } = f(w^{(l)}z^{(l)}) \end{align}
\begin{align} δ^{(l)} &= δ^{(l+1)} w^{(l)} f'(u^{(l)}) \\ \end{align}
- 勾配降下法
\begin{align} \Delta w^{(l)} &= - η\frac{\partial E}{\partial w} \\ &= - η\frac{\partial E}{\partial u^{(l)}} \frac{\partial u^{(l)}}{\partial w^{(l)}} \\ &= - η δ^{(l)} z^{ (l - 1) } \end{align}
このように、誤差逆伝播法をによって求めた誤差を用いて、勾配降下法で重みを更新量を求めます。
今回は、重みの勾配の計算を効率よく行う手法である誤差逆伝播法について説明しました。これで、形式ニューロンから誤差逆伝播法までを一通り説明し終わりましたので、ニューラルネットワーク入門は終了です。深層学習(Deep Learning)はニューラルネットワークを多層にしたものですので、深層学習に関してもここまで読めていれば基礎は大丈夫だと思います。ここまで読んで頂き本当にありがとうございます。もしご質問やご指摘等ありましたら、お気軽にコメントして頂けると幸いです。
最後に、ニューラルネットワークの基礎を学ぶ上でおすすめの書籍をご紹介いたします。
ニューラルネットワークの基礎がPythonのコードとともにとても分かりやすく説明されています。特に、誤差逆伝播法の部分は計算グラフを用いて直観的に説明されていて、とても分かりやすいと思います。手を動かしながら学んでいきたい方にはぴったりな書籍だと思います。最近続編でゼロから作るDeep Learning2が出版されました。こちらは自然言語処理編となっていますが、LSTMやAttentionなど自然言語処理以外でも多くの分野で用いられている非常に重要な手法が説明されているため、自然言語処理に興味がある方はもちろん、自然言語処理以外の分野を扱う方にもおすすめです。
ニューラルネットワークの入門書に多い表面をなぞったようなものではなく、非常に理論的に分かりやすく説明されています。誤差逆伝播法なども、なぜそのような手法を用いるのか、なぜそのような手法だと高速なのかなどとても詳しく書かれています。また、扱っている範囲も非常に網羅的であり、この本を一通り読めばニューラルネットワークの基礎はおさえたと言っても良いと思います。個人的には、ニューラルネットワークの入門書を1冊おすすめしてと言われたらこちらの本をおすすめします。
こちらの書籍はGoogleのIan Goodfellowさんによって書かれた書籍です。上記の2冊より1段階専門的になっており、非常に広い範囲をとても詳しく説明されています。個人的には、この書籍が一番深層学習やニューラルネットワークの本質を捉えた説明がされているのではないかとおもいます。上記の2冊のどちらかを読んで上でさらに専門的な内容に進みたい場合はこちらの書籍をおすすめします。