からっぽのしょこ

読んだら書く!書いたら読む!読書読読書読書♪同じ事は二度調べ(たく)ない

5.7.4:誤差逆伝播法を使った学習【ゼロつく1のノート(実装)】

はじめに

 「プログラミング」学習初手『ゼロから作るDeep Learning』民のための実装攻略ノートです。『ゼロつく1』学習の補助となるように適宜解説を加えています。本と一緒に読んでください。

 関数やクラスとして実装される処理の塊を細かく分解して、1つずつ処理を確認しながらゆっくりと組んでいきます。

 この記事は、5.7.4項「誤差逆伝播法を使った学習」の内容になります。前項までにPythonで実装した2層のニューラルネットワークを用いてパラメータの学習を行います。

【前節の内容】

https://www.anarchive-beta.com/entry/2020/08/07/180000www.anarchive-beta.com

【他の節の内容】

www.anarchive-beta.com

【この節の内容】

5.7.4 誤差逆伝播法を使った学習

 誤差逆伝播法による勾配の計算とレイヤという概念を導入したニューラルネットワークを実装できたので、最後にパラメータの学習を行います。

 基本的な実装は4.5.2項(学習)と4.5.3項(評価)と同じです。こちら「4.5.2-3:ミニバッチ学習の実装【ゼロつく1のノート(実装)】 - からっぽのしょこ」もご参照ください。また学習に用いるMNISTデータセットは前項で読み込んだものを使います。

 まずはインスタンスを作成します。引数はパラメータの形状に影響します。input_sizeはピクセルデータ数の784、hedden_sizeは中間層のニューロン数なので任意の値、output_sizeは数字の種類数の10を指定します。

# インスタンスを作成
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
print(network.params.keys())
dict_keys(['W1', 'b1', 'W2', 'b2'])


 学習に関する値を設定します。

# 試行回数
iters_num = 10000

# 全訓練データ数
train_size = x_train.shape[0]

# バッチサイズ(一度に処理するデータ数)を指定
batch_size = 100

# 全データに対するバッチデータの割合
iter_per_epoch = max(train_size / batch_size, 1)

# 学習率
learning_rate = 0.1

 iter_per_epochは、1エポックごとに認識精度の測定を行うための変数です。そのため最終的な学習結果に対する認識精度を(自動で)測るためには、訓練データ数train_sizeの倍数+1の値を試行回数iters_numに指定する必要があります。

 学習を行います!

# 学習進度を記録するための受け皿を作成(初期化)
train_loss_list = []
train_acc_list = []
test_acc_list = []

# パラメータの学習
for i in range(iters_num):
    # ランダムにデータを抽出
    batch_mask = np.random.choice(train_size, batch_size, replace=False)
    x_batch = x_train[batch_mask]
    t_batch = t_train[batch_mask]
    
    # 勾配を計算
    grad = network.gradient(x_batch, t_batch)
    
    # パラメータごとに値を更新
    for key in ('W1', 'b1', 'W2', 'b2'):
        # 勾配降下法:(4.4.2項)
        network.params[key] -= learning_rate * grad[key]
    
    # 交差エントロピー誤差誤差を計算
    loss = network.loss(x_batch, t_batch)
    train_loss_list.append(loss)
    
    # 1エポックごとに認識精度を測定
    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)


 学習の推移を確認しましょう。まずは交差エントロピー誤差の推移をプロットします。

## 交差エントロピー誤差の推移

# x軸の値
x = np.arange(iters_num)

# 作図
plt.plot(x, train_loss_list)
plt.xlabel("iteration") # x軸ラベル
plt.ylabel("loss") # y軸ラベル
plt.title("Cross Entropy Error", fontsize=20) # グラフタイトル
plt.show()

f:id:anemptyarchive:20200730154301p:plain
交差エントロピー誤差の推移

 試行回数が増えるに従って値が下がっている(学習が進んでいる)ことが確認できました。

 続いて訓練データとテストデータに対する認識精度の推移もプロットします。

## 認識精度の推移

# x軸の値を生成
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") # x軸ラベル
plt.ylabel("accuracy") # y軸ラベル
plt.ylim(0, 1) # y軸の範囲
plt.legend() # 凡例
plt.title("Accuracy", fontsize=20) # グラフタイトル
plt.show()

f:id:anemptyarchive:20200730154325p:plain
正解精度の推移

 こちらも試行回数(学習に使用したデータ数)が増えるに従って値が良くなっていることが確認できます。また訓練データだけでなくテストデータに対しても精度が高いため、過学習が起きていないことも確認できました!

 以上で5章の内容、誤差逆伝播法を用いたニューラルネットワークの学習が完了です!処理時間が短いと試行も思考も増やせるのでとても重要ですね。その分数学学習にたっぷり時間を使えますね!お疲れ様でした!次章では学習アルゴリズムについて学習します。

参考文献

  • 斎藤康毅『ゼロから作るDeep Learning』オライリー・ジャパン,2016年.

おわりに

 5章完了です!!!この章は数学メイン回で大変でしたね。お疲れ様でしたー。

【次節の内容】

https://www.anarchive-beta.com/entry/2020/08/09/180000www.anarchive-beta.com