6章 学習に関するテクニック 『ゼロから作るDeep Learning』
続き。
重みの初期値について。
結論として、重みの初期値をゼロにするのはNG。
重みの対照的な構造を崩し、ランダムな初期値を設定する。
勾配消失gradient vanishing:逆伝播での勾配の値が徐々に小さくなること。
多層NNでは勾配消失が問題になるので、推奨された初期値を使う。
活性化関数にS字カーブ(sigmoid,tanh)を使うなら「Xavierの初期値」
活性化関数にReLUを使うなら「Heの初期値」
以下、比較したサンプルコード
# cat weight_init_compare_save.py # coding: utf-8 import os import sys sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定 import numpy as np import matplotlib.pyplot as plt plt.switch_backend('agg') from dataset.mnist import load_mnist from common.util import smooth_curve from common.multi_layer_net import MultiLayerNet from common.optimizer import SGD # 0:MNISTデータの読み込み========== (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True) train_size = x_train.shape[0] batch_size = 128 max_iterations = 2000 # 1:実験の設定========== weight_init_types = {'std=0.01': 0.01, 'Xavier': 'sigmoid', 'He': 'relu'} optimizer = SGD(lr=0.01) networks = {} train_loss = {} for key, weight_type in weight_init_types.items(): networks[key] = MultiLayerNet(input_size=784, hidden_size_list=[100, 100, 100, 100], output_size=10, weight_init_std=weight_type) train_loss[key] = [] # 2:訓練の開始========== for i in range(max_iterations): batch_mask = np.random.choice(train_size, batch_size) x_batch = x_train[batch_mask] t_batch = t_train[batch_mask] for key in weight_init_types.keys(): grads = networks[key].gradient(x_batch, t_batch) optimizer.update(networks[key].params, grads) loss = networks[key].loss(x_batch, t_batch) train_loss[key].append(loss) if i % 100 == 0: print("===========" + "iteration:" + str(i) + "===========") for key in weight_init_types.keys(): loss = networks[key].loss(x_batch, t_batch) print(key + ":" + str(loss)) # 3.グラフの描画========== markers = {'std=0.01': 'o', 'Xavier': 's', 'He': 'D'} x = np.arange(max_iterations) for key in weight_init_types.keys(): plt.plot(x, smooth_curve(train_loss[key]), marker=markers[key], markevery=100, label=key) plt.xlabel("iterations") plt.ylabel("loss") plt.ylim(0, 2.5) plt.legend() #plt.show() plt.savefig('weight_init_compare.png')
確かにXavier,Heの初期値の方が学習の進みが速い。
重みを適当に設定せず、適切な学習が進むように適切に設定する必要がある。