こんにちは!
現役パラレルワーカー フクコです。
前回の記事↓に続き
来年の2月の試験に向けてE資格試験勉強中のため
ゼロつくシリーズでおなじみ
オーライリーから出版されている
ディープラーニングの本格的な入門書でよくおススメされる
「ゼロからつくる Deep Learning」本
この本↑を毎日5ページずつコツコツこなすと
約2か月間で今年中に終了するので
来年のE資格試験までにこれで基礎力をつけることにしました。(^^)
ついつい私は何もないとだらけてしまうので(笑)
毎日5ページ終わった後の記録とまとめを書いていこうと思います。
と、まとめに入る前に…
やる気を出すためのコトバをシェアします!!(主に私のやる気を出すために 笑)
「まあ、出来て当然ですけれども、仕方ないです。
できないなら しょうがないしょうがない。」
by 胡蝶 しのぶ
おなじみ私の大好きな「鬼滅の刃」から
蟲柱・胡蝶 しのぶの名言です。
鬼殺隊の剣士たちの中で唯一、
藤の花から抽出した「鬼を殺す毒」を作り出し、鬼を滅するすごいヒトです。
そして
医学にも精通しているため
普段は柱に与えられる自身の館・蝶屋敷を治療所として開放してたりします。
出来ない子でスミマセン、しのぶ様 (ついつい様づけ 笑)。もっとガンバります!! 見捨てないで~(>ー<)
やっぱり煽られるとやる気になりますよね!笑
しのぶ様、どうもありがとう! (^0^)
今日もやる気が出てきました!
よし!! 今日も頑張るぞ~! お~!!
というコトで、しのぶ様に見捨てられないためにも、今日も私はノルマをこなしますよ! 笑
ではでは、いい加減まとめに入ります。笑
その前に本の目次の紹介です。
ゼロつくディープラーニングは、下記↓の合計8章で構成されています。
本の目次
- 1章 Python入門
- 2章 パーセプトロン
- 3章 ニューラルネットワーク
- 4章 ニューラルネットワークの学習
- 5章 誤差伝播法
- 6章 学習に関するテクニック
- 7章 畳み込みニューラルネットワーク
- 8章 ディープラーニング
ちなみに…
ゼロつくディープラーニングの第1章はPython入門のセクション(20ページ分)なので、
とりあえず今回私は飛ばし、第2章からまとめています。
今回も第4章のつづきからでーす。
第4章 ニューラルネットワークの学習つづき
ニューラルネットワークの学習とは、
訓練データから最適な重みパラメータの値を自動で獲得するようにできるコト。
4.5.1 2層ニューラルネットワークのクラスのつづきから
前回、↓のTwoLayerNetという名前のクラスとして、
Pythonで↓の様に実装してみた。
# 1つのクラスとして実装することからやってみる。 # TwoLayerNetという名前のクラスとして、 # Pythonで↓の様に実装してみる。 import sys, os sys.path.append(os.pardir) from common.functions import * from common.gradient import numerical_gradient import numpy as np class TwoLayerNet: def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01): #重みの初期化、引数は頭から順に入力層のニューロン数、隠れ層のニューロン数、出力層のニューロン数 self.params = {} self.params['W1'] = weight_init_std * np.random.randn(input_size, hiddent_size) self.params['b1'] = np.zeros(hidden_size) self.params['W2'] = weight_init_std * np.random.randn(input_size, hiddent_size) self.params['b2'] = np.zeros(output_size) def predict(self, x): #認識(推論)を行う。引数のxは画像データ W1, W2 = self.params['W1'], self.params['W2'] b1, b2 = self.params['b1'], self.params['b2'] a1 = np.dot(x, W1) + b1 z1 = sigmoid(a1) a2 = np.dot(z1, W2) + b2 y = softmax(a2) return y # x:入力データ t:教師データ def loss(self, x, t): #損失関数の値を求める。引数のxは画像データ、tは正解ラベル y = self.predit(x) return cross_entropy_error(y,t) def accuracy(self,x,t): #認識精度を求める y = self.predict(x) y = np.argmax(y, axis=1) t = np.argmax(t, axis=1) accuracy = np.sum(y == t) / float(x.shape[0]) return accuracy # x:入力データ t:教師データ def numerical_gradient(self,x,t): #重みパラメータに対する勾配を求める loss_W = lambda W: self.loss(x,t) grads = {} grads['W1'] = numerical_gradient(loss_W, self.params['W1']) grads['b1'] = numerical_gradient(loss_W, self.params['b1']) grads['W2'] = numerical_gradient(loss_W, self.params['W2']) grads['b2'] = numerical_gradient(loss_W, self.params['b2']) return grads
↑のように
params変数には、
このネットワークに必要なパラメータすべて格納されている。
grads変数には、
params変数に対応するように各パラメータの勾配が格納されている。
つづいて、
TwoLayerNetの実装のメソッドについてみていく。
__init__(self, input_size, hidden_size, output_size)は、クラスの初期化メソッド。
手書き数字を認識する場合、
入力画像のサイズが28x28の計784個、出力は10個のクラスとなる。
predict(self, x)は、認識(推論)を行う。
loss(self, x, t)は、損失関数の値を求める。引数のxは画像データ、tは正解ラベル。
accuracy(self,x,t)は、認識精度を求める。
numerical_gradient(self,x,t)は、各パラメータの勾配を計算する。
4.5.2 ミニバッチ学習の実装
ニューラルネットワークの学習の実装は、ミニバッチ学習で行う。
TwoLayerNetクラスを対象に、
MNISTデータを使ってPythonで学習してみる。
# coding: utf-8 import sys, os sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定 import numpy as np import matplotlib.pyplot as plt from dataset.mnist import load_mnist from two_layer_net import TwoLayerNet # データの読み込み (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True) network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10) iters_num = 10000 # 繰り返しの回数を適宜設定する train_size = x_train.shape[0] batch_size = 100 learning_rate = 0.1 train_loss_list = [] train_acc_list = [] test_acc_list = [] iter_per_epoch = max(train_size / batch_size, 1) for i in range(iters_num): batch_mask = np.random.choice(train_size, batch_size) x_batch = x_train[batch_mask] t_batch = t_train[batch_mask] # 勾配の計算 #grad = network.numerical_gradient(x_batch, t_batch) grad = network.gradient(x_batch, t_batch) # パラメータの更新 for key in ('W1', 'b1', 'W2', 'b2'): network.params[key] -= learning_rate * grad[key] loss = network.loss(x_batch, t_batch) train_loss_list.append(loss) if i % iter_per_epoch == 0: train_acc = network.accuracy(x_train, t_train) test_acc = network.accuracy(x_test, t_test) train_acc_list.append(train_acc) test_acc_list.append(test_acc) print("train acc, test acc | " + str(train_acc) + ", " + str(test_acc)) # グラフの描画 markers = {'train': 'o', 'test': 's'} x = np.arange(len(train_acc_list)) plt.plot(x, train_acc_list, label='train acc') plt.plot(x, test_acc_list, label='test acc', linestyle='--') plt.xlabel("epochs") plt.ylabel("accuracy") plt.ylim(0, 1.0) plt.legend(loc='lower right') plt.show()
コレ↑を実装すると、結果が↓コレ。
```
train acc, test acc | 0.11236666666666667, 0.1135
train acc, test acc | 0.7830833333333334, 0.7895
train acc, test acc | 0.87755, 0.8812
train acc, test acc | 0.89905, 0.902
train acc, test acc | 0.9087833333333334, 0.9127
train acc, test acc | 0.9153666666666667, 0.9184
train acc, test acc | 0.9203333333333333, 0.921
train acc, test acc | 0.9242, 0.9254
train acc, test acc | 0.92815, 0.9288
train acc, test acc | 0.9304833333333333, 0.9309
train acc, test acc | 0.93375, 0.9356
train acc, test acc | 0.9365166666666667, 0.9377
train acc, test acc | 0.9385666666666667, 0.9378
train acc, test acc | 0.94105, 0.9404
train acc, test acc | 0.94315, 0.9424
train acc, test acc | 0.94475, 0.944
train acc, test acc | 0.9466666666666667, 0.9439
```
そして、↓が認識精度の図。
勾配法による更新の回数、
繰り返し回数(イテレーション)を10,000回!として
*イテレーション:反復回数
更新するごとに、訓練データに対する損失関数を計算し、その値を配列に追加する。
↑の図からもわかるように、
繰り返しデータを学習することで、
最適な重みパラメータへと徐々に近づいていき、
精度が上がっていることがわかる。
今日のまとめ
ハイ、今日はここまで!!
今回もコーディングが多かったわ~(>ー<)ふう…
もともとコーディングの勉強なんだから当たり前なんですが、
私はよく打ち間違いをするのでエラーが多くなりタイヘン。(>ー<)
でもやるっきゃない!!
ということで、第4章はまだまだつづきます!
引き続き頑張りまっす。
最後まで読んでくださり、ありがとうございます!
フクコ
ディープラーニング入門書おススメ本