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

戯けた姿も生きる道ですか?

鬱屈とした学生の記録。備忘録。メモ。基本的に冗談。

手書き数字digitsを多層パーセプトロンで学習して認識するやつ

ニューラルネットワーク 機械学習

手書き数字認識といえばMNISTだが,次元の低いdigitsデータセットを多層パーセプトロンで学習させ自分で書いた数字を認識させる.
Pythonで書く.行列計算のためにNumPy,グラフ描画のためにMatplotlib,データセット読み込み・データ分割のためにscikit-learn,画像読み込みのためにOpenCVは用いるが,多層パーセプトロンを構成する部分では機械学習ライブラリは使わない.

Pen-Based Recognition of Handwritten Digits Data Set
The Digit Dataset
8×8ピクセルのグレースケール画像が1797枚なので,64次元データが1797個のセット
↓こんな感じ.これ4だって.
f:id:kenijl1116:20161210150216p:plain

順伝播型ニューラルネットワークの一種
詳しくは「高卒でもわかる機械学習」という一連の記事がとても分かりやすい.
hokuts.com
構成は表のとおり入力層を除く2層

入力層 中間層×1 出力層
ユニット数 64 40 10
活性化関数 - ロジスティックシグモイド関数 ソフトマックス関数
誤差関数 - - 交差エントロピー

10クラス分類問題なので教師データベクトルは
d=[0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
という具合にしておく.↑は2を表す.
出力層の活性化関数をソフトマックス関数とすると,出力ベクトルの要素y_kには入力データがk(k=0, ..., 9)である確率が格納される.

  • 最適化法

ニューラルネットワークは,出力ベクトルと教師データベクトルの誤差が最小になるように層間の重みWバイアスbを最適化することが目標で,それこそが“学習”である.この場合は交差エントロピーで算出される誤差E(W, b)を最小化するためにミニバッチで勾配降下法を行う.ミニバッチとは訓練データをいくつかのグループに分け,そのグループごとに誤差を計算して重みとバイアスを修正する.なお,epochごとに訓練データをシャッフルし10個のデータで1つのミニバッチを生成した.誤差の最小化を効率よく行うためにモメンタムを加える.モメンタムは前ステップでの修正量.

学習

  • パラメータ
学習回数 1000
バッチサイズ 10
学習係数 0.01
モメンタム・パラメータ 0.9
  • コード

  • 結果

誤差推移
f:id:kenijl1116:20161210152300p:plain
訓練誤差は学習回数が増えるごとに下がっているが,汎化誤差はepoch=80くらいまでは下がり続けるがそれ以降は逆に増えていく.これが過学習である.
学習回数を増やせば増やすほど性能が上がるかと言うとそうではない.逆に学習したデータしか正確に認識できなくなってしまう.以前,研究室のゼミで先生が言っていた.「講義中に解説した問題しか勉強せぇへん学生がおんねん.テストで同じ問題を値変えて出したらもう解けへん.コンピュータなら過学習やけど人間の場合は勉強不足っていうんや!

認識

上のグラフを踏まえて80回ほど学習させるとテストデータでの正解率は95%程であった.これで得られた重みとバイアスを用いて実際に自分で書いた数字を認識させる.

  • コード


  • 結果

f:id:kenijl1116:20161210165033p:plain
f:id:kenijl1116:20161210165048p:plain
見にくいが,0,1,3,4,5,6,7は正しく認識されている.一方,2は6と,8は1,9は4と誤認識された.
テストデータでは高い認識率だったのに俺の数字は認識してくれない...なぜだろう...学習データセットの数字がアメリカ人が書きそうな書き方だったせいか,8×8では限界があるのか...
次は28×28MNISTでやってみようかな...

参考

「深層学習」 岡谷貴之

深層学習 (機械学習プロフェッショナルシリーズ)

深層学習 (機械学習プロフェッショナルシリーズ)


続き↓
odoketasugata.hatenablog.com