VC++でニューラルネットワークによる手書き文字認識その⑤(オリジナル訓練データの追加)for VS2017
本ソフトウェアは、ニューラルネットワークと深層学習(著:Michael Nielsen )で
紹介されていたPythonで書かれたコードnetwork.pyを元にVC++でアレンジをしたもの。
今回は、まとめとなる。 ソースコードはここからダウンロードできるようにした。
ソースコードの解説は以下①~④記事参照。
但し、①~④で紹介したものとはソースコードは全く同じではなく、多少いじっております。( ゚Д゚)
C++でニューラルネットワーク その① ・・PythonのコードをVC++に書き換え
C++でニューラルネットワーク その② ・・PythonのコードをVC++に書き換え
C++でニューラルネットワーク その③ ・・重みとバイアスを外部に記録
C++でニューラルネットワーク その④ ・・オリジナル訓練データの追加
C++でニューラルネットワーク その⑤ ・・まとめ、文字認識アプリ
アプリケーションはここからダウンロードできます。
NNmodelGUI_sourceフォルダには、GUI本体のフォルダ内に、コンソールとDLLのソースが以下のように配置しています。
.
├── NNmodelDLL.dll ←DLL
├── NNmodelGUI.exe ←プログラム本体
├── NNmodelGUI_source
│ ├── NNmodelGUI ←本体のソースコード
│ │ ├── NNmodelConsole ←コンソールのソースコード
│ │ ├── NNmodelDLL ←DLLのソースコード
├── Readme.txt
├── train-file ←作業フォルダ
│ ├── train-images.idx3-ubyte ←ここからダウンロードして配置
│ └── train-labels.idx1-ubyte ←ここからダウンロードして配置
└── 使用例
├── 例1_mnistデモ.gif
├── 例2_オリジナルデモ.gif
├── 例3_オリジナルひらがなデモ.gif
└── 例4_オリジナル14マス出力層3デモ.gif
MNISTデータ(文字データ)は、ここからダウンロードする必要があります。
今回は、オリジナル訓練データを追加できるようにしてみた。
なので、MNIST データに頼らずとも オリジナル訓練データを作成することが出来ます。
※但し、オリジナル訓練データを作成するのは手作業で地道にやるしかないので、かなりしんどいです(;'∀')。
例① ネットワーク[784 100 10]の数字判定(入力層28x28、出力10)
例② ネットワーク[784 120 70 35 15 10]の数字判定(入力層28x28、出力10)
例③ ネットワーク[1764 120 70 35 15 10]のひらがな判定(入力層42x42、出力10)
例④ ネットワーク[196 81 3]の出力が3の場合の(/ + o)判定(入力層14x14、出力3)
このように、入力層と出力層と中間層を変更できるようし、
オリジナル訓練データを作成し学習できるようにした。
以下に例を示す。
MNIST訓練データの利用
例① ネットワーク[784 100 10]の数字判定
入力層28x28、出力10
グリッドの設定
「28x28(784)size10」を指定して「セット」ボタンを押す。
「訓練data」の設定
訓練データ
train-images.idx3-ubyte
train-labels.idx1-ubyte
のファイルはここからダウンロードしてtrain-fileフォルダ(作業フォルダ)に配置する。
作業フォルダはデフォルトでは「train-file」となっている。
ダウンロードしたMNIST データセットの読み込みの確認方法
アプリケーションと同じフォルダに「setting.txt」ファイルがあればこれを削除、もしくは名称変更すれば初期起動と同じとなる。初期起動の状態で、コマンドはそのままで、「MNIST read」ボタンを押してMNIST 訓練データ(train-images.idx3-ubyte、train-labels.idx1-ubyte)を読み込み成功するとreading.tradingdata reading..と表示される。次に「Index」に0~5万9999の範囲の数字を入力し「MNIST view」ボタンを押した際に、グリッドに数字が表示されれば、正常にMNIST データセットが読み込まれた。(以下のgif画像参照)
MNIST訓練データは28x28で固定なので入力層を変更できない。
※このMNISTの訓練データは、オリジナル訓練データの学習では必要ではない。
学習した内容を記録するファイル名を「weightとbiases」に指定する。
以下の形式で保存されていく。
8 ←学習回数
network=[array([784,50,10])] ←ネットワーク
biases=[array([-0.828435051648776]・・・,[-1.896426398453763])] ←バイアスの値weights=[array(-0.924953936537927,0.02・・・,-3.377555057371262)] ←重みの値
MNIST データでは「訓練data」のファイル名は関係ない
「weightとbiases」の設定
学習した内容を記録するファイル名を「weightとbiases」に指定する。
コマンド
network=784 500 10,epochs=10,mini_batch_size=10,eta=3.0,testdata_n=700,n_test=100,roopcnt=100,outputlist=0 1 2 3 4 5 6 7 8 9
以下コマンドの説明
コマンドは param1=aaaa,param2=bb,param3=cccc,param4=dddd,のようにパラメータ=値と紐付けされて、カンマで区切られている。
network=784 500 10
ネットワークを記述するMNIST データの「入力層」=784、「出力層」=10で固定。隠れ層は任意、それぞれを半角スペースで区切る。
outputlist=0 1 2 3 4 5 6 7 8 9
outputlistに正答を記述し、紐付けする。これもデフォルトのまま変更しないものとし、それぞれは半角スペースで区切る。
testdata_n=700,n_test=100
testdata_nは、MNIST データの6万からランダムで切り出すデータ要素数なので、6万より小さい値を設定する。n_testはテストデータに相当するのでオリジナル訓練データ数、testdata_nより小さい値でないといけない。(オリジナル訓練データ数≧testdata_n>n_test)
epochs=3,mini_batch_size=10,eta=2.1
はそれぞれ、学習回数、バッチ数、学習率
roopcnt=100
はroopcnt=1でもよい。データ要素から、testdata_n, n_testで
指定数のランダムで選び学習するのをroopcnt回繰り返す。
以上の、コマンドやファイル名等、決めたら一旦「設定保存」ボタンを押すと
アプリケーションと同じフォルダに「setting.txt」が作成される。
再起動時に、環境を復元するのでエラーで落ちた際に復帰しやすい。
学習させる
以上、コマンドを設定したら「MNISTを使った学習」ボタンを押すと「weightとbiases」に指定したファイルに学習した重みとバイアスが記録される。中断させる場合は「MNISTを使った学習」ボタンとなりの「 || 」ボタンを押す。重みと、バイアスを記録するファイル名を「BW_MNIST.txt」とした場合、正答率が「BW_MNIST.txt_正答率.log」としてファイルに記録される。
文字解析
「表示をリセット」ボタンを押す。グリッドにマウスで数字「0123456789」の1つを描画し「MNIST使った解析」ボタンを押すと、「weightとbiases」に指定したファイルを利用し機械判定されて結果が表示される。
使用している様子のgif画像
コマンド
network=784 100 10,epochs=10,mini_batch_size=10,eta=3.0,testdata_n=700,n_test=100,roopcnt=100,outputlist=0 1 2 3 4 5 6 7 8 9
オリジナル訓練データの作成
例② ネットワーク[784 120 70 35 15 10]の数字判定
入力層28x28、出力10.
オリジナル訓練データを作成し学習させるので、学習させるまえに
100以上の手書きデータを事前に入力する必要があるのでしんどい。
入力層はMNIST データと同じ28x28とし変更しないものとする。
グリッドの設定
「28x28(784)size10」を指定して「セット」ボタンを押す。
「訓練data」の設定
オリジナル訓練データを保存するファイル名を「訓練data」に指定する。
train-fileフォルダの「NewDataset_28x28.txt」に私が、マウス入力した数字「0123456789」のオリジナル訓練データが937個登録しているので、「訓練data」に「NewDataset_28x28.txt」ファイルを指定する。「28x28(784)size10」をリストから選択し「セット」ボタンを押す。次に「MYDATAを読み込む」ボタンを押す。「Index」に0~937の数字を入力し「MYDATA View」ボタンを押してグリッドに表示されれば正常に読み込まれた。(以下gif画像参照)
「weightとbiases」の設定
学習した内容を記録するファイル名を「weightとbiases」に指定する。前述と、同じファイル名だとMNIST データで学習したファイルが上書きされるので、適当な名称にしておくとよいかと思う。
コマンド
network=784 120 70 35 15 10,epochs=15,mini_batch_size=10,eta=1.5,testdata_n=1000,n_test=100,roopcnt=100,outputlist=0 1 2 3 4 5 6 7 8 9
以下コマンドの説明
コマンドは param1=aaaa,param2=bb,param3=cccc,param4=dddd,のようにパラメータ=値と紐付けされて、カンマで区切られている。
network=784 120 70 35 15
ネットワークを記述するMNIST データの「入力層」=784、「出力層」=10。隠れ層は任意、それぞれを半角スペースで区切る。
outputlistに正答を記述する
outputlist=0 1 2 3 4 5 6 7 8 9
これもデフォルトのまま変更しないものとする。(半角スペースで区切る。)
testdata_nは、オリジナル訓練データからランダムで切り出すデータ要素数なので、オリジナル訓練データ数より小さい値を設定する。
testdata_n=1000
もしオリジナル訓練データ数より大きい値を設定していれば最大値が自動的に指定される。
次に、n_testにテスト数を記述する
n_test=100
これはオリジナル訓練データ数、testdata_nよりも小さい値でないといけない。もし、訓練データ数が100であれば、n_test=50くらいが無難である。
(オリジナル訓練データ数≧testdata_n>n_test)
epochs=15,mini_batch_size=10,eta=1.5
はそれぞれ、学習回数、バッチ数、学習率
roopcnt=100
はroopcnt=1でもよい。データ要素から、testdata_n, n_testで
指定数のランダムで選び学習するのをroopcnt回繰り返す。
コマンドやファイル名、入力層決めたら一旦「設定保存」で状態を記録し再起動時に、環境を再現出来るようにしておくとエラーで落ちた際に復帰しやすい。
オリジナル訓練データの追加
コマンドで、outputlistを記述したらグリッドに「0 1 2 3 4 5 6 7 8 9」のいずれかを記述し解答に正解を記述する。グリッドに「0」を記述したら解答には「0」を記述する。この順番はどちらでもよい。「訓練データ追加」ボタン押すとグリッドはクリアされて、オリジナル訓練データが「訓練data」に記載されたファイル(NewDataset_42x42.txt)に追記される。この作業を繰り返す。
学習させる
以上、オリジナル訓練データを十分に作成し、コマンドを設定したら「MYDATAを使った学習」ボタンを押すと「weightとbiases」に指定したファイルに学習した重みとバイアスが記録される。中断させる場合は「MYDATAを使った学習」ボタンとなりの「 || 」ボタンを押す。重みと、バイアスを記録するファイル名を「BW_オリジナル.txt」とした場合、正答率が「BW_オリジナル.txt_正答率.log」としてファイルに記録される。
文字解析
「表示をリセット」ボタンを押す。グリッドにマウスで数字「0123456789」の1つを描画し「MYDATA使った解析」ボタンを押すと、「weightとbiases」に指定したファイルを利用し機械判定されて結果が表示される。
使用している様子のgif画像
コマンド
network=784 120 70 35 15 10,epochs=15,mini_batch_size=10,eta=1.5,testdata_n=1000,n_test=100,roopcnt=100,outputlist=0 1 2 3 4 5 6 7 8 9
例③ ネットワーク[1764 120 70 35 15 10]のひらがな判定
入力層42x42、出力10.
グリッドの設定
「42x42(1764)size7.5」を指定して「セット」ボタンを押す。
「訓練data」の設定
オリジナル訓練データを保存するファイル名を「訓練data」に指定する。
train-fileフォルダの「NewDataset_42x42_ひらがな.txt」に私が、マウス入力したひらがな「あいうえおかきくこ」のオリジナル訓練データが284個登録しているので、「訓練data」に「NewDataset_42x42_ひらがな.txt」ファイルを指定する。「42x42(1764)size7.5」をリストから選択し「セット」ボタンを押す。次に「MYDATAを読み込む」ボタンを押す。「Index」に0~284の数字を入力し「MYDATA View」ボタンを押してグリッドに表示されれば正常に読み込まれた。(以下gif画像参照)
「weightとbiases」の設定
学習した内容を記録するファイル名を「weightとbiases」に指定する。
コマンド
network=1764 120 70 35 15 10,epochs=30,mini_batch_size=10,eta=1.5,testdata_n=1000,n_test=100,roopcnt=100,outputlist=あ い う え お か き く け こ
以下コマンドの説明
コマンドは param1=aaaa,param2=bb,param3=cccc,param4=dddd,のようにパラメータ=値と紐付けされて、カンマで区切られている。
network=1764 120 70 35 15 10
ネットワークを記述するMNIST データの「入力層」=1764、「出力層」=10。隠れ層は任意、それぞれを半角スペースで区切る。
outputlist=あ い う え お か き く け こ
入力層を決定したら次に出力層を決定する。outputlistに出力の0~9番目の解答を紐付けする。「outputlist=あ い う え お か き く け こ」(半角スペースで区切る。)だと
0=あ 5=か
1=い 6=き
2=う 7=く
3=え 8=け
4=お 9=こ
それぞれの出力と解答が紐付けさせる。
testdata_nは、オリジナル訓練データからランダムで切り出すデータ要素数なので、オリジナル訓練データ数より小さい値を設定する。
testdata_n=1000
もしオリジナル訓練データ数より大きい値を設定していれば最大値が自動的に指定される。
次に、n_testにテスト数を記述する
n_test=100
これはオリジナル訓練データ数、testdata_nよりも小さい値でないといけない。
(オリジナル訓練データ数≧testdata_n>n_test)
epochs=30,mini_batch_size=10,eta=1.5
はそれぞれ、学習回数、バッチ数、学習率
roopcnt=100
はroopcnt=1でもよい。データ要素から、testdata_n, n_testで
指定数のランダムで選び学習するのをroopcnt回繰り返す。
コマンドやファイル名、入力層決めたら一旦「設定保存」で状態を記録し再起動時に、環境を再現出来るようにしておくとエラーで落ちた際に復帰しやすい。
オリジナル訓練データの追加
コマンドで、outputlistを記述したらグリッドに「あ い う え お か き く け こ」のいずれかを記述し解答に正解を記述する。グリッドに「あ」を記述したら解答には「あ」を記述する。この順番はどちらでもよい。「訓練データ追加」ボタン押すとグリッドはクリアされて、オリジナル訓練データが「訓練data」に記載されたファイル(NewDataset_42x42_ひらがな.txt)に追記される。この作業を繰り返す。
学習させる
以上、オリジナル訓練データを十分に作成し、コマンドを設定したら「MYDATAを使った学習」ボタンを押すと「weightとbiases」に指定したファイルに学習した重みとバイアスが記録される。中断させる場合は「MYDATAを使った学習」ボタンとなりの「 || 」ボタンを押す。重みと、バイアスを記録するファイル名を「BW_オリジナル.txt」とした場合、正答率が「BW_オリジナル.txt_正答率.log」としてファイルに記録される。
文字解析
「表示をリセット」ボタンを押す。グリッドにマウスでひらがな「あいうえおかきくけこ」の1つを描画し「MYDATA使った解析」ボタンを押すと、「weightとbiases」に指定したファイルを利用し機械判定されて結果が表示される。
使用している様子のgif画像
コマンド
network=1764 120 70 35 15 10,epochs=30,mini_batch_size=10,eta=1.5,testdata_n=1000,n_test=100,roopcnt=100,outputlist=あ い う え お か き く け こ
例④ ネットワーク[196 81 3]の出力が3の場合の(/ + o)判定
入力層14x14、出力3.
グリッドの設定
「14x14(196)size20」を指定して「セット」ボタンを押す。
「訓練data」の設定
オリジナル訓練データを保存するファイル名を「訓練data」に指定する。
train-fileフォルダの「NewDataset_14x14_出力3.txt」に私が、マウス入力した「/ + o」のオリジナル訓練データが132個登録しているので、「訓練data」に「NewDataset_14x14_出力3.txt」ファイルを指定する。「14x14(196)size20」をリストから選択し「セット」ボタンを押す。次に「MYDATAを読み込む」ボタンを押す。「Index」に0~132の数字を入力し「MYDATA View」ボタンを押してグリッドに表示されれば正常に読み込まれた。(以下gif画像参照)
「weightとbiases」の設定
学習した内容を記録するファイル名を「weightとbiases」に指定する。
コマンド
network=196 81 3,epochs=3,mini_batch_size=10,eta=2.1,testdata_n=1000,n_test=10,roopcnt=100,outputlist=/ + o
以下コマンドの説明
コマンドは param1=aaaa,param2=bb,param3=cccc,param4=dddd,のようにパラメータ=値と紐付けされて、カンマで区切られている。
network=196 81 3
ネットワークを記述するMNIST データの「入力層」=196、「出力層」=3。隠れ層は任意、それぞれを半角スペースで区切る。
outputlist=/ + o
入力層を決定したら次に出力層を決定する。
outputlistに出力の0~2番目の解答を紐付けする。「outputlist=/ + o」だと
0=/
1=+
2=o
それぞれの出力と解答が紐付けさせる。
入力層と出力層を決定したら、オリジナル訓練データを作成していく
testdata_nは、オリジナル訓練データからランダムで切り出すデータ要素数なので、オリジナル訓練データ数より小さい値を設定する。
testdata_n=1000
もしオリジナル訓練データ数より大きい値を設定していれば最大値が自動的に指定される。
次に、n_testにテスト数を記述する
n_test=10
これはオリジナル訓練データ数、testdata_nよりも小さい値でないといけない。
(オリジナル訓練データ数≧testdata_n>n_test)
epochs=3,mini_batch_size=10,eta=2.1
はそれぞれ、学習回数、バッチ数、学習率
roopcnt=100
はroopcnt=1でもよい。データ要素から、testdata_n, n_testで
指定数のランダムで選び学習するのをroopcnt回繰り返す。
コマンドやファイル名、入力層決めたら一旦「設定保存」で状態を記録し再起動時に、環境を再現出来るようにしておくとエラーで落ちた際に復帰しやすい。
オリジナル訓練データの追加
コマンドで、outputlistを記述したらグリッドに「/ + o」のいずれかを記述し解答に正解を記述する。グリッドに「/」を記述したら解答には「/」を記述する。この順番はどちらでもよい。「訓練データ追加」ボタン押すとグリッドはクリアされて、オリジナル訓練データが「訓練data」に記載されたファイル(NewDataset_14x14_出力3.txt)に追記される。この作業を繰り返す。
学習させる
以上、オリジナル訓練データを十分に作成し、コマンドを設定したら「MYDATAを使った学習」ボタンを押すと「weightとbiases」に指定したファイルに学習した重みとバイアスが記録される。中断させる場合は「MYDATAを使った学習」ボタンとなりの「 || 」ボタンを押す。重みと、バイアスを記録するファイル名を「BW_オリジナル.txt」とした場合、正答率が「BW_オリジナル.txt_正答率.log」としてファイルに記録される。
文字解析
「表示をリセット」ボタンを押す。グリッドに記号「/ + o」の1つを描画し「MYDATA使った解析」ボタンを押すと、「weightとbiases」に指定したファイルを利用し機械判定されて結果が表示される。
使用している様子のgif画像
コマンド
network=196 81 3,epochs=3,mini_batch_size=10,eta=2.1,testdata_n=1000,n_test=10,roopcnt=100,outputlist=/ + o
ざっくりな説明
入力層と出力層と中間層を変更できるようし、オリジナル訓練データを作成し
学習できるようにした。
コマンド
コマンドは param1=aaaa,param2=bb,param3=cccc,param4=dddd, のようにパラメータ=値と紐付けされて、カンマで区切られている。
network //ネットワーク構造 examp network=784 30 10のように半角スペースで区切る。行列が6の場合入力は36となり、行列が42の場合入力は1764となる。
epochs, //世代(学習回数) examp 30
mini_batch_size, //ミニバッチサイズ examp 10
eta //学習率 examp 3.0
testdata_n //訓練データ数。もし訓練データよりも大きい値を指定した場合、最大値が入る。
n_test //訓練データからのテストする要素数。全体のtestdata_nから、ランダムでn_test選ばれ、残りが教師データとなる。オリジナル訓練データ数、testdata_nよりも小さい値でないといけない。(オリジナル訓練データ数≧testdata_n>n_test)
roopcnt //「ランダムでテストを選び、学習回数学習する。」を、roopcnt繰り返す。
outputlist //正答(出力)となるリスト、数値だけでなくひらがなや英数字も選択できるようにした。出力は2以上の任意数で、半角スペースで区切る。
作業フォルダ
ここに訓練データ等のファイルを置く。デフォルトでは解凍したアプリケーションと同じフォルダの「train-file」フォルダが作業フォルダとなっている。
変更する場合、ボタン押すとコモンダイアログが開くので参照したいフォルダにある適当なファイルを選択して、開く(選択したファイルが開かれるわけではない)を押すとパスが指定される。
WeightとBiases
重みと、バイアスを記録するファイル名
コマンドで記載されたnetwork=784 50 10と、ファイルに記述された
ネットワークが異なる場合、再利用出来ない。
8 ←学習回数
network=[array([784,50,10])] ←ネットワーク
biases=[array([-0.828435051648776]・・・,[-1.896426398453763])] ←バイアスの値weights=[array(-0.924953936537927,0.02・・・,-3.377555057371262)] ←重みの値
訓練data
オリジナル訓練データのファイル名
ヘッダー部分とデータ要素として、以下の形式で保存される。
count=要素数,row=入力行数,col=入力列数
d=要素のグリッド部分を0と1で記録,anser=解答
設定保存
設定をアプリケーションと同じフォルダの「setting.txt」ファイルに記録する。これは再起動時に読み込まれ復元される。
正答率のログ
重みと、バイアスを記録するファイル名を「BW_オリジナル.txt」とした場合、正答率を「BW_オリジナル.txt_正答率.log」ファイルに記録する
roopcnt回数
Epoch {学習回数} : {正解数} / {テスト数}
今回は、PythonのNetwork2の畳み込みの機能は入れていない。
以上