PyTorch torch.nn.LayerNorm 関数

PyTorch torch.nn リファレンスマニュアル


torch.nn.LayerNormPyTorch のレイヤー正規化モジュールです。

バッチ正規化とは異なり、レイヤー正規化は単一サンプルの特徴次元に対して正規化を行い、batch size に依存しません。

関数定義

torch.nn.LayerNorm(normalized_shape, eps=1e-05, elementwise_affine=True)

パラメータの説明:

  • normalized_shape(int または list): 正規化する次元。
  • eps(float): 数値安定性のための epsilon。デフォルトは 1e-5。
  • elementwise_affine(bool): 学習可能なスケールとシフトを使用するかどうか。デフォルトは True。

数学的原理

レイヤー正規化の式:

y = (x - E[x]) / sqrt(Var[x] + eps) * gamma + beta

バッチ正規化との違い:レイヤー正規化は特徴の最後の次元で平均と分散を計算します。


使用例

例 1: 基本の使い方

特徴に対してレイヤー正規化を行います:

実例

import torch
import torch.nn as nn

# レイヤー正規化:最後の次元で正規化
ln = nn.LayerNorm(normalized_shape=10)

# 入力:batch=4、特徴次元=10
x = torch.randn(4, 10)

# 順伝播
output = ln(x)

print("入力形状:", x.shape)
print("出力形状:", output.shape)
print("n元の入力の最初の行:", x[0].tolist())
print("正規化後の最初の行:", output[0].tolist())

例 2: 多次元入力

3D または 4D 入力を処理します:

実例

import torch
import torch.nn as nn

# シーケンス次元で正規化:(batch, seq, features)
ln_seq = nn.LayerNorm(normalized_shape=64)

# 3D 入力
x_3d = torch.randn(2, 10, 64)
output_3d = ln_seq(x_3d)
print("3D 入力:", x_3d.shape, "-> 出力:", output_3d.shape)

# 4D 入力 (画像など): (batch, height, width, channels)
# LayerNorm は最後の channel 次元で正規化
ln_channel = nn.LayerNorm(normalized_shape=128)
x_4d = torch.randn(2, 8, 8, 128)
output_4d = ln_channel(x_4d)
print("4D 入力:", x_4d.shape, "-> 出力:", output_4d.shape)

例 3: Transformer での使用

典型的な LayerNorm の使用:

実例

import torch
import torch.nn as nn

class TransformerBlock(nn.Module):
    def __init__(self, d_model, nhead):
        super(TransformerBlock, self).__init__()
        self.self_attn = nn.MultiheadAttention(d_model, nhead, batch_first=True)
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        self.ffn = nn.Sequential(
            nn.Linear(d_model, d_model * 4),
            nn.GELU(),
            nn.Linear(d_model * 4, d_model)
        )

    def forward(self, x):
        # Self-attention with residual
        attn_out, _ = self.self_attn(x, x, x)
        x = self.norm1(x + attn_out)

        # FFN with residual
        ffn_out = self.ffn(x)
        x = self.norm2(x + ffn_out)

        return x

# テスト
block = TransformerBlock(d_model=512, nhead=8)
x = torch.randn(4, 100, 512)  # (batch, seq, d_model)
output = block(x)

print("入力形状:", x.shape)
print("出力形状:", output.shape)

例 4: 学習可能なパラメータを使用しない

スケールとシフトのない純粋な正規化:

実例

import torch
import torch.nn as nn

# 学習可能なパラメータなし
ln = nn.LayerNorm(16, elementwise_affine=False)

x = torch.randn(4, 16)
output = ln(x)

# weight と bias なし
print("weight があるか:", hasattr(ln, 'weight'))
print("bias があるか:", hasattr(ln, 'bias'))
print("n出力形状:", output.shape)

正規化手法の比較

手法 正規化次元 Batch 依存 適用シーン
BatchNorm batch 次元 である CNN、batch が安定
LayerNorm 特徴次元 否 Transformer、RNN
InstanceNorm チャンネル+空間 否 スタイル変換
GroupNorm チャンネルグループ 否 小さい batch のシーン

よくある質問

Q1: LayerNorm と BatchNorm の違いは?

LayerNorm は batch に依存せず、系列モデルや batch の変化が大きいシーンに適しています。

Q2: normalized_shape はどう選択する?

通常は特徴次元を選択します。BERT では 768 や 1024 です。

Q3: なぜ Transformer は LayerNorm を使うのか?

Transformer の入力シーケンス長は可変であり、LayerNorm の方が安定します。


使用シーン

nn.LayerNorm主な適用シーンは次のとおりです:

  • Transformer アーキテクチャ: BERT、GPT など
  • リカレントニューラルネットワーク: LSTM、GRU
  • 可変長シーケンスの処理: batch サイズが固定されていない

ヒント:LayerNorm は Transformer の標準装備であり、残差接続の後(Post-LN)または前(Pre-LN)に配置します。


PyTorch torch.nn リファレンスマニュアル

その他の拡張