おひとりさま現役パラレルワーカーフクコろぐ

これからの会社員は、複数の収入源をもとう! 会社に翻弄されずアナタらしく仕事ができる。 そんなパラレルワーカーを広めるフクコのブログです。

【文系プログラミング初心者deE資格】ゼロつくディープラーニング #15

f:id:fukuko-parallel-work:20211114135729j:plain


こんにちは!

現役パラレルワーカー フクコです。

f:id:fukuko-parallel-work:20210212204833p:plain



前回の記事↓に続き

www.fukuko-parallel-work.com





来年の2月の試験に向けてE資格試験勉強中のため


ゼロつくシリーズでおなじみ

オーライリーから出版されている

ディープラーニングの本格的な入門書でよくおススメされる

「ゼロからつくる Deep Learning」本


f:id:fukuko-parallel-work:20211029220008j:plain




この本↑を毎日5ページずつコツコツこなす

約2か月間で今年中に終了するので

来年のE資格試験までにこれで基礎力をつけることにしました。(^^)


ついつい私は何もないとだらけてしまうので(笑)

毎日5ページ終わった後の記録とまとめを書いていこうと思います。


と、まとめに入る前に…

やる気を出すためのコトバをシェアします!!(主に私のやる気を出すために 笑)



「まあ、出来て当然ですけれども、仕方ないです。

できないなら しょうがないしょうがない。」

by 胡蝶 しのぶ



おなじみ私の大好きな鬼滅の刃から

蟲柱・胡蝶 しのぶの名言です。

鬼殺隊の剣士たちの中で唯一、

藤の花から抽出した「鬼を殺す毒」を作り出し、鬼を滅するすごいヒトです。

そして

医学にも精通しているため

普段は柱に与えられる自身の館・蝶屋敷を治療所として開放してたりします。


出来ない子でスミマセン、しのぶ様 (ついつい様づけ 笑)。もっとガンバります!! 見捨てないで~(>ー<)


やっぱり煽られるとやる気になりますよね!笑

しのぶ様、どうもありがとう! (^0^)

今日もやる気が出てきました! 

よし!! 今日も頑張るぞ~! お~!! 

というコトで、しのぶ様に見捨てられないためにも、今日も私はノルマをこなしますよ! 笑


ではでは、いい加減まとめに入ります。笑



その前に本の目次の紹介です。

ゼロつくディープラーニングは、下記↓の合計8章で構成されています。

本の目次

  • 5章 誤差伝播法
  • 6章 学習に関するテクニック


ちなみに…

ゼロつくディープラーニング第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
```


そして、↓が認識精度の図


f:id:fukuko-parallel-work:20211114185009j:plain


勾配法による更新の回数

繰り返し回数(イテレーション)を10,000回!として

*イテレーション:反復回数

更新するごとに、訓練データに対する損失関数を計算し、その値を配列に追加する


↑の図からもわかるように、

繰り返しデータを学習することで

最適な重みパラメータへと徐々に近づいていき

精度が上がっていることがわかる



今日のまとめ


ハイ、今日はここまで!!

今回もコーディングが多かったわ~(>ー<)ふう…

もともとコーディングの勉強なんだから当たり前なんですが、

私はよく打ち間違いをするのでエラーが多くなりタイヘン。(>ー<)

でもやるっきゃない!!

ということで、第4章はまだまだつづきます!

引き続き頑張りまっす。


最後まで読んでくださり、ありがとうございます!

フクコ


ディープラーニング入門書おススメ本