読者です 読者をやめる 読者になる 読者になる

Keras(Tensorflow)でMNIST

KerasでMNIST手書き文字分類問題を試した。

実行環境

Python 3.6.0
Keras 1.2.2
Tensorflow 1.0.1
GeForce 780Ti

コード

ライブラリのインポート
import numpy as np
np.random.seed(123)

from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.utils import np_utils
MNISTデータセットのロード
from keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()

データセットの画像を表示

import matplotlib.pyplot as plt
plt.imshow(X_train[1])

f:id:yusuke_ujitoko:20170319194818p:plain

データを事前処理
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1)
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1)

X_train = X_train.astype('float32')
X_test = X_test.astype('float32')

X_train /= 255
X_test /= 255

ラベルのデータ構造変更

Y_train = np_utils.to_categorical(y_train, 10)
Y_test = np_utils.to_categorical(y_test, 10)
ネットワークを定義
model = Sequential()
model.add(Convolution2D(32, 3, 3, activation='relu', input_shape = (28, 28, 1)))
model.add(Convolution2D(32, 3, 3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

誤差関数、勾配法を定義する。

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
訓練
history = model.fit(X_train, Y_train, batch_size=32, nb_epoch=10, verbose=1)
評価
score = model.evaluate(X_test, Y_test, verbose=0)
print(score)

Accuracyの可視化

fig = plt.figure()
plt.plot(history.history['acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.xlim(0, 10)
plt.savefig('acc.png')

f:id:yusuke_ujitoko:20170319214321p:plain

Lossの可視化

fig = plt.figure()
plt.plot(history.history['loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.xlim(0, 10)
plt.savefig('loss.png')

f:id:yusuke_ujitoko:20170319214313p:plain

モデルの可視化

可視化のための事前準備として、graphvizとpydot_ngをインストール

apt-get install graphviz
pip install pydot_ng
from keras.utils.visualize_util import plot
plot(model, to_file='model.png')

f:id:yusuke_ujitoko:20170319202758p:plain

参考

CUDA 8.0とcuDNN 5.1をUbuntu 16.04にインストールする

CUDA Toolkit 8.0のインストール

GPUが認識されてるか事前にチェック

lspci | grep -i nvidia

CUDA ToolkitからCUDA Toolkit 8.0を導入する。
CUDA Toolkitを以下のようにインストールする。

sudo dpkg -i cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
sudo apt update
sudo apt install cuda

PATHの設定

~/.bashrcにパスを書き込んでおく。

# PATHとLD_LIBRARY_PATHに追加
echo 'export PATH=/usr/local/cuda-8.0/bin:${PATH}' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64:${LD_LIBRARY_PATH}' >> ~/.bashrc

# .bashrcの読み込み
source ~/.bashrc 

パスの確認

echo $PATH             # 上記設定の反映を確認
echo $LD_LIBRARY_PATH  # 
which nvcc             # nvccのパス表示
nvidia-smi             # GPUの情報表示

cuDNN v5.1のインストール

cuDNNをダウンロードする。
ダウンロードしたら解凍して、cuDNNのライブラリをCUDAのディレクトリにコピー。

tar xzvf cudnn-8.0-linux-x64-v5.1.tgz 
sudo cp -a cuda/lib64/* /usr/local/cuda-8.0/lib64/
sudo cp -a cuda/include/* /usr/local/cuda-8.0/include/
sudo ldconfig

Python機械学習プログラミングを読んで覚えておきたいと思ったこと

機械学習 読書メモ

1章 「データから学習する能力」をコンピュータに与える

クラスタリングとクラス分類の違い

2章 分類問題 機械学習アルゴリズムのトレーニング

なぜコスト関数を使うのか?

単位ステップ関数ではなく、コスト関数を導入する理由は、コスト関数が微分可能であるから。 コスト関数の別の利点は、凸関数であることである。 これらの特徴から勾配降下法が使える。

3章 分類問題 機械学習ライブラリscikit-learnの活用

ノーフリーランチ定理(no free lunch theorem)とは?

David H. WolpertとWilliam G. Macreadyが、組み合わせ最適化の全ての問題に対して最良な最適化方法は存在しないことを主張した定理。
機械学習では、データの分布などに関する事前知識がなければ、どの問題に対しても最良のアルゴリズムが存在しないという意味で使われる。

条件付き確率(conditional probability)とは?

条件が与えられたときに、事象が生じる確率(=事後確率)。
ここでは、条件として特徴量{x}が与えられているときに、クラスラベルが{y}となる事象の条件付き確率を{p(y | x)}と表記している。
クラスラベルが特定の値となるときの条件付き確率は、{p(y=1 | x)}のようにクラスラベルの値を明示している。

ロジスティック回帰の直観的知識

事象の起こりやすさを示す、オッズ比(odds ratio)は{\frac{p}{1-p}}と表せる。
ロジット関数を次のように定義してみる。 {} $$ logit(p) = log \frac{p}{1-p} $$

ロジット関数は0より大きく1より小さい範囲の入力値を受取り、実数の全範囲に変換する。
この関数を用いて、特徴量の値と対数オッズの関係を表せる。 {} $$ logit(P(y=1|x)) = w_0 x_0 + w_1 x_1 + \ldots + w_m x_m = \sum_{i=0}^{m} w_i x_i = w^T x $$

ここで左辺の{p(y=1|x)}は特徴量xが与えられた場合にサンプルが分類クラス1に属するという条件付き確率である。
さて、私たちの関心があるのは、サンプルが特定のクラスに属している確率を予測することであるので、ロジット関数の逆関数をとる。
これがロジスティック関数である。シグモイド関数とも呼ばれる。
{} $$ \phi(z) = \frac{1}{1 + e^{-z}} $$ $$ z = w^T x $$

なおロジスティック回帰は、線形分類問題と二値分類問題に対する単純ながら強力なアルゴリズムであり、その名前と裏腹に、回帰ではなく分類のためのモデルである。

今後は{y=0,1}の二値分類問題という前提で進める。
さて、{y=0}のときの条件付き確率と{y=1}のときの条件付き確率は次のように表せる。
{} $$ \begin{array}{} P(y=1|x;w) = \phi(z) \\ P(y=0|x;w) = 1- \phi(z) \end{array} $$ 上式をまとめることができる。 {} $$ P(y|x;w) = (\phi(z))^{y} (1 - \phi(z))^{1 - y} $$

上のまとめ方は、{y}の取りうる値が0か1しかないことを利用している。
各サンプルについての条件付き確率を掛け合わせて尤度関数を次のように定義できる。 {} $$ L(w) = P(y^{(i)}|x^{(i)};w) = \prod_{i=1}^n (\phi(z^{(i)}))^{y^{(i)}} (1 - \phi(z^{(i)}))^{1 - y^{(i)}} $$

扱いやすいようにこの式の対数をとる。 {} $$ l(w) = log L(w) = \sum_{i=1}^n y^{(i)} log(\phi(z^{(i)})) + (1 - y^{(i)}) log (1 - \phi(z^{(i)})) $$

さらに全体をマイナス化して、最小値問題とする。 {} $$ J(w) = \sum_{i=1}^n - y^{(i)} log(\phi(z^{(i)})) - (1 - y^{(i)}) log (1 - \phi(z^{(i)})) $$

SVMの直観的知識

SVM(Support Vector Machine)は広く利用されている学習アルゴリズム
SVMの最適化の目的は、マージンを最大化すること。
マージンは、超平面(決定境界)と、この超平面に最も近いトレーニングサンプルとの間の距離として定義される。
超平面に最も近いトレーニングサンプルはサポートベクトル(support vector)と呼ばれる。

決定境界に沿った正と負の超平面を詳しく見る。
これらの超平面は下記のように表せる。
{} $$ w_0 + w^T x_{pos} = 1 \\ w_0 + w^T x_{neg} = -1 $$ これらの式を引き算する。 {} $$ w^T (x_{pos} - x_{neg}) = 2 \\ $$ この式を重み{w}の大きさで割った式を考える。 {} $$ \frac{w^T (x_{pos} - x_{neg})}{||w||} = \frac{2}{||w||} \\ $$ この式の左辺は、正の超平面と負の超平面の距離とみなせる。
したがって、この距離を最大化することをめざす。
ただし問題を変換して、{\frac{1}{2} ||w||^2}を最小化する問題と置き換える。

さらに、スラック変数{\xi}を導入して、線形制約を緩和することを考える。
緩和された制約は下記のようになる。
{} $$ \begin{array}{} w^T x^{(i)} \geq 1 - \xi^{(i)} & (y^{(i)} = 1) \\ w^T x^{(i)} < -1 + \xi^{(i)} & (y^{(i)} = -1) \end{array} $$

このとき、最初化すべき式は下記のように変更される。 {} $$ \frac{1}{2} ||w||^2 + C (\sum_{i} \xi^{(i)} ) $$ あとは変数Cを使ってご分類のペナルティを制御する。 Cが大きいときは、ご分類のペナルティが大きいことを意味し、Cの値が小さいときはご分類に対して寛大であることを意味する。

カーネルSVMの利用

線形分離できないデータを処理するカーネル手法というものがある。 基本的な発想は、射影関数 {\phi}を使ってそれらの組み合わせを高次元空間へ射影し、線形分離できるようにすることである。

決定木学習

決定木モデルでは、トレーニングデータセットの特徴量に基づいて一連の質問を学習し、サンプルのクラスラベルを推測する。
決定木では、情報利得(information gain)が最大となる特徴量でデータを分割する。
その際の目的関数は以下のように定義される。

{} $$ IG(D_p, f) = I(D_p) - \sum \frac{N_j}{N_p} I(D_j) $$

ここで、{f}は分割を行う特徴量。{D_p}は親のデータセット{D_j}はj番目の子ノードのデータセット
{I}は不純度を数値化したもの。
結局この式が表すのは、「親ノードの不純度」と「子ノードの不純度全体の」差に過ぎない。
不純度は以下の3つの指標がよく使われる。

  • ジニ不純度(Gini impurity)
  • エントロピー(entropy)
  • 分類誤差(classification error)

ランダムフォレスト

直観的にはランダムフォレストは決定木のアンサンブルとみなせる。 アルゴリズムは以下の4つの単純なステップにまとめられる。

  1. 大きさnのランダムな「ブートストラップ」標本を復元抽出する
  2. ブートストラップ標本から決定木を成長させる
    • d個の特徴量を非復元抽出する
    • たとえば情報利得を最大化することにより、目的関数に従って最適な分割となる特徴量を使ってノードを分割する
  3. ステップ1~2をk回繰り返す
  4. 決定木ごとの予測をまとめて、「多数決」に基づいてクラスラベルを割り当てる。

怠惰学習(lazy learner)とは?

トレーニングデータセットから識別関数を学習せず、トレーニングデータセットを暗記する学習。

パラメトリックモデルとノンパラメトリックモデル

パラメトリックモデルでは、トレーニングデータセットからパラメータを推定する。 それにより元のトレーニングデータセットがなくても新しいデータ点を分類できるようになる。 パーセプトロン、ロジスティック回帰、線形SVMパラメトリックモデルの典型例である。

対照的にノンパラメトリックモデルの場合は、固定のパラメータ集合で特徴づけることはできない。 パラメータの個数はトレーニングデータセットとともに増加する。 ノンパラメトリックモデルの例は、決定木・ランダムフォレスト、カーネルSVMなど。

k近傍法

kNNのアルゴリズムは次のステップからなる。

  1. kの値と距離指標を選択する
  2. 分類したいサンプルからk個の最近傍のデータ点を見つけ出す
  3. 多数決によりクラスラベルを割り当てる

scikit-learnのIrisデータセットの構造

3種の分類クラス(Setosa, Versicolour, Virginica)からなる150のデータが、
150x4 numpy.ndarray構造に記録されている。 すなわち特徴の次元は4(Sepal Length, Sepal Width, Petal Length, Petal Width)である。

(参考) The Iris Dataset — scikit-learn 0.18.1 documentation 第18回 ロジスティック回帰:機械学習 はじめよう|gihyo.jp … 技術評論社

4章 データ前処理 よりよいトレーニングセットの構築

one-hotエンコーディング

名義特徴量の列の一意な値ごとにダミー特徴量を新たに作成する。 たとえば、color特徴量にblue, green, redという3つがあったとき、 これらを表す3つの新たな特徴量に変換する。 青のサンプルは、blue=1, green=0, red=0といったように。

過学習の原因と対策

過学習の原因は、与えられたトレーニングデータセットに対してモデルが複雑すぎること。 それに対する対策として、以下の方法がある。

  • 更に多くのトレーニングデータを集める
  • 正則化を通じて複雑さにペナルティを課す
  • パラメータの数が少ない、より単純なモデルを選択する
  • データの次元の数を減らす

L1正則化による疎な解

ペナルティの与える方法によって、L1正則化とL2正則化がある。 {} $$ L1: ||w||_{1} = \sum_{j=1} |w_j| $$ {} $$ L2: ||w||_{2} = \sum_{j=1} w_{j}^{2} $$ L1正則化を課すと、重みが疎となる傾向がある。 つまり殆どの重みが0となる。 この疎性が役立つのは、無関係な特徴量の個数が多い高次元のデータセットがあるときである。

L1正則化が疎性を促す様子を確かめるために、 L1正則化とL2正則化をそれぞれ図解してみる。

L2正則化の場合、目標はコストとペナルティの最小化を目指すことである。 f:id:yusuke_ujitoko:20170228082737p:plain

一方、L1正規化の場合、ペナルティがひし形を示すため、最適解は軸上にあることが多い。そのため疎性が促進される。 f:id:yusuke_ujitoko:20170228082838p:plain

5章 次元削減でデータを圧縮する

特徴抽出

特徴抽出(feature extraction)はデータセットを変換し、元の次元よりも低い次元の新しい特徴部分空間(feature subspace)を作成するものである。 例えば以下のようなものがある。

  • 主成分分析(PCA)
  • 線形判別分析(LDA)
  • カーネル主成分分析

主成分分析(Principal Component Analysis)

PCAの目的は、高次元データにおいて分散が最大となる方向を見つけ出し、元の次元と同じかそれよりも低い次元の新しい部分空間へ射影すること。

PCAのアルゴリズムの手順は以下のようになる。

  1. d次元のデータセットを標準化する
  2. 標準化したデータセットの共分散行列を作成する
  3. 共分散行列を固有ベクトル固有値に分解する
  4. 最も大きい固有値に対応するk個の固有ベクトルを選択する この場合のkは新しい特徴部分空間の次元数を表す
  5. 上位k個の固有ベクトルから射影行列Wを作成する
  6. 射影行列Wを使ってd次元の入力データ・セットXを変換し、新しいk次元の特徴部分空間を取得する

線形判別分析(LDA:Linear Discriminant Analysis)

LDAとPCAはどちらも線形変換法であるが,以下の違いがある.

  • PCA
    • データセットにおいて分散が最も大きい直交成分軸を見つけ出そうとする
    • 教師なし学習
  • LDA

    • クラスの分離を最適化する特徴部分空間を見つけ出そうとする
    • 教師あり学習
  • d次元のデータセットを標準化する

  • クラスごとにd次元の平均ベクトルを計算する
  • クラス感の変動行列 {S_B} と,クラス内変動行列 {S_W} を生成する
  • 行列 {S_W^{-1} S_B}固有ベクトルと対応する固有値を計算する
  • d*k次元の変換行列 {W} を生成するために,最も大きいk個の固有値に対応するk個の固有ベクトルを選択する.固有ベクトルはこの行列の列である.
  • 変換行列 {W} を使ってサンプルを新しい特徴部分空間へ射影する.

6章 モデルの評価とハイパーパラメータのチューニングのベストプラクティス

ホールドアウト法

ホールドアウト法は、機械学習のモデルの汎化性能を評価するために従来より使用されているアプローチ。 データを訓練データ、検証データ、テストデータの3つに分割する。

f:id:yusuke_ujitoko:20170305123424p:plain

ホールドアウト法の問題点は、もとの訓練データを訓練データと検証データにどのように分割するかにより、性能の評価に影響が及ぶことである。 つまりデータのサンプルで評価が変わってきてしまう。

k分割交差検証

k分割交差検証では、非復元抽出を繰り返して、訓練データをランダムにk個に分割する。そのうちのk-1個をモデルの訓練に使用し、1個をテストに使用する。 この手順をk回繰り返すことで、k個のモデルと性能評価を取得する。

グリッドサーチ

グリッドサーチとはハイパーパラメータの最適化手法。 ハイパーパラメータの最適な組み合わせを見つけ出すことにより、モデルの性能を改善するのに役立つ。

網羅的探索手法であるため、パラメータの組み合わせを見つけるには効果的だが、 実際には計算コストが高い。 (そこで、ランダムサーチという手法もある)

入れ子式の交差検証

グリッドサーチと組み合わせてk分割交差検証を使用する方法ではハイパーパラメータの値を変化させて、モデルの性能が最良となるパラメータを決められる。 しかし、さまざまな機械学習アルゴリズムの中からどれかを選択したい場合は、入れ子式の交差検証が推奨される。

入れ子式の交差検証では、 ループが2層になっている。 外側のループでアルゴリズムの比較を行い、 内側のループで各アルゴリズム内でのパラメータチューニングを行っている。

主成分分析(PCA)がなぜ分散共分散行列を対角化する固有値問題となるか

主成分分析(principal component analysis:PCA)とは?

教師なし学習の一つ。 データの分散(ばらつき)が大きいところ(主成分)を見つける操作。 つまり分散が大きいところが大事で、小さいところは気にしないようにする。

既存の特徴を組み合わせて分散が大きくなる新たな尺度となる特徴を見つける。 例えば、2つの特徴を組み合わせて1つの特徴でその対象を上手く捉えることができたら、 パラメータを減らせる。

f:id:yusuke_ujitoko:20170304192428p:plain

  • PCAのアルゴリズム

    1. 全データの重心を求める(平均値)
    2. 重心からデータの分散(ばらつき)が最大となる方向を見つける
    3. 新しいデータ表現軸として、2.で求めた方向を基底とする
    4. 上記でとった軸と直交する方向に対して分散が最大となる方向を探す。
    5. 2.~3.をデータの次元分だけ繰り返す
  • PCAの目的

    • データの特徴抽出
      • データのバラつきが大きい部分に着目することでよいデータを識別しやすくする
    • データの次元圧縮
      • データのバラつきが少ない部分はデータに共通するパターンなのであまり意味をなさない(無視)
    • 多次元特徴量の可視化
      • 多次元データは人間には認識不可
      • データのバラつきが大きところを見ることでデータの関係性を把握

主成分分析がなぜ分散共分散行列を対角化する固有値問題となるか?

訓練データ {x_{i} = (x_{i1}, .. , x_{id})^{{T}}(i = 1, .. ,N)}分散が最大になる方向を求める。
{N} 個のデータからなるデータ行列: {X = (x_{1}, .. x_{N})^{\mathrm{T}}}
{N} 個の訓練データの平均ベクトル: {\bar{x}=(\bar{x_{1}} .. ,\bar{x_{d}})^{\mathrm{T}}}
平均ベクトルを引き算したデータ行列: {\bar{X}=(x_{1} - \bar{x} .. ,x_{N} - \bar{x})^{\mathrm{T}}}
とすると、平均化訓練データ行列の分散は

$$ \sum = Var({\bar{X}}) = \frac{1}{N}\bar{X}^{\mathrm{T}}\bar{X}\ $$

で定義される。

単位ベクトル: {a = (a_{1}, \cdots , a_{d})^{T}} とすると、{N} 個のデータ {x_i - \bar{x}} の単位ベクトル {a} への正射影は

$$ s_i = (s_{1}, .. ,s_{d})^{\mathrm{T}} = \bar{Xa} $$

となる。 この変換後のデータの分散は、

$$ Var({{s}}) = \frac{1}{N}{s}^Ts = \frac{1}{N}(\bar{Xa})^{\mathrm{T}}(\bar{Xa}) = \frac{1}{N}{a}^T\bar{X}^{\mathrm{T}}\bar{Xa} = a^TVar({{\bar{X}}})a $$

となる。この分散が最大となる単位ベクトル {a} は、係数ベクトル{a} のノルムを1となる制約があること利用して、 ラグランジェの未定乗数法を使って求める。

$$ E(a) = a^TVar({{\bar{X}}})a - \lambda(a^T a - 1) $$

を最大にする{a}を見つければよい、{\lambda}はラグランジェ未定定数である、{a}微分して0としておけば、

{\frac{\partial E(a)}{\partial a} = 2 Var({{\bar{X}}})a - 2\lambda a = 0} より {Var (\{\bar{X}\})a = \lambda a}

となる。 この式は元のデータの共分散行列に関する固有値問題を解くことに等しいので、 分散最大となる単位ベクトル {a}固有値問題を解いて求めた固有値固有ベクトルの中で、 最大固有値に対応する固有ベクトル{a}とすればよい。

誤差逆伝播法の数式を簡単なニューラルネットで理解する

機械学習

誤差逆伝播法の数式をニューラルネットで追ってみる。
時々忘れてしまうので、備忘録として残しておく。

今回考えるニューラルネット

下記のニューラルネットを例に取る。 f:id:yusuke_ujitoko:20170224233215p:plain {i}層への入力を{u_i}
{i}層のアクティべーションを{a_i}
{i}層から{i+1}層への重みを{w_i}としている。 なお入力層は活性化しない。
この時、各層間の結合は下記の式のようになる。 {} $$ \left\{ \begin{array}{} u_4 = w_3 a_3 \\ u_3 = w_2 a_2 \\ u_2 = w_1 u_1 \\ \end{array} \right. $$ 上記の式を、{w_i}や、{a_i}について偏微分した下記の式も成り立つ。 {} $$ \left\{ \begin{array}{} \frac{\partial u_4}{\partial w_3} = a_3 \\ \frac{\partial u_3}{\partial w_2} = a_2 \\ \frac{\partial u_2}{\partial w_1} = a_1 \\ \end{array} \right. \\ \left\{ \begin{array}{} \frac{\partial u_4}{\partial a_3} = w_3 \\ \frac{\partial u_3}{\partial a_2} = w_2 \\ \frac{\partial u_2}{\partial a_1} = w_1 \\ \end{array} \right. $$

また活性化関数を{f}とすると、下記の関係式が成り立つ。 {} $$ \left\{ \begin{array}{} a_4 = f(u_4) \\ a_3 = f(u_3) \\ a_2 = f(u_2) \\ \end{array} \right. $$ 上記を{u_i}偏微分した式も記しておく。 {} $$ \left\{ \begin{array}{} \frac{\partial a_4}{\partial u_4} = f'(u_4) \\ \frac{\partial a_3}{\partial u_3} = f'(u_3) \\ \frac{\partial a_2}{\partial u_2} = f'(u_2) \\ \end{array} \right. $$

誤差逆伝播

誤差を{E}とする。
また、{\frac{\partial E}{\partial a_4}}は既知とする。

{\frac{\partial E}{\partial u_4}}を求める。

f:id:yusuke_ujitoko:20170225003603p:plain 連鎖律を利用すると、下記となる。 {} $$ \begin{align} \frac{\partial E}{\partial u_4} &= \frac{\partial E}{\partial a_4} \frac{\partial a_4}{\partial u_4} \\ &= \frac{\partial E}{\partial a_4} f'(u_4) \end{align} $$ この式は、誤差の出力に対する偏微分{\frac{\partial E}{\partial u_4}}が、誤差のアクティベーションに対する偏微分{\frac{\partial E}{\partial a_4}}に、活性化関数の微分{f'(u_4)} を掛けたものであることを示している。

{\frac{\partial E}{\partial w_3}}を求める

次は、{\frac{\partial E}{\partial w_3}}を求める。 f:id:yusuke_ujitoko:20170225003612p:plain

連鎖律を利用すると、下記のようになる。 {} $$ \begin{align} \frac{\partial E}{\partial w_3} &= \frac{\partial E}{\partial u_4} \frac{\partial u_4}{\partial w_3} \\ &= \frac{\partial E}{\partial u_4} a_3 \\ &= \frac{\partial E}{\partial a_4} f'(u_4) a_3 \end{align} $$

{\frac{\partial E}{\partial a_3}}を求める

f:id:yusuke_ujitoko:20170225003725p:plain 次は、{\frac{\partial E}{\partial a_3}}を求めるが、これも上記とほぼ同じ導き方ができる。 {} $$ \begin{align} \frac{\partial E}{\partial a_3} &= \frac{\partial E}{\partial u_4} \frac{\partial u_4}{\partial a_3} \\ &= \frac{\partial E}{\partial u_4} w_3 \\ &= \frac{\partial E}{\partial a_4} f'(u_4) w_3 \end{align} $$

これ以降は繰り返しになる。

{\frac{\partial E}{\partial u_3}}{\frac{\partial E}{\partial w_2}}{\frac{\partial E}{\partial a_2}}{\frac{\partial E}{\partial u_2}}{\frac{\partial E}{\partial w_1}}{\frac{\partial E}{\partial u_1}}を求める。

これまでと同様に、連鎖律を使って順番に求められる。 {} $$ \begin{align} \frac{\partial E}{\partial u_3} &= \frac{\partial E}{\partial a_4} f'(u_4) w_3 f'(u_3) \\ \frac{\partial E}{\partial w_2} &= \frac{\partial E}{\partial a_4} f'(u_4) w_3 f'(u_3) a_2 \\ \frac{\partial E}{\partial a_2} &= \frac{\partial E}{\partial a_4} f'(u_4) w_3 f'(u_3) w_2 \\ \frac{\partial E}{\partial u_2} &= \frac{\partial E}{\partial a_4} f'(u_4) w_3 f'(u_3) w_2 f'(u_2) \\ \frac{\partial E}{\partial w_2} &= \frac{\partial E}{\partial a_4} f'(u_4) w_3 f'(u_3) w_2 f'(u_2) u_1 \\ \frac{\partial E}{\partial u_1} &= \frac{\partial E}{\partial a_4} f'(u_4) w_3 f'(u_3) w_2 f'(u_2) w_1 \\ \end{align} $$

勾配消失や勾配爆発の原因

上式を見ると、前方の層になるにつれて、活性化関数の導関数や重みが繰り返し掛け合わされているのがわかる。
活性化関数を例えばシグモイドと設定すると、シグモイドの導関数の最大値は1/4であるので、 そのシグモイドンホ導関数が繰り返し掛けられると、勾配が徐々に小さくなっていってしまう。
これが勾配消失問題である。

一方、重みが大きい値を取ると、 前方の層に伝わるに際に、その重みが影響して勾配が大きくなる。
そうなると勾配が不安定となる。
これが勾配爆発問題である(と私は理解している)。

参考

ニューラルネットワークと深層学習