05.02 画像分類(中級)-2(MNIST)

④ コンポーネントパラメータ設定
Visual Studio C++で「Property(プロパティ)」という言葉が出てきましたが、今回も「層毎のプロパティ」があり コンポーネントをクリックすると、左下の方に「Layer Property」という設定画面が登場します。試しに「Input(入力層)」コンポーネントをクリックしてみてください。「Layer Property」の内容が、「Input」に変更になります。

この場合、MNISTはグレースケール(白黒)の28x28ですので、

    「Size」 : 「1, 28, 28

となっているか確認してください。GGEは既に変わっており変更する必要はありませんでした。


次は中間層パラメータ「Affine(全結合層)」をクリックします。
すると下記のように出てきますので、出力ノードの変更をします。
仕様により「中間層128ノード」としましたので、下記のように変更します。

OutShape」 : 「128





次は出力層「Affine_2(全結合層)」をクリックし、同様にノードは0~9なので「10」に変更します。

OutShape」 : 「10





必要最小限はこれだけとありますので、とりあえずこれだけの修正は必要となります。




⑤ 学習条件と最適化の設定
次に「CONFIG」をクリックし「Global Config」画面を表示させ、学習条件の設定を行います。
すると下記のような画面となりますので、次の箇所を変更してください。

  「Max Epoch」    : エポック数「20
  「Batch Size」    : ミニバッチ「100」 




次はすぐ下の「Optimizer(最適化)」画面を開き、同様に次の項目を変更してください。

  「Updater」        : 最適化手法を「Sgd
  「LearningRate」 : 学習係数を「0.5

パラメータ内容はNNCインストールフォルダー内「manual_ja.pdf」67ページ以降に記載されていますので確認してください。但し、以降処理遂行に必要と思われる部分については分かり次第解説したいと思っています。





これで最適化設定は完了しました。
フロッピーアイコンをクリックして、適当な場所へ今までのものを保存します。



⑥ 学習の実行
いよいよ中級編で学習させてみましょう。

今までと同じように「Training」下の””をクリックします。
今回は0~9の判別となりますのでエポック終了までの時間が非常に長く感じられますが、Pythonによる自作よりは桁違いに速いです。 とはいえ、時間はかかりますが学習曲線が、わずかなエポック数ですが誤差が少なくなる方向で収束していることが驚かされます。






⑦ 評価の実行
次に「Evaluation」下の””をクリックすると、こちらも結構時間はかかりますが終了すると、下記のようなDATASET画面となります。以前との違いは出力ノードを0~9の10個に設定したため「ylabel」の隣が、もし隠れているなら境となる縦棒をつまんで右へずらしていくと隠れていたもの「y'_0」~「y'_9」が次々登場し下記のように見え始めます。




次に「〇Output Result」から「◎Configuration Matrix」へ変更してみてください。
以前のように4x4行列から多次元行列になっています、 このような行列を「混同行列」と呼ぶらしく、左上から下にかけてが正解で両サイドが不正解件数となります。見方は以前のものと変わりません。




いずれにしても画面の表示幅が小さいので(大きな画面で見ている方は見えるはずです)
前回保存したフォルダーを探します。GGEは参考書通りの「chap5_01_nn」という名前のプロジェクトにしたため下記のフォルダーへ移動します。

~省略~samples\sample_project\tutorial\basics\chap5_01_nn.files\20180612_120416

そのフォルダーの中に、多分下記名称の2つのCSVファイルがあると思いますので、それをエクセルで開いてみましょう。

confusion_matrix_y.csv
output_result.csv


これが混同行列の全容となります。そして分類精度は「0.977」。

【confusion_matrix_y.csv】
y'__0 y'__1 y'__2 y'__3 y'__4 y'__5 y'__6 y'__7 y'__8 y'__9 Recall
y:label=0 970 1 2 0 0 1 3 1 1 1 0.9897
y:label=1 0 1124 3 1 0 2 2 1 2 0 0.9903
y:label=2 2 3 1008 4 2 0 3 6 4 0 0.9767
y:label=3 0 0 3 991 0 5 0 6 3 2 0.9811
y:label=4 0 1 1 0 959 0 6 2 2 11 0.9765
y:label=5 2 0 1 8 0 869 6 1 3 2 0.9742
y:label=6 7 3 0 1 2 6 939 0 0 0 0.9801
y:label=7 1 3 10 3 0 0 0 1006 0 5 0.9785
y:label=8 7 0 2 11 5 5 2 5 933 4 0.9579
y:label=9 3 4 0 6 9 4 0 5 0 978 0.9692
Precision 0.9778 0.9868 0.9786 0.9668 0.9815 0.9742 0.9771 0.9738 0.9841 0.975
F-Measures 0.9837 0.9885 0.9776 0.9738 0.9789 0.9742 0.9785 0.9761 0.9708 0.972
Accuracy 0.9777
Avg.Precision 0.9776
Avg.Recall 0.9774
Avg.F-Measures 0.9774

同時に「output_result.csv」を表示しますのと、全容は下記となります。
要するに左の画像やラベルは同じですが、次に「y'_0」~「y'_9」が連なり、1つ例をとるとNo1はy:labelで””が正解の場合「y'_7」の数字が、”0.999999762%”の確率で”7”だといっています。


【output_result.csv】
x:image y:label y'__0 y'__1 y'__2 y'__3 y'__4 y'__5 y'__6 y'__7 y'__8 y'__9
7\0.png 7 7.36E-12 2.27E-11 1.97E-09 2.92E-07 4.75E-17 6.58E-10 1.85E-18 0.999999762 3.68E-13 1.10E-08
2\1.png 2 9.35E-09 1.53E-05 0.999984741 4.77E-08 3.36E-16 8.94E-10 1.58E-09 2.99E-15 5.75E-11 1.30E-18
1\2.png 1 1.11E-09 0.999754369 8.80E-07 7.07E-09 8.89E-07 9.61E-07 2.25E-06 0.000240523 2.83E-07 7.94E-09
0\3.png 0 0.999962568 9.77E-12 3.62E-05 1.44E-10 3.18E-10 2.27E-07 6.23E-07 7.03E-09 1.12E-10 3.12E-07
4\4.png 4 2.99E-07 1.35E-09 3.46E-06 3.71E-09 0.998989761 1.28E-08 3.33E-07 1.39E-05 1.50E-10 0.000992145
1\5.png 1 5.25E-12 0.999835849 1.29E-09 1.26E-10 8.63E-07 3.64E-09 2.37E-09 0.000163273 1.93E-09 4.80E-10
4\6.png 4 6.43E-11 3.31E-10 2.99E-08 6.13E-09 0.99949646 2.49E-05 7.67E-09 0.000201692 1.72E-05 0.000259779
9\7.png 9 4.26E-10 1.85E-07 2.06E-06 0.001269805 3.22E-05 1.46E-06 3.48E-12 0.000401743 2.90E-10 0.998292625
5\8.png 5 3.11E-12 2.03E-12 1.13E-11 3.75E-12 3.03E-08 0.741435826 0.255853176 1.15E-10 1.78E-06 0.00270923
9\9.png 9 2.96E-12 1.84E-12 6.33E-09 6.81E-07 5.05E-05 7.09E-08 7.12E-13 0.001828336 2.78E-07 0.998120129
0\10.png 0 0.999998331 1.22E-13 1.66E-06 1.82E-12 2.12E-14 1.70E-10 2.06E-08 3.38E-10 5.06E-14 2.41E-10



結 論
単純に指示に従って実行するだけだと完成はしますが、

    「さて? 何ができるようになったのかなぁ?

となって、結構後味が悪くなることをGGEも経験しており、少々この点を中心に解説したいと思います。
まあ、還暦過ぎの爺さんですからご勘弁を!



1)何ができるようになったか?
端的に言うと
    「自己学習により手書きの数字が読めるようになった

ということになります。今回1から作ったものは、例えば「郵便に書かれた手書きの郵便番号」を、自分のパソコンが15分足らず自分で勉強した結果、「97%という高精度」で読むことができるようになったということになります。




2)その方法は?
手書きの数字を28x28ドットに変換し、最初から最後まで(上の画像だと0,0~27,27)の順番でニューラルネットワークの入力として取り入れ学習することで最後0~9の出力として出力するようにした結果、確からしさを確率で出力できるようになったということです。




【参考文献】
リックテレコム 足立悠著
ソニー開発のNeural Network Console入門

オライリー・ジャパン 斎藤 康毅著
ゼロから作るDeep Learning ――Pythonで学ぶディープラーニングの理論と実装