ニューラルネットワーク(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$を求める