ニューラルネットワークを書く #3
概要
3層全結合ニューラルネットワークを書きました。
DIGISTを使おうと思いましたが結局MNISTを使いました。
参考
shop.ohmsha.co.jp
いつもの
理論部分だけ
書いたもの
今回実装したもの
バックプロパゲーション
後ろから勾配を求めて順番に更新していく手法。
ソフトマックスの微分とかReLUの微分とかクロスエントロピーの微分とか色々しました。時間があったら自力で解きたい…。
ReLU
活性化関数の一つ。よく見るやつ。0以下は0に、0以上はそのまま返します。
画素値にマイナスはないから、マイナスの値を0に補正することで計算の破綻を無くすみたいな役割かな?
微分したらマイナスは0、プラスは1になる易しい関数。
ドロップアウト層
任意の割合でランダムなユニットの値を0にすることでネットワークから除外することで過学習を防止するらしいです。
実装的には0と1のフィルターを作って入力ユニット1枚ずつに掛けました。重み更新の時にも同じフィルターを使いました。
この有用性はアンサンブル学習とかでググるといいと思います。
今回変更したもの
重み
前回は1で初期化していましたが今回は-1から1の範囲でランダムにしました。
3層になったのでndarrayのテンソルにしました。次元が同じでないといけないけど重みの数は層ごとに変わるので大きめに作ってスライスしています。
全結合層
1層で出力層としていたものを今回は全結合層として書いて汎用性を持たせました。
3層全部これを使いました。
クロスエントロピー
log0 = -inf になって正しく計算ができない問題が起きたので1e-8を足しています。
前回は層が1層だったせいか偶然エラーが起きなかったらしい…。
ソフトマックス
numpyを使って書き直しました。
コンソール出力
おされにしました。
stdout.writeを使っています。懐かしい感じがするフォーマット指定子%
結果
テスト精度96% 概ね成功でしょう…
課題
メイン関数(Python的にそもそもこの書き方あってるのみたいなとこあるけど)が長い。
トレーニングとテストで同じことの繰り返し書いてるのが気持ち悪い。トレーニングの時に作ったネットワークを関数に保存できればだいぶ見やすくなる気がする…。
感想
numpyの使い方に注意した為か層が増えたが速度が上がったような気がして嬉しい。
0で割るのと無限大の可能性には注意だ!!1
次回
畳み込みニューラルネットワークを書きます。