ニューラルネットワーク

Xavier初期化 / He初期化 ぐざびえしょきか / へーしょきか

Xavier初期化He初期化Glorot初期化Kaiming初期化重みの初期化活性化関数
Xavier初期化 / He初期化について教えて

簡単に言うとこんな感じ!

重みの初期値を「層の入出力のニューロン数に合わせた適切な分散でランダムに設定する」のがXavier初期化だよ。HeはReLU専用に改良したバージョン。どちらも「信号が大きくなりすぎず・小さくなりすぎず」を実現する賢い初期化なんだ!


Xavier初期化 / He初期化とは

Xavier初期化(グロット初期化) は、2010年にXavier GlorotとYoshua Bengioが提案した初期化手法です。活性化関数にSigmoidやtanhを使う場合に適していて、各層の出力の分散が入力の分散と等しくなるよう重みを設定します。ファンイン(入力数)とファンアウト(出力数)の両方を考慮しています。

He初期化(カイミング初期化) は、2015年にKaiming He(ResNetの開発者)らが提案したReLU向けの改良版です。ReLUは負の値を0にするため、情報の半分が失われます。この「情報の損失分」を補うため、Xavier初期化の約2倍の分散で初期化します。

正しい初期化を使わないと、信号が層を通るたびに指数関数的に縮小(勾配消失)または拡大(勾配爆発)してしまい、深いネットワークでは学習が機能しなくなります。


Xavier / He初期化の数式

手法一様分布正規分布(標準偏差)
XavierU(-√(6/(fan_in+fan_out)), +√(6/(fan_in+fan_out)))√(2/(fan_in+fan_out))
HeU(-√(6/fan_in), +√(6/fan_in))√(2/fan_in)
import torch.nn as nn
import torch

# モデル定義と初期化の例
class MyModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(784, 256)  # fan_in=784, fan_out=256
        self.fc2 = nn.Linear(256, 128)
        self.relu = nn.ReLU()
        self._initialize_weights()

    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Linear):
                # ReLUを使う場合はHe初期化
                nn.init.kaiming_normal_(m.weight, mode='fan_in', nonlinearity='relu')
                nn.init.zeros_(m.bias)

歴史と背景

  • 2010年:Glorotらが「Understanding the difficulty of training deep feedforward neural networks」でXavier初期化を発表
  • 2015年:HeらがResNetと同じ論文「Delving Deep into Rectifiers」でHe初期化を発表
  • 以後:TensorFlow・PyTorchのデフォルト初期化として実装され、コードを書かなくても自動適用される
  • 現在:新しいアーキテクチャ(Transformer等)では論文で個別に初期化方式が指定されることが多い

どちらを選ぶべきか

活性化関数推奨初期化理由
SigmoidXavier対称な出力範囲に適合
tanhXavierSigmoidと同様
ReLUHe負値カットによる情報損失を補正
Leaky ReLUHe(slope考慮)ReLUに準じる
ELUHeReLUに近い特性
GELUXavier or HeTransformerでよく使用

関連用語