coursera 機械学習 5週目
Nov 19, 2017ニューラルネットワーク(Neural Network)のコスト関数
ロジスティック回帰のコスト関数は下記のように定義された。
$$
J(\theta) = - \frac{1}{m} \sum_{i=1}^m \large[ y^{(i)}\ \log (h_\theta (x^{(i)})) + (1 - y^{(i)})\ \log (1 - h_\theta(x^{(i)}))\large] + \frac{\lambda}{2m}\sum_{j=1}^n \theta_j^2 \\
$$
ニューラルネットワークのコスト関数は下記のように定義される。
$$
J(\Theta) = - \frac{1}{m} \large[ \sum_{i=1}^m \sum_{k=1}^K y_{k}^{(i)} \log (h_\theta (x^{(i)}))_k + (1 - y^{(i)})\ \log (1 - (h_\theta(x^{(i)}))_k) \large] + \frac{\lambda}{2m} \sum_{l=1}^{L-1} \sum_{i=1}^{s_l}\sum_{j=1}^{s_l + 1}(\Theta_{ji}^{(l)})^2 \\
L: レイア数 \\
s_l: l層におけるユニット数
$$
バックプロパゲーション(Backpropagation)
次に、線形回帰やロジスティック回帰と同様に、コスト関数を最小化することを考える。
これは、以下のように各レイアの重み$\Theta$の各要素で$J(\Theta)$を偏微分したもので表される。
$$ \dfrac{\partial}{\partial \Theta_{i,j}^{(l)}}J(\Theta) $$
この偏微分を実行するために、バックプロパゲーション(Backpropagation)というアルゴリズムがある。
バックプロパゲーション(Backpropagation)の手順は下記のとおり。
- $\Delta_{ij}^{(l)} = 0$で初期化(全てのi,j,l)
- レイア1の$a^{(1)}$を$a^{(1)} = x^{(i)}$とする($x^{(i)}$は入力値)
- フォアワードプロパゲーション(Forwardpropagation)で$a^{(l)} = g(z^{(l)}) = g(\Theta^{(l-1)}a^{(l-1)})$を求める
- L層の誤差、$\sigma^{(L)} = a^{(L)} - y^{(t)}$を求める
- L層より前の各レイアの誤差、$\sigma^{(l)} = ((\Theta^{(l)})^{\mathrm{ T }} \sigma^{(l+1)}) .* a^{(l)} .* (1 - a^{(l)})$
- $a^{(l)} .* (1 - a^{(l)}$ は $g(z^{(l)})$を微分した値なので$g’(z^{(l)}) = a^{(l)} .* (1 - a^{(l)}$
- 偏微分値の更新$\Delta_(ij)^{(l)} := \Delta_(ij)^{(l)} + a_{j}^{l}\delta_{i}^{l+1}$
最終的な偏微分の値は、$\Delta$の平均をとって正則したもので、下記のようになる。
$$
\begin{cases}
D^{(l)}_{i,j} := \dfrac{1}{m}\left(\Delta^{(l)}_{i,j} + \lambda\Theta^{(l)}_{i,j}\right) & (j \ge 1) \\
D^{(l)}_{i,j} := \dfrac{1}{m}\Delta^{(l)}_{i,j} & (j = 1)
\end{cases}
$$
$$
D^{(l)}_{i,j} := \dfrac{1}{m}\left(\Delta^{(l)}_{i,j} + \lambda\Theta^{(l)}_{i,j}\right) (j \ge 1) \\
$$
Gradient checking
コスト関数$J(\Theta)$の偏微分の近似値と、バックプロパゲーション(Backpropagation)で求めた偏微分の値との比較を行うことで、バックプロパゲーション(Backpropagation)が機能しているか調べることができる。
$$ gradApprox = \frac {J(\Theta + \epsilon) - J(\Theta - \epsilon)} {2\epsilon} \approx \dfrac{\partial}{\partial \Theta_{i,j}^{(l)}}J(\Theta) $$
Gradient checkingは遅いから、プログラムの検証が終わったら、チェックアルゴリズムは切ること。
ランダム初期化(Random initialization)
線形回帰やロジスティクス回帰や$\Theta$を$0$を使って初期化したが、ニューラルネットワークでは機能しない。
$0$で初期化された$\Theta$をニューラルネットワークで利用すると、バックプロパゲーションすると、全てのノードで同じ値に更新されてしまう。
この問題を解決するために、ランダムな値で初期化した$\Theta$を生成し、利用する。
初期化に使われるランダムな値は $[-\epsilon,\epsilon]$ の間の値で生成し、$\Theta$は下記の式を使って初期化する。
Theta1 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta2 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta3 = rand(1,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
まとめ
最初に隠れ層のユニット数、出力層のユニット数等のニューラルネットワークのレイアウトを選択する。
- 入力ユニットの数 = 説明変数$x^(i)$の次元
- 出力ユニットの数 = 分類するクラスの数
- 隠れ層のユニットの数 = 多ければ多いほど良いが、計算量が多くなるため、バランスを取るため入力ユニット数と同程度〜4倍程度まで
- 隠れ層の数は最初はは1つで、結果を見て多くしていく。複数の隠れ層がある場合は、全ての隠れ層は同じユニット数となることがオススメ
ニューラルネットワークを実装方法する
- ランダムなk値で重み$\Theta$を初期化する
- フォワードプロパゲーション(Fowardpropagation)を実装して、入力$x^{(i)}$に対する出力$h_{\Theta}(x^{(i)})$を求める
- コスト関数を実装して$J(\Theta)$を求める
- バックプロパゲーション(Backpropagation)を実装してコスト関数の偏微分$\frac{\delta}{\delta\Theta_{jk}^{(l)}}$を計算する
- Gradient checkingを使ってコスト関数$J(\Theta)$の偏微分の近似値を求め、バックプロパゲーション(Backpropagation)を使って求めたコスト関数の偏微分$\frac{\delta}{\delta\Theta_{jk}^{(l)}}$との比較を行い、バックプロパゲーション(Backpropagation)が機能していることを確認する
- 確認できたらGradient checkingを切る
- 再急降下法などの勾配法を使って、コスト関数$J(\Theta)$を最小化する重み$\Theta$を求める