オンライン手書き数字認識のデモページ

管理者権限での InternetExplorer(IE) 10.0 以降でのみ実行可能です。
IE以外を使用してる方は今一度IEを管理者権限で実行してこのページへお越しください。
実行前に以下の設定が必要です。
 (1)IEのメニューの[ツール]-[インターネットオプション]-[セキュリティー]-[レベルのカスタマイズ]と進んで、
   [.Net FrameWork]の[XAMLブラウザアプリケーション]を[有効]にする。
 (2)同じく[セキュリティー]タブの[信頼済サイト]-[サイト]ボタンと進んで、
   下の[このゾーンのサイトには全てサーバの確認(https)を必要とする]のチェックをはずし、
   ついで上の[追加]ボタンの左欄に"http://ir-system.biz/"と入力して[追加]ボタンを押す。
   準備できた場合のみ実行はここをクリック

  .NET FrameWork4.0がインストールされていない場合は自動的にインストールに向かう(結構時間かかる)ので
  インストール終了後再実行。
  途中でウイルス防止ソフトが茶々をだすので予め切っておくか、実行継続の方向で行く。
  ダウンロード/実行するかと聞かれたら、すると答える。デモは32bitのWindows7でのみ確認済み。
  ニューラルネットと遺伝アルゴリズムと脳生理学の線分方向検出器の知見を利用してやってます。


以下、以前ブログに書いていた本システムの内部の説明です。

<前置き>
・昔大学で勉強したパーセプトロンというニューラルネットの画像識別システムと
・脳生理学的な視覚の線分検出の知見と
・遺伝アルゴリズム
を利用してソフトウエアで手書き文字判別システムを作ってみようと思い、2013年ころ暇に任せてやってみた結果です。一度ブログに載せていましたがhustleレンタルサーバが障害ばかりで引っ越ししたためブログができなくなり、今回ホームページにソースコード見て思い出しながら現段階での最終的なものを記載します。

まず、いきなり手書き文字全体を識別相手にするのは難しそうなので、対象は手書きの数字に絞りました。手書き文字のデータベース(以下DB)を探したら、
・ETLというDB(http://etlcdb.db.aist.go.jp/?lang=ja)と
・BIRDSのDB(http://www.geocities.jp/onex_lab/birdsdb/birdsdb.html)
がありました。

<構造>
神経細胞(以下ニューロンまたはセル)は模式的に夫々発火するかしないかのどちらかであり、発火はセル固有の「閾値」を「入力値の合計」が超えると起こるとします。「入力値の合計」はそこへコネクトして来ているセルが発火するとそのセルからの「結合重み」が加算されて計算されます。複数のセルからコネクションが来ている場合はそれらの「結合重み」が全部合計されて「入力値の合計」となります。これは興奮性ニューロンからのコネクションの場合ですが、抑制性ニューロンからの場合は引き算されます。
[各層の構造]
パーセプトロンにならって入力層と中間層と出力層という3層のニューロン(セル)の集合を3つ用意し、
入力層は縦12x横8の計48個のセルを平面上に配置し、それで手書き数字の画像をその粒度で受けます。ここまではパーセプトロンと同じです。例えば9x6の場合の入力層レベルのサンプルは以下のような感じです。



出力層は判別結果を表するセル集合で、数字なので0〜9の計10個のセルかならなります。これもパーセプトロンと同じと思います。

中間層はかなり工夫をして最終的には、
・縦線・横線・右上斜線・右下斜線(|−/\)の4つの形状の識別を担うセルを、入力層の12x8の格子を縦3x横2の計6つの4x4のサブ格子毎に配置しました。(工夫点1)
3x3の例で示せば以下のような4形状の識別を想定しています。
  ●  ●     ●      
 ●    ●    ●   ●●●
●      ●   ●      
これは昔大学で脳生理学でならったHubel & Wiesel博士ら(1958など)の脳の視覚領野に線分の方向を検出するニューロンがあるというサルの実験にヒントを得たものです。http://web2.chubu-gu.ac.jp/web_labo/mikami/brain/26/index-26.html

[層間のコネクション]
・入力層のセルから中間層の全てのセルに対して結合重み=1でコネクションを張ります。
・中間層のセルから出力層の全てのセルに対しては、工夫して、オン結合とオフ結合の2経路の接続を夫々乱数値の結合重みで作りました。オフ結合とはそのセルが発火しないとコネクト先に促進的波及が起こる結合で、通常の裏返しです。自然界ではこんな2経路結合をするニューロンはないはずですが、後に述べる学習時の中間層と出力層間の結合重みの「発火不足時の強化」と「出しゃ張り発火の弱化」による正答率の向上を促進できることが分かったので採用しました。(工夫点2)
・このニューラルネットの構造を表す遺伝子として、結合重みgeneを[ 入力層縦セル数 * 入力層横セル数 * −/\の形状数(=4) * 出力層セル数(=19) * 2 ]の一次元配列で用意し、全ての中間層セルから全ての出力層セルへの結合重み(on/offの2系統)を記録します。
以上がニューラルネット(疑似的な脳)の構造です。

<学習>
上記のような3層構造のニューラルネット(疑似脳)を持つ個体を複数用意し1つの世代とします。同じ結合重みの個体はできないようにします。これらの全個体に対して上記の手書き数字DBや自分で書いた手書き数字を一定回数学習させます。学習の際の結合重みの変更は以下のようにしました。
[強化]
ある数字を提示して正解の数字に対応する出力層セルが発火しない場合は、
・そこにコネクトして来ている中間層セルが発火してるならそこからのオン結合重みを少し増加させ、
・中間層セルが発火していなければそこからのオフ結合重みは増加させて褒めます。
[弱化]
正解でない数字の出力セルが発火(出しゃ張り発火)してる場合は、
・そこにコネクトして来ている中間層セルが発火しているならそこからのオン結合重みを少し減少させ、
・中間層セルが発火していなければそこからのオフ結合重みは減少させて懲らしめます。
このようにして複数回学習させ世代の最高得点に到達した個体をもって世代の正解率とします。
一般的にこのニューロ学習だけでも簡単な数字などは数十回の学習で殆ど90%台の正答率に達しますが、それ以上はなかなか向上しなかったようです。
[手書き数字画像の前処理]
手書き画像には極端に擦れていて見にくいものや、極端に太い部分と細い部分があるもの、勢いで筆の終わりが極端に長いもの、枠の極一部分の範囲に押し込められて書かれているものなどがあり、これらはソフトウエア的に事前処理しています。

<交配・進化>
世代に於いて正答率の高い順に個体を並べ、成績優秀な個体同士で優先的に交配を行います。交配は両個体の上記の遺伝子(結合重みgene)を任意の一点で交差させて新たな遺伝子を作り、それをもとに2つの個体を作ります。ただし同じ遺伝子の個体が新たな世代で重複しないようにします。(工夫点3)
このようにして新しい世代を作り、そこでまた全個体に学習をさせて選択交配をするという過程を繰り返します。自然界と同じ掟とはいえ、身につまされるものがあります。でも結局はすごくゆっくりではあれ、こういう仕組みで生物は進化してきたんでしょうか。
ともあれ、どういう成績レベルの個体を交配させるかなどいろんなパラメータがあり、うまい組み合わせに到達するのは大変です。以上のようなことを行った結果、以下のような正答率の疑似進化のグラフが出てきました。
[使用する手書き数字サンプル数-1個体あたりの学習回数-個体数-世代数]のパラメータで実行した時の世代ごとの成績ですが、
図1は500-1-100-487でmax正解率98.6%、なかなか100%に達しません。

それに対し図2は100-2-1000-50で50世代くらいでmax正解率100%に達しました。


のように学習回数はぐっと少なめにして、個体数を多くして選択が局所的な最適解に落ち込まないようにした方が早い世代で良い成績が出るようです。analys.xlsx参照。
このようにニューラルネットだけでも結構な識別レベルに到達しますがそれ以上には向上せず、それ以上の向上に遺伝アルゴリズムが役に立つように思えました。現状では突然変異などは取り入れてませんがそれも大いに役に立つと思われます。

<その他>
ソースコードは ここです。ただし、文字DBがつけられないので実行はできません。当時は次は手書き漢字の識別をやってみようと思っていましたが、いくら暇なシルバーとはいえお金にならないことばかりやっておれず、今日に至っております。
後日、ここまでの過程を振り返って経過を少し書き足す予定です。