层归一化 LayerNorm:Transformer 中的标准归一化

FreeGuideOnline 最新 2026-06-21

什么是层归一化

层归一化(Layer Normalization,LayerNorm)是一种用于稳定和加速深度神经网络训练的技术。与批归一化(Batch Normalization)在批次维度上进行标准化不同,层归一化在特征维度上进行标准化,使得每个样本的所有特征均值为 0、标准差为 1。这种特性使其非常适合处理序列数据,成为 Transformer 架构中的标准归一化方式。

为什么需要层归一化

深度网络在训练时,每一层的输入分布会随着前一层参数更新而改变,这种现象叫做 内部协变量偏移(Internal Covariate Shift)。层归一化通过固定每一层输入的均值和方差来缓解这一问题,从而带来以下好处:

  • 加速收敛:使损失曲面更平滑,允许使用更大的学习率。
  • 降低对初始化的敏感性:即使权重初始值不够理想,逐层标准化也能稳定训练。
  • 缓解梯度消失/爆炸:将激活值控制在合理范围内。
  • 适应小批次或动态输入:不像批归一化那样依赖批次统计量,在批次大小变化或仅为 1 时依然稳定。

层归一化的计算过程

对于一个输入向量 ( \mathbf{x} = (x_1, x_2, ..., x_H) ) ,层归一化的计算分为三步。

1. 计算统计量

特征维度上计算均值和方差:

[ \mu = \frac{1}{H}\sum_{i=1}^{H} x_i ]

[ \sigma^2 = \frac{1}{H}\sum_{i=1}^{H} (x_i - \mu)^2 ]

这里 ( H ) 是隐藏层的神经元数量(即特征数)。

2. 标准化

用得到的均值和方差将输入标准化:

[ \hat{x}_i = \frac{x_i - \mu}{\sqrt{\sigma^2 + \epsilon}} ]

其中 ( \epsilon ) 是一个很小的常数(例如 ( 10^{-5} ) ),防止除零。

3. 缩放和平移

为了让网络能够学习到更有表达能力的分布,引入可学习的参数 ( \gamma ) (缩放因子)和 ( \beta ) (偏移因子):

[ y_i = \gamma , \hat{x}_i + \beta ]

这两个参数与原始输入 ( \mathbf{x} ) 的维度相同,通过反向传播更新。

最终输出 ( \mathbf{y} = (y_1, y_2, ..., y_H) ) 即为层归一化的结果。

层归一化与批归一化的对比

对比维度 层归一化 (LayerNorm) 批归一化 (BatchNorm)
标准化轴 特征维度(单个样本内) 批次维度(同一特征跨样本)
依赖批次大小 不依赖,批次大小 = 1 也稳定 强依赖,小批次时统计量不可靠
适用场景 适合 RNN、Transformer 等序列模型 适合 CNN、固定前馈网络
计算开销 单个样本内计算,开销小 需要跨样本计算,引入额外通信(分布式训练)
训练/推理一致性 完全一致,无需保存滑动平均 推理时需使用训练阶段保存的滑动均值和方差

层归一化在序列建模中优势明显,因为序列长度可能动态变化,批归一化很难跨时间步维护稳定统计量。

在 Transformer 中的应用

Transformer 模型大量使用层归一化,主要出现在两个位置:残差连接之后每个子层之前(或之后,取决于具体变体)。

原始 Transformer 的 Post-LN 结构

在 “Attention Is All You Need” 论文中,每个子层(自注意力和前馈网络)的计算顺序为:

输出 = LayerNorm( x + Sublayer(x) )

这种在残差加法之后施加归一化的方式称为 Post-LN

改进的 Pre-LN 结构

后来的研究发现,将层归一化放在子层之前(Pre-LN)有助于训练更深的 Transformer,使梯度流动更顺畅:

输出 = x + Sublayer( LayerNorm(x) )

Pre-LN 已经成为许多现代 Transformer(如 GPT 系列、ViT 等)的默认选择。

代码实现示例(PyTorch 风格)

import torch
import torch.nn as nn

class LayerNorm(nn.Module):
    def __init__(self, features, eps=1e-6):
        super().__init__()
        self.gamma = nn.Parameter(torch.ones(features))
        self.beta  = nn.Parameter(torch.zeros(features))
        self.eps = eps

    def forward(self, x):
        # x shape: (batch_size, ..., features)
        mean = x.mean(-1, keepdim=True)
        std  = x.std(-1, keepdim=True, unbiased=False)
        return self.gamma * (x - mean) / (std + self.eps) + self.beta

在实际框架中,直接调用 nn.LayerNorm 即可,内部实现会针对特定硬件优化。

层归一化的变体与扩展

  • RMSNorm:只使用均方根(Root Mean Square)进行缩放,移除均值中心化,计算更高效,常用于 LLaMA 等大模型。
  • DeepNorm:结合深度缩放的层归一化,专门为训练非常深的 Transformer 设计。
  • PowerNorm:在标准化时引入幂项,以应对不同分布的数据。

所有这些变体都保留了层归一化“每个样本独立归一化”的核心思想,只是在统计量的选择和缩放策略上有所不同。

总结

层归一化是深度学习中不可或缺的基础组件。它通过单样本内跨特征的标准化,解决了小批次动态序列场景下的训练稳定性问题。尤其在 Transformer 架构中,LayerNorm 配合残差连接,支撑起了从机器翻译到大规模语言模型的各类成功应用。理解其原理和计算过程,能够帮助你在设计或调试网络时做出恰当选择。


熟练使用层归一化,是深入掌握现代深度学习模型的必修课。