【ディープラーニング】5-2 学習関連スキル - 重みの初期値

ニューラルネットワークの学習においては、重みの初期値が特に重要です。実際、どのような重みの初期値を設定するかがニューラルネットワークの学習の成功に関係することが多いですここでは重みの初期値の推奨値を紹介し、ニューラルネットワークの学習が早く進むか実験で確認していきます。

重みの初期値を 0 に設定することはできますか?過学習を抑制し、汎化能力を向上させる手法である重み減衰
後で紹介します重み減衰は、重みパラメータの値を減らすことを目的とした学習方法です。

重みの値を小さくしたい場合は、最初から初期値を小さい値に設定すると良いでしょう。実はこれ以前の重みの初期値はこんな感じで0.01 * np.random.randn(10,100)、ガウス分布で生成した値に0.01を乗算した値(標準偏差0.01のガウス分布)を使用しています。

重みの値を下げるために、重みの初期値をすべて 0 に設定したらどうなるでしょうか? 実際、重みの初期値を 0 に設定すると、正しく学習できなくなります。
重みの初期値を 0 に設定できないのはなぜですか? 厳密に言うと、重みの初期値を同じ値に設定できないのはなぜですか?
これは、誤差逆伝播法ではすべての重みの値が同じ値に設定できないためです。同様に更新されます。
たとえば、2 層のニューラル ネットワークでは、層 1 と層 2 の重みが 0 であると仮定します。このように、順伝播中、入力層の重みは 0 であるため、2 番目の層のすべてのニューロンには同じ値が渡されます。2 番目の層のニューロンはすべて同じ値を入力します。これは、バックプロパゲーション中に 2 番目の層の重みがすべて同じように更新されることを意味します。したがって、重みは同じ値に更新され、対称的な値(重複した値)を持ちます。これでは、ニューラル ネットワークにさまざまな重みを持たせるという意味が損なわれるため、初期値はランダムに生成する必要があります。

隠れ層の活性値の分布
各層の活性値の分布には適切な幅が必要ですなぜなら、層間で多様なデータを渡すことで、ニューラルネットワークは効率的に学習できるからです。逆に偏ったデータを流すと、勾配の消失や「表現力の制限」といった問題が発生し、学習がスムーズに進まない可能性があります。

さて、一般的な深層学習フレームワークではXavierの初期値が基準として使用されていますが、例えばCafeフレームワークでは重みの初期値を設定する際にxavierパラメータを与えることでXavierの初期値を使用することができます。 。ザビエルの論文では、各層の活性化値が同じ幅の分布となるように、適切な重み付けスケールを導出している。導き出された結論は、前の層のノード数が n の場合、初期値は標準偏差が のここに画像の説明を挿入
分布を使用するということです。
ここに画像の説明を挿入

Xavier 初期値を使用した後、前の層のノードが多いほど、ターゲット ノードの初期値として設定される重みスケールは小さくなります。

ReLU の重み初期値
ザビエル初期値は、活性化関数が一次関数であることを前提として導出されます。シグモイド関数とタン関数は左右対称で中心付近は一次関数とみなせるため、ザビエルの初期値を使用するのが適しています。ただし、活性化関数が ReLU を使用する場合、一般的には ReLU 専用の初期値、つまり「 He 初期値」、つまり現在の層のノード数が n の場合の He 初期値を使用することが推奨されます。ここに画像の説明を挿入標準偏差が のガウス分布を使用します。
まとめると、活性化関数がReLUを使用する場合、重みの初期値はHe の初期値を使用し、活性化関数がsigmoid や Tanh などの S 字曲線関数の場合、重みの初期値はXavier の初期値を使用します。 。これが現在のベストプラクティスです。

MNIST データセットに基づく初期重み値の比較
次に、実際のデータを通じて、初期重み値のさまざまな割り当て方法がニューラル ネットワークの学習にどのような影響を与えるかを観察します。ここでは、std=0.01、Xavierの初期値、Heの初期値に基づいて実験を行います。テストコードは次のとおりです。

# coding: utf-8
import os
import sys

sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
import numpy as np
import matplotlib.pyplot as plt
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()

結果は次のとおりです。
ここに画像の説明を挿入

std=0.01の場合は全く学習できません。フォワードパスで渡される値が小さい(近くのデータに集中している)ため、これは観測された活性化値と同じ分布になります。したがって、バックプロパゲーション中に得られる勾配も非常に小さく、重みはほとんど更新されません。
逆に、重みの初期値がザビエル初期値とHe初期値の場合は学習がスムーズに進み、He初期値の方が学習の進みが早いことが分かりました。

要約すると、ニューラル ネットワークの学習においては、重みの初期値が非常に重要です。多くの場合、重みの初期値の設定はニューラルネットワークの学習の成否に関係します。重みの初期値の重要性は見落とされがちであり、何事においても最初 (初期値) は常に重要であるため、このセクションの最後で重みの初期値の重要性を再度強調します

おすすめ

転載: blog.csdn.net/loyd3/article/details/131099933