stMind

about Arsenal, Arsene Wenger, Tech, Computer vision and Machine learning

誤差逆伝播法と最急降下法の数式を追いかける

誤差逆伝播法は「でんぱん」ではなくて「でんぱ」だとDeep Learning勉強会のUstで気づきました。

わかりやすいパターン認識

わかりやすいパターン認識

わかりやすいパターン認識を参考に誤差逆伝播法と最急降下法について数式を追いかけて理解したいと思います。

誤差逆伝播

誤差逆伝播法(Backpropagation:BP)は、多層ニューラルネットワークで使われる教師あり学習アルゴリズムです。
正解との誤差を出力層に近い層から入力層へと遡って伝播させていくことで、ネットワーク全体の重みを学習することが出来ます。

1. ネットワーク

最初に、想定するNNと記号を対応付けしておきます。ここでは、隣接する3つの層を考え、入力に近い層からi, j, kで表します。3層のNNであれば、iが入力層、jが隠れ層、kが出力層となるような構成です。また、iからjへの結合の重みを w_{ij}、jからkへの結合の重みを w_{jk}として表すこととします。

このとき、 p番目のパターン x_pを入力とした時、ユニット iからの出力を g_{ip}、ユニット jへの入力を h_{jp}とすると、

 {\displaystyle
(3.46) \ \ \ \ \ \ \ \ \ \  h_{jp} = \sum_{i} w_{ij} g_{ip}
}

さらに、ユニット jからの出力を非線形関数 f_jを用いて、

 {\displaystyle
(3.47) \ \ \ \ \ \ \ \ \ \  g_{jp} = f_j (h_{jp})
}

と表すこととします。

2. 誤差関数 J

誤差関数ですが、ここでは二乗誤差を使っています。

{ \displaystyle
(3.48) \ \ \ \ \ \ \ \ \ \  J_p = \frac{1}{2} \sum_{l}(g_{lp}-b_{lp})^{2}
}

{ \displaystyle b_{lp}}は教師データとなる正解値、{ \displaystyle g_{lp} }は出力値です。 ここで、{ \displaystyle l}は出力層のユニットを表すインデックスです。

3. 誤差の逆伝播と最急降下法

この誤差を小さくするように各層の重みを更新していくことが、すなわち学習フェーズで行っていることになります。このとき、誤差が最小となる重みを求める方法が最急降下法です。

2.1 最急降下法で重みの計算

最急降下法を用いた重みの更新は

 {\displaystyle
(3.54) \ \ \ \ \ \ \ \ \ \  w_{ij}' = w_{ij} - \rho \frac{\partial J_p}{\partial w_{ij}}
}

と求められます( { \rho }は学習率を表す)。
また、勾配はチェインルールを用いて、次のように計算できます。

 { \displaystyle
(3.50) \ \ \ \ \ \  \frac{\partial J_p}{\partial w_{ij}} = \frac{\partial J_p}{\partial h_{jp}}
\frac{\partial h_{jp}}{\partial w_{ij}}
}

右辺の第一項を \varepsilon_{jp}で表すことにすると、

 {\displaystyle
(3.51) \ \ \ \ \ \ \ \ \ \  \varepsilon_{jp} = \frac{\partial J_p}{\partial h_{jp}}
}

第二項は(3.46)を代入して、さらに偏微分で残るのは iの時だけなので、

 {\displaystyle
(3.52) \ \ \ \  \frac{\partial h_{jp}}{\partial w_{ij}} = \frac{\partial \sum_{i} w_{ij} g_{ip}}
{\partial w_{ij}} \\
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  = \sum_i \frac{\partial w_{ij} g_{ip}}{\partial w_{ij}} \\
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  = g_{ip}
}

として求められます。 ということで、(3.54)に代入すると、

 {\displaystyle
(3.55) \ \ \ \ \ \ \ \  w_{ij}' = w_{ij} - \rho \varepsilon_{jp} g_{ip}
}

を得ることが出来ます。

2.2 個々のユニットに対する \varepsilonの計算

同じようにチェインルールを使って計算をしていくことが出来ます。

 {\displaystyle
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  \varepsilon_{jp} = \frac{\partial J_p}{\partial h_{jp}} \\
(3.56) \ \ \ \ \ \ \ \ \ \ \  = \frac{\partial J_p}{\partial g_{jp}} \frac{\partial g_{jp}}{\partial h_{jp}} \\
(3.57) \ \ \ \ \ \ \ \ \ \ \  = \frac{\partial J_p}{\partial g_{jp}} f_j' (h_{jp})
}

第一項の計算ですが、ユニットjが出力層かもしくは隠れ層かによって異なって、出力層にある場合は、

 {\displaystyle
(3.59) \ \ \ \  \frac{\partial J_{p}}{\partial g_{jp}} = \frac{\partial \frac{1}{2} \sum_l (g_{lp} - b_{lp})^{2}}{\partial g_{jp}} = g_{jp} - b_{jp}
}

一方で中間層にある場合は、

 {\displaystyle
(3.60) \ \ \ \  \frac{\partial J_{p}}{\partial g_{jp}} = \sum_k \frac{\partial J_p}{\partial h_{kp}} \frac{\partial h_{kp}}{\partial g_{jp}}
}

さらに、第一項と第二項は

 {\displaystyle
(3.61) \ \ \ \ \ \  \frac{\partial J_p}{\partial h_{kp}} = \varepsilon_{kp}
}

 {\displaystyle
(3.63) \ \ \ \  \frac{\partial h_{kp}}{\partial g_{jp}} = \frac{\partial \sum_j w_{jk} g_{jp}}{\partial g_{jp}} = w_{jp}
}

結局、中間層の時の計算は以下のように得ることが出来ます。

 {\displaystyle
(3.64) \ \ \ \  \frac{\partial J_{p}}{\partial g_{jp}} = \sum_k \varepsilon_{kp} w_{jk}
}

2.3 非線形関数 f_jの計算

最後に、非線形関数 f_jを求めます。ここでは、非線形関数としてシグモイド関数を考えます。

 {
(3.65) \ \ \ \  S(u) = \frac{1}{1 + \exp (-u)}
}

 { \displaystyle
(3.66)  \ \ \ \  S'(u) = \frac{dS}{du} \\
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  = \frac{d}{du} (1 + \mathrm{e}^{-u})^{-1} \\
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  = -1 (1 + \mathrm{e}^{-u})^{-2} \frac{d \mathrm{e}^{-u}}{du} \\
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  = -1 (1 + \mathrm{e}^{-u})^{-2}  (- \mathrm{e}^{-u} ) \\
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  = \frac{ \mathrm{e}^{-u} }{ (1 + \mathrm{e}^{-u})^{2}  } \\
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  = \frac{ 1 + \mathrm{e}^{-u} - 1 }{ (1 + \mathrm{e}^{-u})^{2}  } \\
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  = \frac{1}{1 + \mathrm{e}^{-u}} (1 - \frac{1}{1 + \mathrm{e}^{-u}}) \\
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  = S(u) (1 - S(u))
}

ということで、 f_jシグモイド関数 Sとすると、

 { \displaystyle
(3.67)  \ \ \ \  f_j'(h_{jp}) = f_j(h_{jp}) (1 - f_j(h_{jp})) = g_{jp} (1 - g_{jp})
}

2.4 最終的な重みの更新式

最急降下法による重みの更新は、

jが出力層の時は、

 {\displaystyle
(3.68) \ \ \ \ \ \ \ \  w_{ij}' = w_{ij} - \rho (g_{jp} - b_{jp}) g_{jp}(1-g_{jp}) g_{ip}
}

jが隠れ層の時は、

 {\displaystyle
(3.68) \ \ \ \ \ \ \ \  w_{ij}' = w_{ij} - \rho \left( \sum_k \varepsilon_{kp} w_{jk} \right) g_{jp}(1-g_{jp}) g_{ip}
}

となります。

終わりに

Pythonで実装して確認しようと思いましたが、式を追いかけるので疲れてしまった...
次回試してみようと思います。