層正規化(Layer Normalization) そうせいきか(れいやーのーまりぜーしょん)
層正規化Layer NormalizationTransformer正規化学習安定化バッチ正規化
層正規化(Layer Normalization)について教えて
簡単に言うとこんな感じ!
ニューラルネットの各層の出力値が「大きくなりすぎたり小さくなりすぎたり」しないように正規化する技術だよ。1サンプルの中の全特徴量を使って正規化するから、バッチサイズに関係なく動く。TransformerやLLMで必須の技術なんだ!
層正規化(Layer Normalization)とは
層正規化(Layer Normalization) は、2016年にBaらが提案した1つのサンプルの中ですべての特徴量を正規化する手法です。各層の入力を平均0・分散1に変換し、学習パラメータγとβでスケールとシフトを調整します。
バッチ正規化(Batch Normalization)がバッチ内の複数サンプルをまとめて正規化するのに対し、層正規化は1サンプルだけで完結します。そのため「バッチサイズが小さい場合」「バッチサイズが1のRNN・Transformer」「バッチサイズが可変のオンライン学習」などバッチ正規化が使いにくい状況でも安定して動作します。
Transformerの登場とともに広く普及し、現在ではGPT・BERT・LLaMAなどほぼすべての大規模言語モデルでLayer Normalizationが採用されています。
バッチ正規化との比較
| 項目 | バッチ正規化 | 層正規化 |
|---|---|---|
| 正規化の単位 | バッチ内の同じ特徴量 | 1サンプルの全特徴量 |
| バッチサイズ依存 | あり(小バッチで不安定) | なし |
| 推論時の挙動 | 移動平均を使う(学習と別処理) | 学習・推論で同じ処理 |
| RNN・Transformerへの適用 | 困難 | 容易 |
| 計算コスト | やや低い | やや高い |
| 主な用途 | 画像(CNN) | テキスト(Transformer) |
import torch.nn as nn
# 層正規化の使い方
layer_norm = nn.LayerNorm(normalized_shape=512) # 特徴量次元を指定
# Transformerブロックでの典型的な使い方
class TransformerBlock(nn.Module):
def __init__(self, d_model, n_heads):
super().__init__()
self.attention = nn.MultiheadAttention(d_model, n_heads)
self.norm1 = nn.LayerNorm(d_model) # Attention後の正規化
self.ffn = nn.Linear(d_model, d_model)
self.norm2 = nn.LayerNorm(d_model) # FFN後の正規化
def forward(self, x):
x = self.norm1(x + self.attention(x, x, x)[0]) # Add & Norm
x = self.norm2(x + self.ffn(x))
return x
歴史と背景
- 2015年:Ioffe・SzegedyがBatch Normalizationを提案(CV分野で大成功)
- 2016年:Baら「Layer Normalization」を提案。RNN向けとして登場
- 2017年:Transformer論文でLayer Normalizationが採用、NLPの標準技術へ
- 2020年以降:Pre-LN(Normalizationを先に適用するスタイル)が安定性から主流に
Pre-LN vs Post-LN
| スタイル | 計算順序 | 特徴 |
|---|---|---|
| Post-LN(元Transformer) | Attention → Add → Norm | 精度が高いが学習初期が不安定 |
| Pre-LN | Norm → Attention → Add | 学習が安定。ウォームアップなしでも動くことがある |
関連用語
- グループ正規化 — 層正規化の派生手法
- 残差接続(Residual Connection) — 層正規化とセットで使うAdd & Norm
- ウォームアップ(学習率) — 層正規化と合わせて学習を安定化
- 自己注意機構(Self-Attention) — 層正規化が欠かせないTransformerの中核