順伝播型ニューラルネットワークでMNISTの手書き数字認識

深層学習を勉強しようと思って,深層学習の本[1]を読んだ. さらに,MNISTデータセット[2]を使って,手書き数字認識プログラムを作った MNISTは,分類器を作る時のHello worldみたいなの 一番簡単な順伝播型ニューラルネットワーク(FFNN)を使う(他はよくわからん) 1章から4章あたりまで読めば実装に必要な情報が揃う 入力層,中間層,出力層の3層だけで構成 行列計算,データセットは既存のパッケージを使う 画像認識プログラムそれ自体は自分で実装する(caffe,TensorFlow等を使わない) この界隈ではPythonがスタンダードらしいので,それに従う ただ,Jupyter(IPython)は準備がめんどくさかったので保留 ソースコードは全部まとめて[3]に置いておく 順伝播型ニューラルネットワークの構築 構造が簡単な順伝播型ニューラルネットワーク(FFNN)を採用 多層パーセプトロンともいう 入力データを,多クラスに分類させる ネットワークは図のように構築する \(L\): 層の数.入力層,中間層,出力層の3層があればよい \(f^{(l)}(u)\): 第\(l\)層における活性化関数 \(f^{(l)}(u) = \frac{1}{1+e^{-u}} \): 出力層以外なら,ロジスティック関数を使う \(u_i^{(l)}\): 第\(l\)層の\(i\)番目のユニットにおける入力 \(z_{i}^{(l)}=f^{(l)}(u_i^{(l)})\): 第\(l\)層の\(i\)番目のユニットにおける出力 \(\mathbf{W}^{(l)}\): 第\(l-1\)層と第\(l\)層の間の重みを要素にもつ行列 各層の入出力を列ベクトルで表す \(\mathbf{u^{(l)}} = [u_0^{(l)} u_1^{(l)} \dots u_i^{(l)} \dots]^{T}\): 第\(l\)層のユニットへの入力を表す列ベクトル \(\mathbf{z^{(l)}} = [z_0^{(l)} z_1^{(l)} \dots z_i^{(l)} \dots]^{T}\): 第\(l\)層のユニットの出力を表す列ベクトル この時,順方向(入力層->中間層->出力層)の伝播は以下のように行列演算で書ける 入力を列ベクトル\(\mathbf{x}\)とすると,\(\mathbf{z}^{(0)} = \mathbf{x}\) 出力を列ベクトル\(\mathbf{y}\)とすると,\(\mathbf{y} = \mathbf{z}^{(L-1)}\) \(\mathbf{u^{(l+1)}} = \mathbf{W}^{(l+1)} \mathbf{z}^{(l)} + \mathbf{b}^{(l+1)}\) \(\mathbf{z^{(l+1)}} = f^{(l+1)}(\mathbf{u^{(l+1)}})\) ただし,\(\mathbf{b}^{(l)}\)は第\(l\)層のバイアス 分類するだけならここで終わり.\(\mathbf{y}\)が分類結果. 学習段階であれば,次に逆方向(出力層->中間層->入力層)の伝播を行う. \(\mathbf{d}\): \(\mathbf{x}\)の正解データ \(\mathbf{\Delta}^{(L-1)} = \mathbf{z}^{(L-1)} - \mathbf{d}\) \(\mathbf{\Delta}^{(l)} = f^{(l)’} ( \mathbf{u^{(l)}} ) \odot \mathbf{W}^{(l+1)T} \mathbf{\Delta}^{(l+1)} \) \(\odot\): 行列の要素同士の積 \(f^{(l)’}(u)\): \(f^{(l)}(u)\)の導関数 \(\mathbf{\Delta}^{(l)}\)が求まれば,それをもとに重みとバイアスを更新する....

April 24, 2016