ニューラルネットワークを理解する#8  効率的に学習させる「ミニバッチ学習」

前回まででニューラルネットワークを実装するための基礎の部分は終わりました。
しかし、あのままだと学習に時間がかかりすぎてちょっと使い勝手が悪いです。
そこで、学習を早めるためのテクニックをいくつかみていきましょう!

バッチとは何か

バッチとは一塊のデータを意味します。
配列で表してみるといかが一つのデータです。
[0,1,2,3]

これを複数まとめたものをバッチと呼びます。
[
  [0,1,2,3],
  [4,5,6,7]
]

わかりやすい画像がありました。
以下のように入力を全て一塊にして学習させるのがバッチ学習というものです。
参考:https://chefyushima.com/ai-ml_batch-online/2781/

バッチにするとなぜ早くなるのか?

これは大抵の数値計算ライブラリが配列の計算に最適化されているからです。
一つずつ処理するよりも、まとまった配列を計算するのが得意だからバッチにすると計算が早くなるわけですねー。
でも、数百万とあるデータを一個にまとめるのはあまり現実的ではありません。。
そこで出てくるのがミニバッチ処理というものです。

ミニバッチ処理とは

文字通り全てをまとめるのではなく、少数にまとめて処理していく方法がミニバッチ処理というものです。


大抵はランダムにミニバッチを取り出して、任意の回数処理させて学習させるのが一般的なようです。(例えば100ずつを1000回とか)


試してみよう!

前回の方法では1000枚の学習で1時間以上かかりましたがミニバッチだとどうでしょうねー。

#7と#8の実装をほぼまんま使って学習のコードだけを改変します。


network=init_network(784, 50, 10, weight_init_std=0.01)

iters_num = 100  # 繰り返しの回数を適宜設定する
train_size = x_train.shape[0]
batch_size = 10

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_fla_norm[batch_mask]
    y_batch = y_train_one_hot[batch_mask]

    # 勾配の計算
    grad = numerical_gradient_calc(network,x_batch, y_batch)

    # パラメータの更新
    for key in ('W1', 'b1', 'W2', 'b2'):
        network['params'][key] -= learning_rate * grad[key]

    loss_ = loss(network, x_batch, y_batch)
    train_loss_list.append(loss_)


    train_acc = accuracy(network,x_train_fla_norm, y_train_one_hot)
    test_acc = accuracy(network,x_test_fla_norm, y_test_one_hot)
    train_acc_list.append(train_acc)
    test_acc_list.append(test_acc)
    print("train acc, test acc | " + str(train_acc) + ", " + str(test_acc))

大体30分くらいで終わりました。約半分くらい早くなっとるー。



認識精度も同じくらいですね。
それでもやはり遅いは遅いです。

次回は高速化のもう一つのテクニック「誤差逆伝搬法」についてみていきましょう。


コメント