手書き文字の認識をさせてみよう|Excel VBAでMNIST機械学習
本ページではこれまでに実装したすべてのコードを使って自身の書いた手書き文字の認識をさせていきます。自分の書いた数字をニューラルネットワークに読み込ませ、認識させることがExcel VBAにもできるのかを実際に体験してみましょう。
今回の内容は既にMNIST学習されていることが前提です。
まだの方はメインページの「ニューラルネットワーク作成編」を参考にニューラルネットワークの学習を行っておいてください。
メインモジュールの実装(追加)
学習時にも使っていた「Main」モジュールに推論用のコードを追加します。
(※新規のモジュールではないので注意)
以前作成した関数「Train」の下に関数「Classification_MNIST」を追記します。
以下は関数「Classification_MNIST」の全コードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
'VBA Main(module) '学習済みパラメータを書き出し 'Call network.ExportParameters(ParamsSheet) 'MsgBox "学習終了" & vbLf & "学習結果はシート(Parameters)に書き出しました。" 'End Sub '------------------------------------------------------------------------------- Sub Classification_MNIST() input_size = 784 '28x28ピクセル hidden_size = 64 '学習結果に応じて変更可(※必ず学習時の構成と揃えること) output_size = 10 '0~9 Dim i As Long Dim j As Long Dim InputImageData() As Long Dim Data() As Double ReDim InputImageData(input_size) ReDim Data(input_size) InputImageData = csv_Functions.bmp_to_csv For i = 1 To input_size Data(i) = InputImageData(i) / 255 Next i Dim ExportSheet As Worksheet Set ExportSheet = Worksheets.Item("Sheet1") ExportSheet.Cells.ClearContents Dim cnt As Long Application.ScreenUpdating = False cnt = 1 For i = 1 To 28 For j = 1 To 28 ExportSheet.Cells(i, j) = InputImageData(cnt) cnt = cnt + 1 Next j Next i Application.ScreenUpdating = True Dim ModelSheet As Worksheet Set ModelSheet = Worksheets.Item("Parameters_Comp") Dim network As TwoLayerNet Set network = New TwoLayerNet ParamsCheck = True 'ModelSheetのパラメータを使用する Call network.Initialize(input_size, hidden_size, output_size, ModelSheet) Dim answer As Long answer = network.answer(Data) MsgBox answer End Sub |
学習ではニューラルネットワーク内で順伝播と逆伝播を繰り返していましたが、推論では順伝播を1回行うだけです。最終的にSoftmax関数によって導き出される値のうち一番大きな値をもつラベルが素論結果となります。
手書き文字データの作成
ニューラルネットワークに推論させるための手書き文字のデータを作成します。
これまでにもいってきましたが、推論させるためのデータは学習したMNISTデータと同じ形式である必要があります。
また、画像ファイルを数値に変換するための「csv_Functions」モジュールの関数はbmpファイルのみに対応しているので、結論をいうと28×28(px)でのbmp画像である必要があります。(実際はグレースケール画像を入れる必要がありますが「csv_Functions」モジュールでRGB値からのグレースケール変換を行うので、ここではカラー画像のままでOKです)
今回は一番手軽な「ペイント」で作成していきます。
[サイズ変更]より28×28(px)のサイズに変更します。
変更したら0~9のいずれかの数字を1つ、マウス(ペンタブ)で書きます。
数字を書いたら[名前を付けて保存]します。
このときファイルの種類は「24ビット ビットマップ」にして下さい。
以上で手書き文字データの作成は完了です。
ニューラルネットワークによる推論
「MNISTデータセットを学習させてみよう」でやったとおり、「Parameters」というシートに学習の結果が出力されます。
推論する際には、推論に使用したいシートの名前を「Parameters_Comp」にする必要があります。
シート名を「Parameters_Comp」に変更したら、あとは「Sub Classification_MNIST」を実行するだけです。(何回か学習を行い、複数のシートがある場合は一番精度の良さそうなもののシート名を「Parameters_Comp」に変更しましょう)
「Sub Classification_MNIST」を実行するとファイル選択画面が表示されます。
ここでは先ほど作成した手書き文字ファイル(.bmp)を選択します。
するとニューラルネットワークの推論が始まり、数秒待つとニューラルネットワークの推論の結果がメッセージボックスで表示されます。
学習がうまくいっていれば、7割から9割くらいの確率で正常に認識されます。
まとめ
今回はこれまでに実装したニューラルネットワークや関数を使って、自分の書いた手書き数字の認識させる方法を紹介しました。
ニューラルネットワークでの推論の方法をまとめると以下のとおりです。
① 手書き数字データを作成(ペイント等で作成)
② 学習済みシート「Parameters」のシート名を「Parameters_Comp」に変更
③ Mainモジュールの「Sub Classification_MNIST」を実行
④ t描き数字データを読み込ませる
⑤ 推論結果がメッセージボックスで表示
実際に手書き数字はうまく認識されたでしょうか?
おそらく期待したほどは精度が出なかったと思います。
というのも、今回やった内容は順伝播と誤差逆伝播の繰り返しだけなので、精度自体はもとより低めです。(ちなみに書籍にも書かれている「Momentum」や「AdaGrad」「Adam」などを実装するとさらに精度は上がります)
本サイトでの最終的な目標は機械学習の流れのイメージを掴むことです。
どこでどのような計算がされ、結果としてどのような値が求められるのか。
この辺りのイメージが少しでも伝わっていれば幸いです。