技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

ニューラルネットワーク各階層の勾配計算式

勾配計算式

 w を重み、 b をバイアス、 E を誤差(損失関数出力)とするとこんな形状で定式化されてる。
この辺はいくつかの書籍見て、ようやっと飲み込めた感じ…。

数式を飲み込むのにはそれなりに時間を要したけど…。

  • 出力層

\delta_k = \frac{\partial E}{\partial u_k} = \frac{\partial E}{\partial y_k} \frac{\partial y_k}{\partial u_k} \\
\partial w_{jk} = \frac{\partial E}{\partial w_{jk}} = y_j \delta_k (重み勾配) \\
\partial b_k = \frac{\partial E}{\partial b_k} = \delta_k (バイアス勾配) \\
\partial y_j = \frac{\partial E}{\partial y_j} = \sum^n_{r=1} \delta_r w_{jr} (一つ上の層の出力勾配)
  • 中間層

\delta_j = \frac{\partial E}{\partial u_j} = \partial y_j \frac{\partial y_k}{\partial u_j} \\
\partial w_{ij} = \frac{\partial E}{\partial w_{ij}} = y_i \delta_j (重み勾配) \\
\partial b_j = \frac{\partial E}{\partial b_j} = \delta_j (バイアス勾配) \\
\partial y_i = \frac{\partial E}{\partial y_i} = \sum^m_{q=1} \delta_q w_{iq} (一つ上の層の出力勾配)

結局のところ、 \delta_n さえ算出できれば、残りの計算式は芋づるで計算できることになる。

求めた過程

原則的に、ニューロン(出力層含む)の作りは、入力  y と重み  w_{jk} + バイアス  b_k によるもので


u_k = y_j w_{jk} + b_k \\
y_k = f(u_k)

でできてる。
出力層に至ってはここに損失関数を食わせて  E (理想値との誤差)を取得する。
この時、勾配降下法を用いるなら、それら式を微分して、勾配を求めていくことになる。

ニューロンが学習するべき値は  w b で、これらは行列なので偏微分でひとつづつ誤差への影響を求めていくことになる。


  \partial w_{jk} = \frac{\partial E}{\partial w_{jk}}  \\
  = \frac{\partial E}{\partial u_k} \frac{\partial u_k}{\partial w_{jk}} ...(※)

※連鎖律を適用。連鎖律については ここ 参照

 \frac{\partial u_k}{\partial w_{jk}}  u_k を展開すると


\frac{\partial u_k}{\partial w_{jk}} = \frac{\partial (\sum^m_{q=1} y_q w_{qk} + b_k) }{\partial w_{jk}} \\
= \frac{\partial}{\partial w_{jk}} (y_1 w_{1k} + y_2 w_{2k} ... y_j w_{jk} ... + y_m w_mk + b_k)

偏微分なので、  w_{jk} のかかってない項はすべて 0 なので、


\frac{\partial u_k}{\partial w_{jk}} = \frac{\partial}{\partial w_{jk}} (y_1 w_{1k} + y_2 w_{2k} ... y_j w_{jk} ... + y_m w_mk + b_k)
= y_j

次に  \frac{\partial E}{\partial u_k} に焦点を当てて、こちらも連鎖律で展開して、


\frac{\partial E}{\partial u_k} = \frac{\partial E}{\partial y_k} \frac{\partial y_k}{\partial u_k}

これを  \delta_k とすると


\delta_k = \frac{\partial E}{\partial y_k} \frac{\partial y_k}{\partial u_k} \\
\partial w_{jk} = y_j \delta_k

という形に持っていける。

 \partial b_k も同様の手順で考えると


\partial b_k = \frac{\partial E}{\partial b_k} = \frac{\partial E}{\partial u_k} \frac{\partial u_k}{\partial b_k}

 u_k を展開すると、偏微分したときに  b_k の1項しか残らず、最終的に 1 になるので、最終形態は


\partial b_k = \delta_k

中間層出力の勾配も考えると、


\partial y_j = \frac{\partial E}{\partial y_j} = \sum^n_{r=i} \frac{\partial E}{\partial u_r} \frac{\partial u_r}{\partial y_j}

このうち、


\frac{\partial u_r}{\partial y_j} = \frac{\partial (\sum^m_{q=1}) y_q w_{qr} + b_r}{\partial y_j} \\
= \frac{\partial}{\partial y_j} (y_1 w_{1r} + y_2 w_{2r} + ... y_j w_{jr} + ... + y_m w_{wr} + b_r)  \\
= w_{jr}  (y_j の偏微分なので、y_j を含まない項はすべて 0 になる)

ここで  \delta_r = \frac{\partial E}{\partial u_r} とすれば


\partial y_j = \sum^n_{r=1} \delta_r w_{jr}

中間層の重み勾配を考えると、


\partial w_{ij} = \frac{\partial E}{\partial w_{ij}} = \frac{\partial E}{\partial u_j} \frac{\partial u_j}{\partial w_{ij}}

このうち  \frac{\partial u_j}{\partial e_{ij}}


\frac{\partial u_j}{\partial w_{ij}} = \frac{\partial (\sum^l_{p=1} y_p w_{pj} + b_j)}{\partial w_{ij}} \\
  = y_i (展開して偏微分するとこうなる)

もう一つ  \frac{\partial E}{\partial u_j} 部分は連鎖律使って


\frac{\partial E}{\partial u_j} = \frac{\partial E}{\partial y_j} \frac{\partial y_j}{\partial u_j}

このうち  \frac{\partial y_j}{\partial u_j} は活性関数の微分
 \frac{\partial E}{\partial y_j} は中間層出力の勾配(=  \partial y_j )。


\delta_j = \frac{\partial E}{\partial u_j} = \partial y_j \frac{\partial y_j}{\partial u_j}

と、なるほど。中間層出力の勾配を受け取って、中間層が計算できる → 下層からの結果を受け取る → 逆伝播の原理 というわけですね

 \frac{\partial u_j}{\partial w_{ij}} = y_i

を使うと  \partial w_{ij} = y_i \delta_j

バイアス勾配  \partial b_j


\partial b_j = \frac{\partial E}{\partial b_j} = \frac{\partial E}{\partial u_j} \frac{\partial u_j}{\partial b_j}

このうち


\frac{\partial u_j}{\partial b_j} = \frac{\partial (\sum^l_{p=1} y_p w_{pj} + b_j )}{\partial b_j} \\
  = 1 (※)

偏微分なので、 b_j 以外の全ての項は 0 になり、残った  b_j 微分されるため。

そのため

 \partial b_j = \delta_j

こんなノリで上の層に伝播を続けていく。

ニューラルネットに実際に適用して考える

損失関数を二乗誤差、活性関数を恒等関数とした出力層の場合


\delta_k = \frac{\partial E}{\partial u_k} = \frac{\partial E}{\partial y_k} \frac{\partial y_k}{\partial u_k}

を求めたい。
二乗誤差関数は


\frac{1}{2} \sum_k ( y_k - t_k )^2

なので、


\frac{\partial E}{\partial y_k} = \frac{\partial}{\partial y_k} (\frac{1}{2} \sum_k(y_k - t_k)^2) \\
   =  \frac{\partial}{\partial y_k} (\frac{1}{2}(y_0 - t_0)^2 + \frac{1}{2}(y_1 - t_1)^2 + ... \frac{1}{2}(y_n - t_n)^2) \\
   = y_k - t_k (※)

偏微分につき、 y_k を含まない項はすべて 0 となるため。

隣の項は 活性関数が恒等関数(入力 = 出力)の関数なので、


\frac{\partial y_k}{\partial u_k} = 1

なので


\delta_k = (y_k - t_k) 1 = y_k - t_k

中間層がシグモイド関数であるとした場合

シグモイド関数  f(x) = \frac{ 1 }{1 + exp(-x)} 微分 f'(x) = (1-f(x))f(x) なので


\frac{\partial y_k}{\partial u_j} = (1 - y_j)y_j \\
\delta_j = \partial y_j \frac{\partial y_k}{\partial u_j} = \partial y_j (1 - y_j)y_j

交差エントロピー誤差とソフトマックス関数を採用した出力層

これは分類で使う組み合わせ。

交差エントロピー誤差

こちらの記事 が丁寧に書いてくれています。

数式的にはこんな関数


E(t,y) = - \sum_x t_x log(y_x)

理想の出力  t は、スイッチ出力なので [1, 0, 0, 0] の様な一つだけ 1 となってるので、仮に入力値を [0.5, 0.8, 0.2, 0.4] だとすると


E(t,y) = - (1 log(0.5) + 0 log(0.8) + 0 log(0.2) + 0 log(0.4) \\
  = -log(0.5) \\
  = -(-0.693...) \\
  = 0.693

こんな感じで出てくる。

ソフトマックス関数

過去記事 参照(グラフ付き)。


y = \frac{exp(x)}{\sum^n_{k=1} exp(k)}

こんな感じの関数を組み合わせすると


E = - \sum_k t_k log( \frac{exp(u_k)}{ \sum_k exp(u_k) } )

この時、  log \frac{p}{q} = log(p) - log(q) を使うと


  = - \sum_k ( t_k log(exp(u_k)) - t_k log(\sum_k exp(u_k)) ) \\
  = なんやかんやあって \\
  = - \sum_k t_k u_k + log(\sum_k exp(u_k))

これを更新式に突っ込むと


\delta_k = \frac{\partial E}{\partial y_k} \frac{\partial y_k}{\partial u_k} \\
= \frac{\partial}{\partial u_k} (- \sum_k t_k u_k + log(\sum_k exp(u_k))) \\
= -t_k + \frac{exp(u_k)}{\sum_k exp(u_k)} \\
= -t_k + y_k

ようやっと…微分オワタ (;'∀')