现在位置: 首页 > PyTorch 教程 > 正文

PyTorch torch.nn.LayerNorm 函数

PyTorch torch.nn 参考手册 PyTorch torch.nn 参考手册


torch.nn.LayerNorm 是 PyTorch 中的层归一化模块。

与批归一化不同,层归一化在单个样本的特征维度上进行归一化,不依赖 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 参考手册 PyTorch torch.nn 参考手册