🐷

Xavier初期化、He初期化

に公開

Xavier初期化とHe初期化:ニューラルネットワークの重み初期化手法

ニューラルネットワークを学習させる際、重みの初期化は非常に重要な要素といわれています。
適切な初期化を行わないと、勾配消失問題や勾配爆発問題が発生し、効率的な学習ができません。
今回は、これらの問題を解決する代表的な手法であるXavier初期化He初期化について調べてみました。

なぜ重み初期化が重要なのか?

勾配消失・勾配爆発問題

ニューラルネットワークでは、誤差逆伝播法を使用して重みを更新します。しかし、重みの初期値が不適切だと以下の問題が発生します:

  • 勾配消失問題: 勾配が層を遡るにつれて指数的に小さくなり、初期層の重みがほとんど更新されない
  • 勾配爆発問題: 勾配が層を遡るにつれて指数的に大きくなり、学習が不安定になる

解決のアプローチ

これらの問題を解決するために、各層の出力のばらつき(分散)を適切に保つことが重要です。つまり:

  • 順伝播時:各層の出力の分散を一定に保つ
  • 逆伝播時:各層の勾配の分散を一定に保つ

Xavier初期化(Glorot初期化)

基本概念

Xavier初期化は、2010年にXavier Glorotらによって提案された手法です。

線形活性化関数や双曲線正接(tanh)関数、シグモイド関数などの対称な活性化関数に適しています。

数学的な導出

記号の定義

まず、使用する記号を定義します:

  • x^{(l-1)}: l-1層の出力(l層への入力)
  • W^{(l)}: l層の重み行列
  • z^{(l)} = W^{(l)} x^{(l-1)}: l層の線形結合(活性化関数適用前)
  • y^{(l)} = f(z^{(l)}): l層の出力(活性化関数適用後)
  • n_{in}^{(l)}: l層への入力数
  • n_{out}^{(l)}: l層からの出力数

基本仮定

Xavier初期化では以下の仮定を置きます:

  1. 独立性: 入力x_iと重みW_{ij}は互いに独立
  2. 平均ゼロ: E[x_i] = E[W_{ij}] = 0
  3. 同一分布: 同一層内の重みと入力は同じ分布に従う

順伝播の分析

l層のj番目のニューロンの出力を考えます:

z_j^{(l)} = \sum_{i=1}^{n_{in}^{(l)}} W_{ji}^{(l)} x_i^{(l-1)}

この分散を計算します:

\text{Var}(z_j^{(l)}) = \text{Var}\left(\sum_{i=1}^{n_{in}^{(l)}} W_{ji}^{(l)} x_i^{(l-1)}\right)

重みと入力が独立なので:

\text{Var}(z_j^{(l)}) = \sum_{i=1}^{n_{in}^{(l)}} \text{Var}(W_{ji}^{(l)} x_i^{(l-1)})

= \sum_{i=1}^{n_{in}^{(l)}} \text{Var}(W_{ji}^{(l)}) \text{Var}(x_i^{(l-1)})

E[W_{ji}^{(l)}] = E[x_i^{(l-1)}] = 0なので)

重みと入力が同一分布に従うとすると:

\text{Var}(z_j^{(l)}) = n_{in}^{(l)} \cdot \text{Var}(W^{(l)}) \cdot \text{Var}(x^{(l-1)})

順伝播の条件: 各層で分散を保持したい場合:

\text{Var}(z^{(l)}) = \text{Var}(x^{(l-1)})

これより:

n_{in}^{(l)} \cdot \text{Var}(W^{(l)}) = 1

\therefore \text{Var}(W^{(l)}) = \frac{1}{n_{in}^{(l)}}

逆伝播の分析

逆伝播では、誤差の勾配が各層を遡って伝播されます。l層での勾配を\frac{\partial C}{\partial z^{(l)}}とします。

l-1層への勾配の伝播:

\frac{\partial C}{\partial z_i^{(l-1)}} = \sum_{j=1}^{n_{out}^{(l)}} \frac{\partial C}{\partial z_j^{(l)}} \frac{\partial z_j^{(l)}}{\partial z_i^{(l-1)}}

活性化関数が線形またはほぼ線形(勾配≈1)の場合:

\frac{\partial z_j^{(l)}}{\partial z_i^{(l-1)}} = W_{ji}^{(l)}

したがって:

\frac{\partial C}{\partial z_i^{(l-1)}} = \sum_{j=1}^{n_{out}^{(l)}} W_{ji}^{(l)} \frac{\partial C}{\partial z_j^{(l)}}

この分散を計算:

\text{Var}\left(\frac{\partial C}{\partial z_i^{(l-1)}}\right) = \text{Var}\left(\sum_{j=1}^{n_{out}^{(l)}} W_{ji}^{(l)} \frac{\partial C}{\partial z_j^{(l)}}\right)

= \sum_{j=1}^{n_{out}^{(l)}} \text{Var}(W_{ji}^{(l)}) \text{Var}\left(\frac{\partial C}{\partial z_j^{(l)}}\right)

= n_{out}^{(l)} \cdot \text{Var}(W^{(l)}) \cdot \text{Var}\left(\frac{\partial C}{\partial z^{(l)}}\right)

逆伝播の条件: 勾配の分散を保持したい場合:

\text{Var}\left(\frac{\partial C}{\partial z^{(l-1)}}\right) = \text{Var}\left(\frac{\partial C}{\partial z^{(l)}}\right)

これより:

n_{out}^{(l)} \cdot \text{Var}(W^{(l)}) = 1

\therefore \text{Var}(W^{(l)}) = \frac{1}{n_{out}^{(l)}}

Xavier初期化の妥協案

順伝播条件:\text{Var}(W^{(l)}) = \frac{1}{n_{in}^{(l)}}

逆伝播条件:\text{Var}(W^{(l)}) = \frac{1}{n_{out}^{(l)}}

両方を同時に満たすことは一般的に不可能なので、Xavierは調和平均を提案:

\text{Var}(W^{(l)}) = \frac{2}{n_{in}^{(l)} + n_{out}^{(l)}}

これは以下の式とも表現できます:

\text{Var}(W^{(l)}) = \frac{1}{\frac{n_{in}^{(l)} + n_{out}^{(l)}}{2}}

実装方法

一様分布を使用する場合

import numpy as np

def xavier_uniform(n_in, n_out):
    limit = np.sqrt(6 / (n_in + n_out))
    return np.random.uniform(-limit, limit, (n_in, n_out))

正規分布を使用する場合

def xavier_normal(n_in, n_out):
    std = np.sqrt(2 / (n_in + n_out))
    return np.random.normal(0, std, (n_in, n_out))

He初期化(Kaiming初期化)

基本概念

He初期化は、2015年にKaiming Heらによって提案された手法です。ReLU系の活性化関数(ReLU、Leaky ReLU、ELUなど)に最適化されています。

なぜXavier初期化では不十分なのか?

ReLU関数は非対称な活性化関数です:

  • 入力が正の場合:そのまま出力
  • 入力が負の場合:0を出力

この非対称性により、ReLUを使用する場合、Xavier初期化では分散が半分になってしまいます。

数学的な導出

ReLU関数の特性分析

ReLU関数は以下のように定義されます:

\begin{align} f(x) = \max(0, x) = \begin{cases} x & \text{if } x > 0 \\ 0 & \text{if } x \leq 0 \end{cases} \end{align}

重要な特性:

  1. 非対称性: 負の入力を0にクリップ
  2. 確率的振る舞い: 入力が正規分布N(0, \sigma^2)に従う場合、出力の期待値と分散が変化

入力が正規分布に従う場合の分析

入力z \sim N(0, \sigma^2)のとき、ReLU出力y = \text{ReLU}(z)の統計量を計算:

期待値:
E[y] = E[\text{ReLU}(z)] = \int_0^{\infty} z \cdot \frac{1}{\sqrt{2\pi\sigma^2}} e^{-\frac{z^2}{2\sigma^2}} dz

この積分を計算すると:
E[y] = \frac{\sigma}{\sqrt{2\pi}}

分散:
E[y^2] = \int_0^{\infty} z^2 \cdot \frac{1}{\sqrt{2\pi\sigma^2}} e^{-\frac{z^2}{2\sigma^2}} dz = \frac{\sigma^2}{2}

したがって:
\text{Var}(y) = E[y^2] - (E[y])^2 = \frac{\sigma^2}{2} - \left(\frac{\sigma}{\sqrt{2\pi}}\right)^2

= \frac{\sigma^2}{2} - \frac{\sigma^2}{2\pi} = \sigma^2\left(\frac{1}{2} - \frac{1}{2\pi}\right)

近似的に:\text{Var}(y) \approx \frac{\sigma^2}{2}

He初期化の導出

l層のニューロンの出力を考えます:

z_j^{(l)} = \sum_{i=1}^{n_{in}^{(l)}} W_{ji}^{(l)} y_i^{(l-1)}

ここで、y_i^{(l-1)} = \text{ReLU}(z_i^{(l-1)})です。

前層の出力がz_i^{(l-1)} \sim N(0, \text{Var}(z^{(l-1)}))に従うとすると:

\text{Var}(y_i^{(l-1)}) = \frac{1}{2} \text{Var}(z_i^{(l-1)})

l層の線形結合の分散:

\text{Var}(z_j^{(l)}) = \sum_{i=1}^{n_{in}^{(l)}} \text{Var}(W_{ji}^{(l)}) \text{Var}(y_i^{(l-1)})

= n_{in}^{(l)} \cdot \text{Var}(W^{(l)}) \cdot \frac{1}{2} \text{Var}(z^{(l-1)})

分散保持条件: \text{Var}(z^{(l)}) = \text{Var}(z^{(l-1)})

n_{in}^{(l)} \cdot \text{Var}(W^{(l)}) \cdot \frac{1}{2} = 1

\therefore \text{Var}(W^{(l)}) = \frac{2}{n_{in}^{(l)}}

より一般的な分析:fan_in vs fan_out

逆伝播を考慮した場合:

  • fan_in mode: 順伝播を重視 → \text{Var}(W) = \frac{2}{n_{in}}
  • fan_out mode: 逆伝播を重視 → \text{Var}(W) = \frac{2}{n_{out}}

実際のフレームワークでは用途に応じて選択可能です。

一般化:異なる活性化関数への拡張

He初期化は、活性化関数の「有効な勾配」を考慮して一般化できます:

\text{Var}(W) = \frac{2}{\text{gain}^2 \cdot n_{in}}

ここで、\text{gain}は活性化関数依存の係数:

  • ReLU: \text{gain} = \sqrt{2}
  • Leaky ReLU (negative_slope=\alpha): \text{gain} = \sqrt{\frac{2}{1+\alpha^2}}
  • SELU: \text{gain} = \frac{3}{4}

従って、ReLUの場合:
\text{Var}(W) = \frac{2}{2 \cdot n_{in}} = \frac{1}{n_{in}}

ただし、一般的な実装では簡略化して\text{Var}(W) = \frac{2}{n_{in}}が使用されます。

実装方法

一様分布を使用する場合

def he_uniform(n_in, n_out):
    limit = np.sqrt(6 / n_in)
    return np.random.uniform(-limit, limit, (n_in, n_out))

正規分布を使用する場合

def he_normal(n_in, n_out):
    std = np.sqrt(2 / n_in)
    return np.random.normal(0, std, (n_in, n_out))

実践的な使い分け

Xavier初期化を使用する場合

  • 活性化関数: tanh、sigmoid、線形関数
  • ネットワーク: 比較的浅いネットワーク
  • 用途: 従来的なフィードフォワードネットワーク

He初期化を使用する場合

  • 活性化関数: ReLU、Leaky ReLU、ELU、Swish
  • ネットワーク: 深いネットワーク(ResNet、DenseNetなど)
  • 用途: 現代的な深層学習モデル

深層学習フレームワークでの実装

PyTorch

import torch.nn as nn

# Xavier初期化
nn.init.xavier_uniform_(layer.weight)
nn.init.xavier_normal_(layer.weight)

# He初期化
nn.init.kaiming_uniform_(layer.weight, mode='fan_in', nonlinearity='relu')
nn.init.kaiming_normal_(layer.weight, mode='fan_in', nonlinearity='relu')

TensorFlow/Keras

from tensorflow.keras.initializers import GlorotUniform, GlorotNormal, HeUniform, HeNormal

# Xavier初期化
initializer = GlorotUniform()  # または GlorotNormal()

# He初期化
initializer = HeUniform()  # または HeNormal()

# 層に適用
Dense(64, kernel_initializer=initializer)

実験結果の比較

適切な初期化手法を選択することで、以下のような改善が期待できます:

  1. 収束速度の向上: より少ないエポック数で最適解に到達
  2. 安定した学習: 勾配の爆発や消失を防止
  3. 最終精度の向上: より良いローカル最適解への到達

まとめ

重みの初期化は、ニューラルネットワークの学習成功の鍵となる重要な要素です。活性化関数に応じて適切な初期化手法を選択することで、効率的で安定した学習が可能になります。

  • 対称な活性化関数(tanh、sigmoid): Xavier初期化
  • ReLU系の活性化関数: He初期化

現代の深層学習では、ReLU系の活性化関数が主流であるため、He初期化がデフォルトの選択肢となることが多いです。ただし、具体的な問題やアーキテクチャに応じて、最適な初期化手法を実験的に確認することも重要です。

参考

https://cvml-expertguide.net/terms/dl/optimization/weight-initialization/

Discussion