重み初期化シミュレーター — Xavier・He 戻る
機械学習

重み初期化シミュレーター — Xavier・He

深いニューラルネットワークで、入力信号が層を順伝播するときに活性化の分散がどう変化するかを可視化します。初期化法を切り替えると、信号が消える(勾配消失)か、発散する(勾配爆発)か、一定に保たれるかが一目で分かります。

パラメータ設定
初期化法
重みの分散 Var(W) の決め方
活性化関数
層ごとの非線形変換
層数
順伝播する全結合層の数
各層のユニット数 n
層の幅(ファンイン)
入力信号の標準偏差
第1層に入る活性化の std
計算結果
初期化法
最終層の活性化 std
入力比の変化倍率
信号の状態
推奨初期化
適合判定
信号の伝播 — 深層ネットワーク可視化

左から右へ層が並びます。各ノードの明るさ・大きさはその層の活性化 std を表し、信号パルスが層を伝わります。消える信号は右へ向かって暗くなり、発散する信号は眩しく膨らみます。

活性化のばらつき vs 層
初期化法ごとの最終層 std
理論・主要公式

$$\text{Xavier: }\mathrm{Var}(W)=\frac{1}{n_{in}},\qquad \text{He: }\mathrm{Var}(W)=\frac{2}{n_{in}}$$

重みの分散の決め方。n_in はファンイン(その層への入力ユニット数)。He は ReLU 用、Xavier は tanh・シグモイド用。

$$\mathrm{Var}(z_\ell)=n\cdot\mathrm{Var}(W)\cdot\mathrm{Var}(a_{\ell-1})$$

線形層を通った後の信号 z の分散。n 個の入力 aᵢ に重み wᵢ を掛けて足し合わせた結果。

$$\mathrm{Var}(a_\ell)=g\cdot\mathrm{Var}(z_\ell)$$

活性化後の分散。ReLU は分散の約半分を捨てる(g≈0.5)ため、He は Var(W) を2倍にしてこれを補い、層を通っても分散が一定に保たれる。

重み初期化とは

🙋
ニューラルネットの「重み初期化」って、学習が始まる前に重みの値を決めるだけですよね?適当な小さい乱数でいいんじゃないんですか?
🎓
それがね、深いネットワークだと「適当な小さい乱数」で派手に失敗するんだ。各層は前の層の出力に重みを掛けて足し算するだろう? つまり信号の「ばらつき(分散)」が層を通るたびに掛け算で変化していく。重みが小さすぎると、層を1つ進むごとに分散がどんどん小さくなって、20層も進む頃には信号がほぼゼロ。これだと一番手前の層に届く勾配もゼロで、学習が完全に止まる。これが「勾配消失」だよ。
🙋
え、じゃあ重みを大きめにすればいいんですか?左のセレクトで「大きな乱数(std=1.0)」を選んでみたら、最終層の std がとんでもない数字になりました…
🎓
そう、それが逆方向の失敗、「勾配爆発」だ。今度は層を通るたびに分散が倍々に増えていって、指数的に発散する。30層もあれば数値があふれて NaN になり、学習どころじゃない。だから初期化は「小さすぎず大きすぎず」、層を通っても分散がちょうど保たれる値にしたい。その「ちょうどいい値」を理論的に求めたのが Xavier 初期化と He 初期化なんだ。
🙋
Xavier と He って、何が違うんですか?どっちを使えばいいのか分かりません。
🎓
活性化関数で決まるんだ。Xavier は重みの分散を Var(W)=1/n(n は入力ユニット数)にする。これは tanh やシグモイドのように、原点付近の傾きがほぼ1の対称な関数を前提にした値だね。一方 He は Var(W)=2/n、つまり Xavier の2倍。なぜ2倍かというと、ReLU は負の入力を全部ゼロにして、分散のだいたい半分を捨ててしまうから。その半分を取り戻すために、あらかじめ重みの分散を2倍にしておくんだ。左で活性化関数を ReLU にして He を選ぶと、上のグラフがほぼ水平な直線になるのが見えるはずだよ。
🙋
なるほど!じゃあ ReLU なのに Xavier を使っちゃうとどうなるんですか?
🎓
やってみるといい。活性化関数 ReLU のまま初期化を Xavier にすると、Var(W)=1/n だから線形層を出た直後の分散は元と同じ。でも ReLU がそのあと半分捨てるから、1層ごとに分散がきっちり半減していく。12層なら 2 の 12 乗分の1、つまり約4000分の1まで縮む。std で言えば60分の1くらい。これはもう立派な勾配消失だ。理論的には「ReLU には He」というのが、この半分のズレを埋めるための答えなんだよ。
🙋
最後にもう一つ。「ゼロ初期化」って選択肢もありますけど、全部ゼロから始めちゃダメなんですか?
🎓
これは絶対ダメな初期化の代表例だね。重みを全部0にすると、同じ層の全ニューロンが完全に同じ出力を返す。逆伝播のときも全員が同じ勾配を受け取るから、永遠に同じ値のまま動く。つまり何百ニューロンあっても実質1個分の働きしかしない。これを「対称性が破れない」と言うんだ。学習を成立させるには、重みをランダムにしてニューロンごとに違う役割を持たせる「対称性の破れ」が絶対に必要。バイアスは0で大丈夫だけど、重みは0にしちゃいけないんだよ。

よくある質問

深いネットワークでは、各層の線形変換 z = Σwᵢaᵢ により活性化の分散 Var(a) が層ごとに掛け算で変化します。重みが小さすぎると Var(a) が層を進むたびに小さくなり、入力側の層に届く勾配がほぼゼロになって学習が止まります(勾配消失)。逆に大きすぎると Var(a) が指数的に発散して NaN になります(勾配爆発)。Xavier・He 初期化は、この分散が層を通っても一定に保たれるよう重みの分散 Var(W) を設計したもので、初期値を変えるだけで学習が「全く進まない」か「収束する」かが決まります。
活性化関数で選びます。tanh やシグモイドのように原点付近の傾きがほぼ1の対称な関数には Xavier(Glorot)初期化 Var(W)=1/n を使います。ReLU のように負の入力をゼロにして分散の約半分を捨てる関数には He 初期化 Var(W)=2/n を使います。He が Xavier の2倍の分散を持つのは、ReLU が落とした半分を補うためです。本ツールで活性化関数を ReLU にして Xavier を選ぶと、層ごとに分散が半減して信号が消えていく様子が確認できます。
全ての重みを0にすると、同じ層の全ニューロンが同一の出力を返し、誤差逆伝播でも全く同じ勾配を受け取ります。つまり全ニューロンが永遠に同じ値を保ち、層が何個あっても実質1ニューロン分の表現力しか持てません。これを「対称性の破れがない」状態と呼びます。学習を機能させるには重みをランダムな小さな値にして、ニューロンごとに異なる役割を持たせる必要があります。バイアスはゼロ初期化で問題ありません。
Batch Normalization(BN)は各層の出力を平均0・分散1へ正規化するため、初期化の影響をある程度吸収します。BN を入れたネットでは初期化が多少ずれていても学習は進みます。しかし BN にも計算コストやバッチ依存性があり、Transformer など BN を使わない構成も多いため、適切な初期化(He・Xavier)は依然として基本です。BN や Layer Normalization と良い初期化を併用すれば、より深いネットワークを安定して学習できます。

実世界での応用

画像認識の深層 CNN:ResNet や VGG のような畳み込みネットワークは ReLU を多用するため、He 初期化が事実上の標準です。He 論文(2015年)はまさに「30層級の ReLU ネットを最初から安定して学習する」ために提案されました。畳み込み層ではファンインを「カーネルサイズ × 入力チャンネル数」として Var(W)=2/n を計算します。初期化を Xavier のまま深い CNN を学習させると、序盤で損失が下がらず「学習率が悪いのか」と悩むことになりますが、原因は初期化であることが多いです。

自然言語処理と Transformer:Transformer は内部に多数の全結合層を持ち、活性化に GELU(ReLU の滑らかな親戚)を使います。元論文では Xavier 系の初期化に加え、残差接続の数に応じて初期スケールを小さくする工夫が入っています。GPT 系では層数 L に対して出力射影の重みを 1/√(2L) でスケールするなど、「深さに応じた初期化」が安定学習の鍵になっています。重み初期化は単なる前処理ではなく、アーキテクチャ設計の一部です。

転移学習・ファインチューニング:事前学習済みモデルを使う場合、本体の重みは学習済みなので初期化は不要ですが、新しく付け加える出力ヘッド(分類層など)は初期化が必要です。ここで大きすぎる初期値を使うと、ファインチューニング初期に勾配が暴れて事前学習した良い特徴を壊してしまいます。出力ヘッドは小さめの初期化、または学習率を本体より低く設定するのが定石です。

学習が進まないときの診断:「損失が全く下がらない」「数エポックで NaN になる」といったトラブルでは、まず各層の活性化の標準偏差をログに出して確認します。本ツールのように層を追って std がゼロへ消えていれば初期化が小さすぎ、発散していれば大きすぎのサインです。学習率やオプティマイザを疑う前に、初期化と活性化分散をチェックするのが効率的なデバッグ手順です。

よくある誤解と注意点

まず多いのが、「初期化はどれも似たようなもので、学習率さえ合わせれば収束する」という誤解です。本ツールで確かめられるとおり、ReLU・12層のネットで He なら最終層の std が約1.0に保たれるのに対し、std=0.01 の小さな乱数では信号が天文学的に小さくなり、std=1.0 の大きな乱数では発散します。これは学習率では救えません。勾配が消えていれば、学習率をいくら上げても更新量はゼロのままだからです。初期化は「学習開始点を決めるだけ」ではなく、「そもそも勾配が流れる土俵を作る」役割を持っています。

次に、「ファンイン(n_in)とファンアウト(n_out)を混同する」こと。本ツールでは順伝播の分散保存に着目して Var(W)=2/n_in(He)を使っていますが、Xavier の原論文は順伝播と逆伝播の両方を保ちたいため Var(W)=2/(n_in+n_out) という平均形を提案しています。実装によってどちらの規約を採るかが違い、fan_in モードと fan_out モードが用意されているフレームワークもあります。層の幅が入口と出口で大きく異なるネットワークでは、この違いが分散を数倍ずらすことがあるため、使っているライブラリの既定値を必ず確認してください。

最後に、「Batch Normalization を入れれば初期化はどうでもいい」という思い込み。確かに BN は各層の出力を正規化するので初期化の粗さをかなり吸収します。しかし BN 自体が学習可能なスケール・シフトパラメータを持ち、それらの初期値(通常スケール1・シフト0)も一種の初期化です。さらに残差接続を持つネットでは、残差ブランチの最後の BN のスケールを0に初期化すると、学習初期にネットワークが恒等写像から始まって安定する、という「ゼロ初期化を意図的に使う」テクニックもあります。BN があっても初期化の設計は消えるのではなく、形を変えて残り続けるのです。

使い方ガイド

  1. ニューラルネットワークのレイヤー数を設定します(例:5層から50層の範囲で指定)
  2. 各レイヤーのユニット数を入力します(例:入力層256ユニット、隠れ層128ユニット、出力層10ユニット)
  3. 入力信号の標準偏差を設定し、Xavier初期化(均一分布U[-√(6/(n_in+n_out)), √(6/(n_in+n_out))])またはHe初期化(正規分布N(0, √(2/n_in)))を選択します
  4. シミュレーションを実行すると、各レイヤーを通過した活性化値の標準偏差の変化が可視化されます

具体的な計算例

入力層1024ユニット、隠れ層が512→256→128ユニットの3層構成で、入力信号の標準偏差が1.0の場合を想定します。Xavier初期化では第1層の重み分散が約6/(1024+512)≈3.9×10^-3となり、10層を通過後の活性化std変化倍率は約0.95となって信号が安定します。一方He初期化では分散が2/1024≈1.96×10^-3で、深い層でも活性化stdが0.98倍に保たれ、勾配消失を回避できます。

実務での注意点

  1. ReLU活性化関数を使用する場合はHe初期化を採用してください(Xavier初期化では20層以上で信号が減衰する可能性があります)
  2. tanh・sigmoid使用時はXavier初期化が最適で、活性化std変化倍率が0.97以上を目安としてください
  3. 最終層の活性化stdが入力比の10倍以上に変動する場合、バッチ正規化(BatchNormalization)の導入を検討してください
  4. 残差接続(ResNet型)を導入する場合、層数が50層を超えてもXavier初期化で勾配爆発が起こりにくくなります