ニューラルネットワークで手書き文字認識。

2015/4/12

ニューラルネットワークで手書き文字認識をやってみる。今回もJavaScriptで実装する。

手書き文字データ

手書き文字データはMNISTを利用する。データをダウンロードしてPerlスクリプトJavaScriptソースに変換した。
オリジナルは28×28サイズで学習用60,000文字+検証用10,000文字あり、そのままだと処理が遅くソースサイズも非常に大きくなるので、14×14サイズに縮小して学習用6,000文字+検証用1,000文字を使う。

プログラム。

前回は関数近似なのでニューロンのユニット数は入力1、出力1だったが、今回は入力が14×14の画像なので14×14=196個、出力は0から9の数字に対応する10個とする。
train()とrecognize()は前回の関数を学習させたものと同じで、main()を画像認識用に変更してある。



学習結果。

「学習による重み」枠では、ユニット間接続の重みを可視化してある。上の50個の四角い画像が「入力-隠れ層」の重み w1 で、隠れ層の50個のユニットごとに入力層14×14の重みをpixelごとに表示している。
下の10個の画像は「隠れ-出力層」の重み w2 と、「入力-隠れ層」の重み w1 をかけあわせて、0~9の出力ユニットごとに対応するpixelの重みをあらわしたものである。ここに0~9の平均的な手書き画像が現れるのを期待したのだが、ぜんぜん見えない。そう単純でもないようだ。

「検証結果」枠では、左端の検証用画像を認識した結果、0~9各ユニットの出力値が右側の棒グラフになる。最も大きい値が認識結果とみなせる。それが正解なら赤で、不正解なら青で表示している。はじめは青が多く、学習するにつれて赤が増えてくる。

学習による重み
検証結果



ここでいう1回の学習は、6,000文字の全てを(1文字ずつオンライン方式で)学習している。

参考になったリンク。



©