ニューラルネットワークのコスト関数とバックプロパゲーション


最近数学をやり直していてふと機械学習がどういう仕組みなのか知りたくなって、Courseraでスタンフォード大学が提供している機械学習講座を受けている。第6週まで終わったので思い出しながら軽くまとめる。講座はこちら Coursera Machine Learning

week1 機械学習とは何か、単線形回帰、仮説関数、コスト関数、最急降下法
week2 重線形回帰、スケーリング、多項式回帰、正規方程式
week3 ロジスティック回帰、共役勾配法・BFGS・L-BFGS、多クラス分類 、過学習と正則化
week4 ニューラルネットワークの基礎
week5 ニューラルネットワークのコスト関数とバックプロパゲーション
week6 機械学習のモデルの評価 - 交差検証、バイアスとバリアンス、学習曲線、適合率と再現率

Week 5 ニューラルネットワークのコスト関数とバックプロパゲーション

ニューラルネットワークのパラメータをフィッティングするにはどうするか。いつもと同じようにコスト関数から入る。

コスト関数

ニューラルネットワークはロジスティック回帰が連なったものなので、ロジスティック回帰のコスト関数を思い出すと直感的にイメージしやすい。

  • ロジスティック回帰のコスト関数
J(\theta)=−\frac{1}{m}\sum_{i=1}^{m}[y^{(i)}\log(h_\theta(x^{(i)}))+(1−y^{
(i)})\log(1−h_\theta(x^{(i)}))]+\frac{\lambda}{2m}\sum_{j=1}^{n}\theta_j^2​ 
  • ニューラルネットワークのコスト関数
    • $L=$ レイヤーの合計
    • $s_l=$ $l$レイヤーのユニット数
    • $K=$ 出力のユニット数
J(\Theta)=−\frac{1}{m}\sum_{i=1}^{m}\sum_{k=1}^{k}[y^{(i)}_k\log((h_\Theta(x^{(i)}))_k)+(1−y^{
(i)}_k)\log((1−h_\Theta(x^{(i)}))_k)]+\frac{\lambda}{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{s_l}\sum_{j=1}^{s_l+1}(\Theta_{j,i}^{(l)}​)^2

バックプロパゲーション - Backpropagation

いつものように$J(\Theta)$を最小化するような$\Theta$を求めたいので、$J(\Theta)$の偏導関数を計算する。

$$
\frac{\partial}{\partial\Theta_{i,j}^{(l)}}J(\Theta)
$$

計算するためにバックプロパゲーションというアルゴリズムを使用する。

まず$\{(x^{(1)},y^{(1)})⋯(x^{(m)},y^{(m)})\}$のようなm個のトレーニングセットを考える。

$\Delta_{i,j}^{(l)}:=0$とする。

step 1: $a^{(1)}:=x^{(t)}$

入力層の活性化ユニット$a^{(1)}$に対して$x^{(t)}$をセットする。

step 2: フォワードプロパゲーションを適用して$a^{(l)}$を計算する。レイヤー2,3...と最後のレイヤーまで。

step 3: トレーニングセットの出力$y^{(t)}$を使って、$\delta^{(L)}=a^{(L)}−y^{(t)}$、つまり誤差を計算する。

この時、$L$はレイヤーの合計で、$a^{(L)}$は最後のレイヤーの活性化ユニットの出力のベクトルである。そのため、最後のレイヤーの誤差は、単に最後のレイヤーの仮説が出力した値とトレーニングセット$y$の値の差でしかない。最後のレイヤーよりも前にあるレイヤーの$\delta$を取得するには、右から左に戻る。このことから誤差を右から左に伝播させるという意味でバックプロパゲーションと呼ばれる。

step 4: $\delta^{(l)}=((\Theta^{(l)})^T\delta^{(l+1)})\hspace{2pt}.∗\hspace{2pt}a^{(l)}\hspace{2pt}.∗\hspace{2pt}(1−a^{(l)})$を使って、それぞれの誤差である$\delta^{(L-1)}, \delta^{(L-2)},\dots,\delta^{(2)}$を計算する。$\delta^{(1)}$を計算しないのはレイヤー1は入力層のため誤差が存在しないから。

レイヤー$l$の$\delta$は、次のレイヤーの$\delta$にレイヤー$l$の$\Theta$行列を掛けることによって計算される。次に、$g'$関数を要素ごとに掛ける。これは入力$z^{(l)}$の活性化関数$g$の導関数である。$g'(z^{(l)})=a^{(l)}\hspace{2pt}.∗\hspace{2pt}(1−a^{(l)})$

step 5: $\Delta_{i,j}^{(l)}:=\Delta_{i,j}^{(l)}+a_j^{(l)}\delta_i^{(l+1)}$ もしくはベクトル化した $\Delta^{(l)} := \Delta^{(l)} + \delta^{(l+1)}(a^{(l)})^T$で$\Delta$行列をアップデートする。

\begin{align}
D_{i,j}^{(l)}&:=\frac{1}{m}(\Delta_{i,j}^{(l)}+\lambda\Theta^{(l)}_{i,j})\hspace{4pt},if\hspace{4pt}j≠0\\
D_{i,j}^{(l)}&:=\dfrac{1}{m}\Delta_{i,j}^{(l)}\hspace{4pt},if\hspace{4pt}j=0
\end{align}

最終的に以下となる。

$$
\frac{\partial}{\partial\Theta_{i,j}^{(l)}}J(\Theta)=D_{i,j}^{(l)}
$$