誤差逆伝搬法の計算(2)

隠れ層、出力ユニットが増えた時の誤差逆伝搬法の算出について

前回のチュートリアルでは3層でかつ1入力1出力のニューラルネットワークを用いて、誤差逆伝搬法の算出について説明しました。しかし、あくまでそれは1経路(後述)に対する算出でした。4層以上になると、入力層付近の重みの経路が増えます。本チュートリアルでは経路が増えた場合にどのように算出するかについて説明します。また、層が増えることによって、入力層が付近の重みが更新しにくくなるという勾配消失問題が生じます。これについても軽く紹介します。

隠れ層が増えた場合

出力ユニットと更新したい重みの間に「経路」があると考えてください。例えば以下のようなニューラルネットワークがあるとして、入力層付近にある重み1個を更新したい時には以下の経路に従ってチェイン・ルールを適用します。

問題を分かりやくするため、今回は活性化関数は f(x) で統一します。

ここで E=(r_1-y_1)^2/2 を想定しています。上記の経路に従ってチェイン・ルールを使えば、重み w_1 の更新量は赤丸の値だけを使って計算できます。

\begin{split}\frac{\partial E}{\partial w_1}=\frac{\partial E}{\partial y_1}\frac{\partial y_1}{\partial z_5}\frac{\partial z_5}{\partial x_3}\frac{\partial x_3}{\partial z_3}\frac{\partial z_3}{\partial x_1} \\=-(r_1-y_1)\ \dot{f}(z_5)\ w_3\ \dot{f}(z_3)\ u_1\end{split}

しかし、ニューラルネットワークの隠れ層が下記のように増えた場合どうなりますでしょうか。4層と1出力のニューラルネットワークを考えてください。

すると、出力層までの経路が増えます。この場合、どのように算出するのでしょうか?

例えば、 w_1 の更新量を算出したいとします。ここで、改めて、更新式を確認します。ついでに第2項にある更新量 \partial E/\partial y も確認します。

w_{t+1}\leftarrow w_t + \gamma \frac{\partial E}{\partial w_1}
\frac {\partial E}{\partial w_1}=\frac {\partial E}{\partial y_1}\frac {\partial y_1}{\partial z_5}\frac {\partial z_5}{\partial w_1}

出力層に入力する値 z_5 w_7x_7 w_8x_8 を加算します。各々には重み w_1 を含めています。すると、 \partial z_5/\partial w_1 は以下のように表現できます。

\frac {\partial z_5}{\partial w_1}=\frac {\partial}{\partial w_1}(w_7x_7+w_8x_8)= w_7\frac {\partial x_7}{\partial w_1}+ w_8\frac {\partial x_8}{\partial w_1}

各々に対して算出すると、以下の結果が得られます。

\begin{split} w_7\frac {\partial x_7}{\partial w_1}= \frac {\partial x_7}{\partial z_3} \frac {\partial z_3}{\partial x_3} \frac {\partial x_3}{\partial z_1}\frac {\partial z_1}{\partial w_1} \\ w_8\frac {\partial x_8}{\partial w_1}= \frac {\partial x_8}{\partial z_4} \frac {\partial z_4}{\partial x_4} \frac {\partial x_4}{\partial z_1}\frac {\partial z_1}{\partial w_1}\end{split}

結果的に更新量として下記の演算結果が得られます。

\begin{split}\frac {\partial E}{\partial w_1}=\frac {\partial E}{\partial y_1}\frac {\partial y_1}{\partial z_5} \frac {\partial z_5}{\partial x_7}\frac {\partial x_7}{\partial z_3} \frac {\partial z_3}{\partial x_3} \frac {\partial x_3}{\partial z_1}\frac {\partial z_1}{\partial w_1}\\ +\frac {\partial E}{\partial y_1}\frac {\partial y_1}{\partial z_5}\frac {\partial z_5}{\partial x_8}\frac {\partial x_8}{\partial z_4} \frac {\partial z_4}{\partial x_4} \frac {\partial x_4}{\partial z_1}\frac {\partial z_1}{\partial w_1}\\ =-(r_1-y_1)\ \dot{f}(z_5) \ w_7\ \dot{f}(z_3)\ w_3\ \dot{f}(z_1)\ u\\ -(r_1-y_1)\ \dot{f}(z_5)\ w_8\ \dot{f}(z_4)\ w_4\ \dot{f}(z_1)\ u\end{split}

上記の式は2つの経路のチェイン・ルール の和です。つまり、経路が複数ある場合は、各経路に対してチェイン・ルールを適用し、それらの和を取れば更新量は算出できます。赤が第1項、青が第2項です。丸記号は更新量を算出に必要な値です。

出力ユニットが増えた場合

では、出力ユニットが1個増えた場合はどうでしょうか。各出力 y_1 , y_2 の損失関数を E_1 E_2 とすると以下のように表現できます。

\frac {\partial E}{\partial w_1}=\frac {\partial E_1}{\partial w_1}+\frac {\partial E_2}{\partial w_1}

つまり、重み w_1 からそれぞれの出力 y_1 , y_2 までにチェーンルールを適用すれば、重み w_1 が算出できます。結局図のように4経路に対してチェーンルールを見ればいいということです。

入力ユニットが増えた場合については上記の算出方法が適用します。

勾配消失問題

ところで、上記では4層のニューラルネットワークを構築した場合、入力層付近の重みは出力層からの複数の経路に対してチェイン・ルールを適用し、それらの和をとりました。ここで、入力層と出力層を線形活性化関数( f(x)=x )、隠れ層の活性化関数としてSigmoid関数を用いた場合は、どうなるでしょうか。Sigmoid 関数の微分式を表すと以下のようになります。

\begin{split}f(x)=\frac{1}{1+\exp(-x)} \\ \frac {\partial f(x)}{\partial x}=f(x)(1-f(x))\end{split}

Sigmoid関数の場合、最大勾配は出力0.5の時です。つまり最大勾配は0.5(1-0.5)=0.25です。また、Sigmoid関数の出力は[0,1]です。

1経路に対してチェイン・ルールは以下のように算出できます。以下の式は上記の出力ユニットが1つ、 w_3 の重みを経由している時の更新量は以下のようになります。

\begin{split}\frac {\partial E_1}{\partial w_1}=\frac {\partial E}{\partial y_1}\frac {\partial y_1}{\partial x_8}\frac {\partial x_8}{\partial z_3} \frac {\partial z_3}{\partial x_1} \frac {\partial x_1}{\partial z_1}\frac {\partial z_1}{\partial w_1} \\ ≤ |-(r_1-y_1) \ w_5\ 0.25\ w_3\ 0.25\ u|\\ = 0.0625\ |r_1-y_1|\ w_5\ w_3\ u\end{split}

上記の算出から 0.0625 \partial E/\partial y\ w_5\ w_3\ u 以上の値は出せないことがわかります。この式は4層にした時の話ですが、隠れ層が増えるごとに、入力層における最大値に0.25を掛けないといけないため、最大勾配が少しずつ減ることは想像できるでしょう。

逆に重みを大きくすれば、最大値が上がり、更新量が大きくなるのではと思うかもしれませんが、そうするとSigmoid関数の出力が1付近となり、どこかの勾配( \partial f(x)/ \partial x )がほぼ0になります。上記のように深層型のニューラルネットワークにおいて、入力層に近づくにつれ、重みがあまり更新されないという問題がありました。これがいわゆる勾配消失問題といいます。

しかし、2006 Hinton らのDBN[1]の提案をきっかけに、再びAIブームが到来し、様々な研究がされるようになりました。その過程でReLUを隠れ層の活性化関数として活用することで勾配消失問題を解決できることが分かり、以来、多くの研究においてReLUやその派生系が使われるようになりました。ReLUとは入力 x とした時、 y=\max(x,0) を出力する関数であり、 \partial y/\partial x が一定値(入力時に異なる値)となる関数です。この関数を用いることにより、従来のニューラルネットワークの学習を大きく改善することができました。

まとめ

本チュートリアルでは、4層以上になると、入力層付近の重みの経路が増えるが、経路ごとにチェインルールを適用し、それぞれの和を算出すれば計算できると説明しました。しかし、深層(4層以上)にすると入力層が付近の重みが更新しにくくなり、勾配消失問題という問題が生じます。それに対して、現在は活性化関数としてReLUを使用することで解決できることがわかりました。

ちなみに本チュートリアルでは詳細の記述はしていませんが、上記の算出をより早くするために計算グラフを用いります。より具体的にどのように演算しているかについてはこちらについて調べてもいいかもしれません。

[1] Hinton, G. E.; Osindero, S.; Teh, Y. W. (2006). "A Fast Learning Algorithm for Deep Belief Nets" Neural Computation. 18 (7): 1527–1554.