メインモジュールの実装|Excel VBAでMNIST機械学習
本ページは「ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装」を参考にニューラルネットワークを作成していきます。参考書籍では「Affineレイヤ」「ReLUレイヤ」「Softmax-with-Lossレイヤ」という3つのレイヤを作成し、それらを組み合わせることでニューラルネットワークを構築していきます。本サイトでも同じように3つのレイヤをVBAで作成し実装していきます。
これまでに「Affineレイヤ」「ReLUレイヤ」「Softmax-with-Lossレイヤ」、それらを組み合わせたニューラルネットワーク本体である「TwoLayerNetクラス」をVBAで実装しました。
本ページではニューラルネットワークを呼び出し、学習を行うための機能をメインモジュールを実装していきます。また、別ページではこのメインモジュール内に推論を行う機能も追加します。つまり、マクロとして実行するのは今回実装するメインモジュールの関数のみとなっています。
メインモジュールの機能
メインモジュールでは「学習」と「推論」の2つの機能を持ちます。
(本ページでは「学習」の機能のみを実装します)
ニューラルネットワークの学習
「学習」とは、順伝播と逆伝播を繰り返し、重みパラメータとバイアスパラメータの値を徐々に更新していき『適正な値』を見つけ出すことを意味しています。
例えば「2」と描かれた画像を入力したら「2」という値を出力、「3」と描かれた画像を入力したら「3」という値を出力するように、「0〜9」どの数字で”誰が描いた数字”だとしても正しく出力できるようなパラメータ値を見つけます。
適切なパラメータの値はこれまでに実装したクラス/レイヤの関数を順番に実行していくことで導き出すことができます。導き出す方法はいくつかありますが、今回実装している方法は「誤差逆伝播法」という1番シンプルで簡単な仕組みです。
とても極端な話をすれば「TwoLayerNetクラス」の関数「gradient」と関数「ParamsUpdate」をループ処理に入れるだけで学習が可能になっています。(引数を準備する必要がありますが)
ニューラルネットワークの推論
「推論」とは、入力された画像に何の数字が描かれているかをニューラルネットが自ら考え導き出すことです。
処理としては非常にシンプルで「学習」で求めた適切なパラメータの値をそのまま使い、順伝播を1回行うだけです。この順伝播によって出力された値がニューラルネットワークの最終的な答えとなります。
1度学習済みのパラメータさえ求めることができれば同じニューラルネットワークに入れることで何度でも使い回すことができます。つまり今回の場合、1度学習を終えパラメータ値が取得できればMNISTと同じ構成の画像データに描かれている「0~9」のいずれかの数字を当てるという処理は何度でも行ことができます。
ただ注意しないといけないのは、正解できる確率(精度)は学習の内容によるという点です。
正しく十分な学習ができていれば正解をうまく導き出すことができますし、逆に学習が不十分の場合はうまく導き出すことができません。
そのため学習中に一定間隔で精度を求める機能を追加していきます。
これにより現在の学習状態での学習の精度を随時確認することができるので、精度を確認しつつ自分の好きなタイミングで学習を終了させることができます。
メインモジュールの実装
まずは標準モジュールで「Main」というモジュールを作成します。
これまでに実装したクラス/レイヤと揃えるため、本モジュールでも「Option Base 1」を使い配列を「1」スタートにします。
以下はメインモジュール(学習のみ)の全コードです。
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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
'VBA Main(module) Option Explicit Option Base 1 #If Win64 Then Declare PtrSafe Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer #Else Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer #End If Dim input_size As Long '入力層のニューロン数 Dim hidden_size As Long '隠れ層のニューロン数 Dim output_size As Long '出力層のニューロン数 Dim MinLoss As Double '最小Loss値 Dim MaxEpoc As Long '最大エポック数 Dim LearningRate As Double '学習率 Dim batch_size As Long 'ミニバッチサイズ Dim train_size As Long 'mnist_trainの総データ数(default:60000) Dim test_size As Long 'mnist_testの総データ数(default:10000) Public ParamsSheet As Worksheet '書き出し用シート Public ParamsCheck As Boolean 'シート確認用変数 '―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― Sub Train() '********************************************************************** ' ' ユーザ-設定(ハイパーパラメータ設定) ' '********************************************************************** 'ユニット数の設定(Input:784 / Output:10は変更不可) input_size = 784 '28x28(px) hidden_size = 64 '学習結果に応じて変更可 output_size = 10 '0~9 '学習設定 batch_size = 100 'バッチサイズ(Default:100) LearningRate = 0.01 '学習率(Default:0.01) train_size = ws_mnist_train.Cells(Rows.count, 1).End(xlUp).Row 'mnist_trainの総データ数(default:60000) test_size = ws_mnist_test.Cells(Rows.count, 1).End(xlUp).Row 'mnist_testの総データ数(default:10000) '学習終了条件 MinLoss = 0.01 '目標Loss値 MaxEpoc = 500 '最大エポック数(学習回数) '********************************************************************** ' ' 学習開始 ' '********************************************************************** '学習途中データの確認----------------------------------------------------- ParamsCheck = False Dim ws As Worksheet Dim flag As Boolean Dim res As String Dim msg As String msg = "学習モデルのデータがあります。" & vbLf & _ "続きから学習を始めますか?" & vbLf & vbLf & _ "[いいえ]を押すと新規モデルとして学習を始めます。" For Each ws In Worksheets If ws.Name = "Parameters" Then flag = True Next ws If flag = True Then res = MsgBox(msg, vbYesNoCancel + vbInformation, "学習データの再利用") If res = vbYes Then ParamsCheck = True Set ParamsSheet = Worksheets.Item("Parameters") ElseIf res = vbNo Then ParamsCheck = False flag = False label1: Dim SheetName As String SheetName = InputBox("既存のモデル(シート)名を入力して下さい。", "モデル名変更") If StrPtr(SheetName) = 0 Then MsgBox "キャンセルします。" Exit Sub ElseIf SheetName = "" Then MsgBox "モデル名を入力して下さい。" GoTo label1 End If For Each ws In Worksheets If ws.Name = SheetName Then flag = True Next ws If flag = True Then MsgBox "「" & SheetName & "」は既に存在します。" & vbLf & "別の名称を入力し直してください。" GoTo label1 End If Worksheets.Item("Parameters").Name = SheetName Set ParamsSheet = Worksheets.add(After:=Worksheets(1)) ParamsSheet.Name = "Parameters" ElseIf res = vbCancel Then MsgBox "キャンセルします。" Exit Sub End If Else Set ParamsSheet = Worksheets.add(After:=Worksheets(1)) ParamsSheet.Name = "Parameters" End If '---------------------------------------------------------------------- Dim network As TwoLayerNet Set network = New TwoLayerNet 'ニューラルネットワークの初期化 Call network.Initialize(input_size, hidden_size, output_size, ParamsSheet) Dim eRow As Long Dim eCol As Long Dim Datas() As Double Dim c As Long Dim r As Long Dim i As Long Dim epoc As Long Dim sumE As Double Dim sumAcc As Long Dim cnt As Long Dim label As Integer Dim t() As Long Dim DataRows() As Long With ws_mnist_train eRow = .Cells(Rows.count, 1).End(xlUp).Row eCol = .Cells(1, Columns.count).End(xlToLeft).Column ReDim Datas(eCol - 1) Do '最大エポック数に到達したら学習終了 If epoc >= MaxEpoc Then Exit Do sumAcc = 0 sumE = 0 cnt = 0 '学習データ行をランダム取得 ReDim DataRows(batch_size) DataRows = Functions.GetRandomRow(batch_size, train_size) For r = 1 To UBound(DataRows) cnt = cnt + 1 For c = 2 To eCol Datas(c - 1) = .Cells(DataRows(r), c).Value / 255 '正規化 Next c label = .Cells(DataRows(r), 1).Value t = Functions.one_hot_t(output_size, label) 'labelをone-hot化 Call network.gradient(Datas, t) '重み/バイアスパラメータの勾配を求める sumE = sumE + network.E If network.accuracy = True Then sumAcc = sumAcc + 1 End If Call network.ParamsUpdate(LearningRate) 'Affinレイヤの重み/バイアスパラメータを更新 '[F7]キーが押下されたら学習終了 If Functions.KeyPress = True Then Call network.ExportParameters(ParamsSheet) MsgBox "学習終了" & vbLf & "学習結果はシート(Parameters)に書き出しました。" Exit Sub End If DoEvents Next r epoc = epoc + 1 'テストデータ(未学習データ)で精度確認------------------------------------------------------------- Dim testData() As Double Dim testLabel As Long Dim testDataRows() As Long Dim test_acc() As Double Dim test_acc_size As Long Dim test_cnt As Long test_acc_size = 100 ReDim testData(input_size) ReDim testDataRows(test_acc_size) testDataRows = Functions.GetRandomRow(test_acc_size, test_size) test_cnt = 0 For r = 1 To UBound(testDataRows) For c = 2 To eCol testData(c - 1) = ws_mnist_test.Cells(testDataRows(r), c).Value / 255 '正規化 Next c testLabel = ws_mnist_test.Cells(testDataRows(r), 1).Value If network.test_accuracy(testData, testLabel) = True Then test_cnt = test_cnt + 1 End If Next r '-------------------------------------------------------------------------------------------- '学習の途中経過をイミディエイトウィンドウに表示 Debug.Print epoc & "回目: " & sumE / cnt & " 正解率: " & (sumAcc / cnt) * 100 & "% テスト正解率" & (test_cnt / test_acc_size) * 100 & "% " Loop Until sumE / cnt < MinLoss End With '学習済みパラメータを書き出し Call network.ExportParameters(ParamsSheet) MsgBox "学習終了" & vbLf & "学習結果はシート(Parameters)に書き出しました。" End Sub |
以下では上記のコードでどのような処理を行っているかを解説していきます。
※メインモジュールではこれまでに実装したクラス/レイヤ/関数を全て呼び出します。
適宜、各実装ページに戻り本モージュールとの繋がりやレイヤごとの繋がりを確認しましょう。
Sub Train
関数「Train」ではこれまでに実装したレイヤや関数を呼び出してニューラルネットワークの学習を行う関数です。
ここでは「この関数がどのような処理を行なっているのか」を部分ごとに分けて上から順に説明していきます。
Windows APIの宣言
まずはメインモジュールの設定を行います。
「Functions」モジュールで実装した関数「KeyPress」を実行するためにWindows APIの「GetAsyncKeyState関数」を宣言します。(詳しくは「GetAsyncKeyState関数」ページを参照ください)
1 2 3 4 5 6 7 8 |
Option Explicit Option Base 1 #If Win64 Then Declare PtrSafe Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer #Else Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer #End If |
変数の宣言
次に変数の宣言を行います。
プロシージャ外で宣言する必要のない変数もありますが、ハイパーパラメータ類は1つに固めておきたかったのでここでまとめて宣言しています。中には「Public」を使ってグローバル変数として宣言しているものもあるので注意してください。
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 |
Option Explicit Option Base 1 #If Win64 Then Declare PtrSafe Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer #Else Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer #End If Dim input_size As Long '入力層のニューロン数 Dim hidden_size As Long '隠れ層のニューロン数 Dim output_size As Long '出力層のニューロン数 Dim MinLoss As Double '最小Loss値 Dim MaxEpoc As Long '最大エポック数 Dim LearningRate As Double '学習率 Dim batch_size As Long 'ミニバッチサイズ Dim train_size As Long 'mnist_trainの総データ数(default:60000) Dim test_size As Long 'mnist_testの総データ数(default:10000) Public ParamsSheet As Worksheet '書き出し用シート Public ParamsCheck As Boolean 'シート確認用変数 |
ハイパーパラメータ設定
ここからは「Sub Train()」プロシージャ内のコードです。
はじめに、学習の初期設定ともいえるハイパーパラメータを設定します。
ハイパーパラメータとは各層のニューロン数や学習率などのニューラルネットワークの根源となるパラメータのことをいいます。このハイパーパラメータの値は学習前に変更することが可能で、学習結果に応じて変更したり自分の好きな設定で学習を行うことができます。
今回作成したニューラルネットワークではハイパーパラメータの値を変更できるものは少ないですが、コードを書き足したり、レイヤを増やすことで隠れ層の数を増やしたり、活性化関数を変更したりすることも可能になります。(ニューラルネットワークについて理解が深まったらぜひコードを書き換えてみてください)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
'ユニット数の設定(Input:784 / Output:10は変更不可) input_size = 784 '28x28(px) hidden_size = 64 '学習結果に応じて変更可 output_size = 10 '0~9 '学習設定 batch_size = 100 'バッチサイズ(Default:100) LearningRate = 0.01 '学習率(Default:0.01) train_size = ws_mnist_train.Cells(Rows.count, 1).End(xlUp).Row 'mnist_trainの総データ数(default:60000) test_size = ws_mnist_test.Cells(Rows.count, 1).End(xlUp).Row 'mnist_testの総データ数(default:10000) '学習終了条件 MinLoss = 0.01 MaxEpoc = 500 |
基本的に今回変更できるのは以下のハイパーパラメータだけです。
hidden_size:隠れ層のニューロン数
batch_size:バッチサイズ(まとめて何個のデータを学習するかを決める)
LearningRate:学習率(この値が小さいほど学習時間は長くなるが精度の高い学習ができる)
train_size:学習用データのデータ数
test_size:テスト用データのデータ数
MinLoss:最少Loss値(Loss値がこの値になったら学習を終了する)
MaxEpoc:最大エポック数(batch_size×MaxEpoc個のデータを学習したら学習を終了する)
batch_size、MaxEpocについては本来の意味とは少し違うので注意してください。
(詳しい説明は後ほど出てきます)
学習途中データの確認
次に学習途中データの確認を行います。
今回実装するニューラルネットワークは最終的に「Parameters」という名前のシートを作成しそこに結果を書き出します。ここでは既に「Parameters」というシートが存在するかを確認し、以降でどの処理を行うかをユーザーに選択させます。
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 62 |
ParamsCheck = False Dim ws As Worksheet Dim flag As Boolean Dim res As String Dim msg As String msg = "学習モデルのデータがあります。" & vbLf & _ "続きから学習を始めますか?" & vbLf & vbLf & _ "[いいえ]を押すと新規モデルとして学習を始めます。" For Each ws In Worksheets If ws.Name = "Parameters" Then flag = True Next ws If flag = True Then res = MsgBox(msg, vbYesNoCancel + vbInformation, "学習データの再利用") If res = vbYes Then ParamsCheck = True Set ParamsSheet = Worksheets.Item("Parameters") ElseIf res = vbNo Then ParamsCheck = False flag = False label1: Dim SheetName As String SheetName = InputBox("既存のモデル(シート)名を入力して下さい。", "モデル名変更") If StrPtr(SheetName) = 0 Then MsgBox "キャンセルします。" Exit Sub ElseIf SheetName = "" Then MsgBox "モデル名を入力して下さい。" GoTo label1 End If For Each ws In Worksheets If ws.Name = SheetName Then flag = True Next ws If flag = True Then MsgBox "「" & SheetName & "」は既に存在します。" & vbLf & "別の名称を入力し直してください。" GoTo label1 End If Worksheets.Item("Parameters").Name = SheetName Set ParamsSheet = Worksheets.add(After:=Worksheets(1)) ParamsSheet.Name = "Parameters" ElseIf res = vbCancel Then MsgBox "キャンセルします。" Exit Sub End If Else Set ParamsSheet = Worksheets.add(After:=Worksheets(1)) ParamsSheet.Name = "Parameters" End If |
ユーザーの選択により処理は以下のように分岐します。
Parametersが存在しない場合 → 学習開始
Parametersが存在する場合 → 続きから学習をする(Parametersに学習結果を上書き)
→ 新規で学習をする(現在のParametersを別名に変更する)
→ キャンセル
Parametersが存在する場合はメッセージボックスでさらに分岐しますが、学習済みのシート(つまりはParameters)がない場合はすぐに学習が始まります。
ここでは上記の分岐を行うために「シートの設定」と変数「ParamsCheck」の設定を行います。(ParamsCheckはグローバル変数なのでこの値を使ってTwoLayerNetクラスなどの処理を分岐させます)
学習
次にTwoLayerNetのインスタンスを作成し、ループ分を使って学習を行なっていきます。
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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
Dim network As TwoLayerNet Set network = New TwoLayerNet 'ニューラルネットワークの初期化 Call network.Initialize(input_size, hidden_size, output_size, ParamsSheet) Dim eRow As Long Dim eCol As Long Dim Datas() As Double Dim c As Long Dim r As Long Dim i As Long Dim epoc As Long Dim sumE As Double Dim sumAcc As Long Dim cnt As Long Dim label As Integer Dim t() As Long Dim DataRows() As Long With ws_mnist_train eRow = .Cells(Rows.count, 1).End(xlUp).Row eCol = .Cells(1, Columns.count).End(xlToLeft).Column ReDim Datas(eCol - 1) Do '最大エポック数に到達したら学習終了 If epoc >= MaxEpoc Then Exit Do sumAcc = 0 sumE = 0 cnt = 0 '学習データ行をランダム取得 ReDim DataRows(batch_size) DataRows = Functions.GetRandomRow(batch_size, train_size) For r = 1 To UBound(DataRows) cnt = cnt + 1 For c = 2 To eCol Datas(c - 1) = .Cells(DataRows(r), c).Value / 255 '正規化 Next c label = .Cells(DataRows(r), 1).Value t = Functions.one_hot_t(output_size, label) 'labelをone-hot化 Call network.gradient(Datas, t) '重み/バイアスパラメータの勾配を求める sumE = sumE + network.E If network.accuracy = True Then sumAcc = sumAcc + 1 End If Call network.ParamsUpdate(LearningRate) 'Affinレイヤの重み/バイアスパラメータを更新 '[F7]キーが押下されたら学習終了 If Functions.KeyPress = True Then Call network.ExportParameters(ParamsSheet) MsgBox "学習終了" & vbLf & "学習結果はシート(Parameters)に書き出しました。" Exit Sub End If DoEvents Next r epoc = epoc + 1 'テストデータ(未学習データ)で精度確認------------------------------------------------------------- Dim testData() As Double Dim testLabel As Long Dim testDataRows() As Long Dim test_acc() As Double Dim test_acc_size As Long Dim test_cnt As Long test_acc_size = 100 ReDim testData(input_size) ReDim testDataRows(test_acc_size) testDataRows = Functions.GetRandomRow(test_acc_size, test_size) test_cnt = 0 For r = 1 To UBound(testDataRows) For c = 2 To eCol testData(c - 1) = ws_mnist_test.Cells(testDataRows(r), c).Value / 255 '正規化 Next c testLabel = ws_mnist_test.Cells(testDataRows(r), 1).Value If network.test_accuracy(testData, testLabel) = True Then test_cnt = test_cnt + 1 End If Next r '-------------------------------------------------------------------------------------------- '学習の途中経過をイミディエイトウィンドウに表示 Debug.Print epoc & "回目: " & sumE / cnt & " 正解率: " & (sumAcc / cnt) * 100 & "% テスト正解率" & (test_cnt / test_acc_size) * 100 & "% " Loop Until sumE / cnt < MinLoss End With |
複雑なように見えますが処理の流れを大雑把にみると以下の通りです。
① ランダムで学習データを取得(このとき学習データの値を0〜1の範囲で表現するため255で割る)
② ①の画像データの正解ラベルを取得しone-hot表現に変換する
③ ①と②を引数としてTwoLayerNetの関数「gradient」を実行
④ ③で取得した勾配を使い、各Affineレイヤのパラメータを更新
⑤ ①〜④の処理を「batch_size」回行う(「batch_size」回の学習結果の平均の精度を出力する)
⑥ ⑤の処理を学習終了条件を満たすまでループする
この処理の流れはミニバッチ学習から来ています。
本来のミニバッチ学習では③の処理の時点で複数の画像データをまとめてTwoLayerNetに渡し、まとめて計算を行います。(通常これを1エポックという)
しかしVBAでミニバッチ学習を行う場合、入力する画像データが増えることは配列の次元が増えることを意味します。ここでは機能の理解をメインとしているためあまり複雑な計算は避けています。そのため本来のミニバッチ学習とは少し変えた処理で、ミニバッチ学習に似せた処理をしています。(つまりミニバッチ学習自体は実装できていません)
上記の処理には書いていませんが、ループの中ではテストデータの精度確認も併せて行います。
処理の内容自体は上記の内容とほとんど同じなので割愛しますが、最終的にはこのテストデータの精度で学習の良し悪しを判断します。(詳しくは実際に学習をする際に解説します)
ここの処理は説明を聞くよりも1行1行コードを見ながら何をしているかを確認していった方が理解しやすいと思います。おそらくニューラルネットワークを学ぶ上で1番つまづきやすいのが「学習」の部分なのでここはじっくりとやっていきましょう。
学習終了処理
最後に学習終了条件を満たした際の処理を書いておきます。
ここではTwoLayerNetの関数「ExportParameters」を呼び出すだけです。
引数となる「ParamsSheet」は先の「学習途中データの確認」のコードで条件に合わせて中身のシートを変更しているため、引数自体を変える必要はありません。
1 2 3 4 |
'学習済みパラメータを書き出し Call network.ExportParameters(ParamsSheet) MsgBox "学習終了" & vbLf & "学習結果はシート(Parameters)に書き出しました。" |
まとめ
ここでは「ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装」を参考に、ニューラルネットワークで学習を行うためのメインモジュールを作成しました。
今回実装したメインモジュールの機能をまとめると以下の通りです。
Sub Train:学習を行う
長いコードにはなっていますが機能としては「学習を行う」の1つだけです。
これまでに実装してきたレイヤやクラスの関数を呼び出して学習していくので、初めのうちは少しややこしく感じるかもしれません。ただ、コードが理解できればやっている内容が思ったよりはシンプルだということがわかります。
このシンプルな内容を理解することで、ニューラルネットワークの仕組みも理解できるのでじっくり理解していってください。
今回のメインモジュールで「学習」に関するコードはすべてです。
次回はこれらのコードを使いMNIST学習を行う方法を解説していきます。
※これまでのコードをコピペして実行してもエラーが発生します。
詳しくは次回の「MNISTデータセットを学習させてみよう」を参照下さい。
参考書籍