「ゼロから作るDeep Learning」自習メモ（その５）４章 ニューラルネットワークの学習

「ゼロから作るDeep Learning」(斎藤 康毅　著　オライリー・ジャパン刊)を読んでいる時に、参照したサイト等をメモしていきます。 [その４](https://qiita.com/slow_learner/items/d914454ecee154e98cd2)← →[その６](https://qiita.com/slow_learner/items/5589a95081d30f82fbbd)

##４　ニューラルネットワークの学習

何をしているかの概略は、P112 からの説明で、なんとなくわかります。
損失関数を最小にするために、勾配を求めて、勾配の方向へ進むというのも、グラフのイメージで納得できるのですが、

が

微分、偏微分、２重和誤差、交差エントロピー誤差といろんな言葉と数式が並ぶと、わけがわからなくなりそうです。

とりあえず、4.1 データから学習する　を読んだら、
>P88
損失関数はニューラルネットワークの性能の“悪さ”を示す指標です。現在のニューラルネットワークが教師データに対してどれだけ適合していないか、教師データに対してどれだけ一致していないかということを表します。
　 
>P106
勾配が示す方向は、各場所において関数の値を最も減らす方向なのです。

>勾配をうまく利用して関数の最小値（または、できるだけ小さな値）を探そう、というのが勾配法です。

ということを押さえて、P112 4.5 学習アルゴリズムの実装 に進んでしまってもいいかもしれません。
本の内容は、プログラム内で使っている関数の説明を順に積み上げてから実装、となっていますが、まず実装したプログラムを動かして見る。で、いろいろデータ内容を確認してみてから、関数の説明を熟読する、という順番のほうが、理解しやすいと思います。
数学の素養がない私などには、最初に関数の説明を読んでも、なんのことかよくわかりませんでしたが、プログラムを動かしてから、プログラムをトレースしていくと、本の説明がどのようにプログラムに組まれているか、理解できないまでも、納得はできました。

で、まず動かしてみようとなった場合には、P118 のプログラムの中に

```python
# 勾配の計算
grad = network.numerical_gradient(x_batch, t_batch)
# grad = network.gradient(x_batch, t_batch) # 高速版!
```

となっているところがありますが、この通りにして実行すると、ものすごく時間がかかります。
ここは

```python
# 勾配の計算
# grad = network.numerical_gradient(x_batch, t_batch)
grad = network.gradient(x_batch, t_batch) # 高速版!
```

と変えて実行したほうがいいでしょう。
P114 のプログラム例には gradientメソッドが書いてありませんが、ダウンロードしたファイルのch04/two_layer_net.py　には、gradientメソッドも書いてあります。

損失関数が変化していく様子のグラフ

```python
# print(train_loss_list)
import matplotlib.pylab as plt
x = np.arange(len(train_loss_list))
y = train_loss_list
plt.plot(x, y)
plt.show()
```
![p119.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686010/57fb3bb3-b9b5-f5c1-a9c7-48eb3157af25.jpeg)

学習した結果（重みとバイアス）をpickleで退避させてみた

```python
# networkオブジェクトを、pickleで保存する。
import pickle
save_file = dataset_dir + '/gakusyuukekka_weight.pkl'    #拡張子は.pkl
with open(save_file, 'wb') as f:
    pickle.dump(network, f, -1)    
```

学習した結果（重みとバイアス）をセットし、テストデータを読ませて推論処理をしてみた。

```python
import numpy as np
from common.functions import *

class TwoLayerNet:
    def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01):
        # 重みの初期化
        self.params = {}
        
    def predict(self, 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

import pickle
import sys, os

dataset_dir = os.path.dirname(os.path.abspath('__file__'))+'/dataset'

mnist_file = dataset_dir + '/mnist.pkl'
with open(mnist_file, 'rb') as f:
    dataset = pickle.load(f)
dataset['test_img'] = dataset['test_img'].astype(np.float32)
dataset['test_img'] /= 255
x = dataset['test_img']
t = dataset['test_label']

# network = TwoLayerNet(input_size=784, hidden_size=100, output_size=10)
weight_file = dataset_dir + '/gakusyuukekka_weight.pkl'
with open(weight_file, 'rb') as f:
    network = pickle.load(f)

accuracy_cnt = 0
for i in range(len(x)):
    y = network.predict(x[i])
    p= np.argmax(y) 
    if p == t[i]:
        accuracy_cnt += 1

print("Accuracy:" + str(float(accuracy_cnt) / len(x))) 
```
結果は　
>Accuracy:0.8652

と、えらく悪い認識精度に。

```python
# 識別結果の内容を確認してみる
import matplotlib.pyplot as plt

def showImg(x):
    example = x.reshape((28, 28))
    plt.figure()
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(example)
    plt.show()
    return

for i in range(10):
    y = network.predict(x[i])
    p= np.argmax(y)
    print("正解 " + str(t[i]))
    print("[ " + str(p) + " ]")
    count = 0
    for v in y:
        print("["+str(count)+"] {:.2%}".format(v))
        count += 1
    showImg(x[i])
```

![p120.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686010/518a5b78-9801-1c9d-2876-1d0eecd9f604.jpeg)

正解ではあるが、確率95.63％ で、３章でやった処理よりも確度が低い。

![p121.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686010/0a800ea2-4cc0-7d32-ca24-8761a4618c05.jpeg)

これは３章の処理では正解していたもの。

まだ、本の途中だから精度は低いのだろうけど、何か間違っているのかどうかは不明。

 [その４](https://qiita.com/slow_learner/items/d914454ecee154e98cd2)← →[その６](https://qiita.com/slow_learner/items/5589a95081d30f82fbbd)

[読めない用語集](https://qiita.com/slow_learner/items/03eb3367119e98b5a22c)