层归一化(LayerNorm)
概述
层归一化就是把一个样本的所有特征值,调整成均值为 0、方差为 1 的标准分布,然后再用两个可学习参数 γγγ 和 βββ 做缩放和平移。
它和 BatchNorm 的区别:BatchNorm 是在 batch 维度上做归一化,LayerNorm 是在单个样本的特征维度上做归一化,不依赖 batch 大小,适合序列模型。
公式
给定一个向量 x=x1,x2,...,xdx = x_1, x_2, \\dots, x_dx=x1,x2,...,xd:
μ=1d∑i=1dxi \mu = \frac{1}{d} \sum_{i=1}^{d} x_ iμ=d1i=1∑dxi
σ=1d∑i=1d(xi−μ)2+ϵ \sigma = \sqrt{\frac{1}{d} \sum_{i=1}^{d} (x_i - \mu)^2 + \epsilon} σ=d1i=1∑d(xi−μ)2+ϵ
x^i=xi−μσ \hat{x}_i = \frac{x_i - \mu}{\sigma} x^i=σxi−μ
LN(x)i=γix^i+βi \text{LN}(x)_i = \gamma_i \hat{x}_i + \beta_i LN(x)i=γix^i+βi
其中 ϵ\epsilonϵ 是很小的常数(如 10−510^{-5}10−5),防止除零。
数值例子
取向量 x=1.848,2.872,2.594,1.599x = 1.848, 2.872, 2.594, 1.599x=1.848,2.872,2.594,1.599。
第一步:均值
μ=1.848+2.872+2.594+1.5994=8.9134=2.22825 \mu = \frac{1.848 + 2.872 + 2.594 + 1.599}{4} = \frac{8.913}{4} = 2.22825 μ=41.848+2.872+2.594+1.599=48.913=2.22825
第二步:方差
σ2=(1.848−2.22825)2+(2.872−2.22825)2+(2.594−2.22825)2+(1.599−2.22825)24 \sigma^2 = \frac{(1.848 - 2.22825)^2 + (2.872 - 2.22825)^2 + (2.594 - 2.22825)^2 + (1.599 - 2.22825)^2}{4} σ2=4(1.848−2.22825)2+(2.872−2.22825)2+(2.594−2.22825)2+(1.599−2.22825)2
逐项计算:
- 1.848−2.22825=−0.380251.848 - 2.22825 = -0.380251.848−2.22825=−0.38025,平方 =0.14459= 0.14459=0.14459
- 2.872−2.22825=0.643752.872 - 2.22825 = 0.643752.872−2.22825=0.64375,平方 =0.41441= 0.41441=0.41441
- 2.594−2.22825=0.365752.594 - 2.22825 = 0.365752.594−2.22825=0.36575,平方 =0.13377= 0.13377=0.13377
- 1.599−2.22825=−0.629251.599 - 2.22825 = -0.629251.599−2.22825=−0.62925,平方 =0.39596= 0.39596=0.39596
总和 =1.08873= 1.08873=1.08873,除以 4:
σ2=0.27218 \sigma^2 = 0.27218 σ2=0.27218
σ=0.27218≈0.52171 \sigma = \sqrt{0.27218} \approx 0.52171 σ=0.27218 ≈0.52171
第三步:归一化 (忽略 ϵ\epsilonϵ)
x^i=xi−μσ \hat{x}_i = \frac{x_i - \mu}{\sigma} x^i=σxi−μ
- x^1=−0.38025/0.52171≈−0.7288\hat{x}_1 = -0.38025 / 0.52171 \approx -0.7288x^1=−0.38025/0.52171≈−0.7288
- x^2=0.64375/0.52171≈1.2339\hat{x}_2 = 0.64375 / 0.52171 \approx 1.2339x^2=0.64375/0.52171≈1.2339
- x^3=0.36575/0.52171≈0.7010\hat{x}_3 = 0.36575 / 0.52171 \approx 0.7010x^3=0.36575/0.52171≈0.7010
- x^4=−0.62925/0.52171≈−1.2061\hat{x}_4 = -0.62925 / 0.52171 \approx -1.2061x^4=−0.62925/0.52171≈−1.2061
假设 γ=1,1,1,1\gamma = 1, 1, 1, 1γ=1,1,1,1,β=0,0,0,0\beta = 0, 0, 0, 0β=0,0,0,0,则 LayerNorm 输出为:
LN(x)=−0.7288,1.2339,0.7010,−1.2061 \text{LN}(x) = -0.7288, 1.2339, 0.7010, -1.2061 LN(x)=−0.7288,1.2339,0.7010,−1.2061
残差连接(Residual Connection)
概述
残差连接就是把子层的输入直接加到子层的输出上
Output=x+Sublayer(x) \text{Output} = x + \text{Sublayer}(x) Output=x+Sublayer(x)
这样信息有一条"捷径"可以直接流过,不需要经过子层的变换。
作用
缓解梯度消失:反向传播时,梯度可以通过捷径直接回传;
保留恒等映射:如果子层学不到有用变换,至少可以输出 xx,不会比不加层更差;
让深层网络可训练:原始 Transformer 有 6 层编码器 + 6 层解码器,没有残差很难训练。
数值例子
假设子层(多头注意力)输出为 Z1=0.848,2.872,1.594,1.599Z_1 = 0.848, 2.872, 1.594, 1.599Z1=0.848,2.872,1.594,1.599,原始输入为 x=1,0,1,0x = 1, 0, 1, 0x=1,0,1,0。
残差相加:
x+Z1=1+0.848,0+2.872,1+1.594,0+1.599=1.848,2.872,2.594,1.599x + Z_1 = 1 + 0.848, 0 + 2.872, 1 + 1.594, 0 + 1.599 = 1.848, 2.872, 2.594, 1.599x+Z1=1+0.848,0+2.872,1+1.594,0+1.599=1.848,2.872,2.594,1.599
这个结果正好是上面 LayerNorm 例子的输入。所以实际顺序是:
输出=LayerNorm(x+MultiHeadAttention(x))\text{输出} = \text{LayerNorm}(x + \text{MultiHeadAttention}(x))输出=LayerNorm(x+MultiHeadAttention(x))
这就是原始论文的 Post-Norm 结构。
前馈网络(Feed Forward Network, FFN)与激活函数
FFN 是什么?
FFN 是 Transformer 中每个位置独立经过的一个小型全连接网络:
FFN(x)=Linear2(ReLU(Linear1(x))) FFN(x) = Linear_2(ReLU(Linear_1(x))) FFN(x)=Linear2(ReLU(Linear1(x)))
原始论文中:
- 输入/输出维度:dmodel=512d_{model} = 512dmodel=512
- 中间层维度:dff=2048d_{ff} = 2048dff=2048(扩展 4 倍)
- 第一层线性:512→2048512 \to 2048512→2048
- 激活函数:ReLU
- 第二层线性:2048→5122048 \to 5122048→512
为什么用 ReLU?
| 特性 | 说明 |
|---|---|
| 非线性 | 没有非线性,多层线性叠加还是线性模型 |
| 计算简单 | ReLU(x)=max(0,x)\text{ReLU}(x) = \max(0, x)ReLU(x)=max(0,x),导数只有 0 或 1 |
| 梯度好 | 正区间梯度恒为 1,缓解梯度消失 |
| 稀疏激活 | 负值输出 0,带来稀疏性 |
数值例子
为了手算,假设中间维度也是 4(实际是 4 倍),且两层线性都是单位阵,偏置为 0。
则 FFN 等价于对输入做 ReLU。
取 LayerNorm 的输出:
LN(x)=−0.7288,1.2339,0.7010,−1.2061 LN(x) = -0.7288, 1.2339, 0.7010, -1.2061 LN(x)=−0.7288,1.2339,0.7010,−1.2061
第一层线性(单位阵):
y1=LN(x)=−0.7288,1.2339,0.7010,−1.2061 y_1 = \text{LN}(x) = -0.7288, 1.2339, 0.7010, -1.2061 y1=LN(x)=−0.7288,1.2339,0.7010,−1.2061
ReLU:
y1relu=max(0,−0.7288),max(0,1.2339),max(0,0.7010),max(0,−1.2061)=0,1.2339,0.7010,0 \begin{aligned} y_1^{\text{relu}} &= \\max(0, -0.7288), \\max(0, 1.2339), \\max(0, 0.7010), \\max(0, -1.2061) \\ &= 0, 1.2339, 0.7010, 0 \end{aligned} y1relu=max(0,−0.7288),max(0,1.2339),max(0,0.7010),max(0,−1.2061)=0,1.2339,0.7010,0
第二层线性(单位阵):
FFN(x)=0,1.2339,0.7010,0 \text{FFN}(x) = 0, 1.2339, 0.7010, 0 FFN(x)=0,1.2339,0.7010,0
这些组件在多头注意力中的作用
text
输入 x
↓
多头自注意力 (Multi-Head Self-Attention)
↓
残差连接:x + Attention(x)
↓
层归一化:LayerNorm(x + Attention(x))
↓
前馈网络:FFN(...)
↓
残差连接:LN_out + FFN(LN_out)
↓
层归一化:LayerNorm(LN_out + FFN(LN_out))
↓
输出
各组件作用:
| 组件 | 作用 |
|---|---|
| 多头注意力 | 让序列内每个位置关注其他位置,捕捉依赖关系 |
| 残差连接 | 提供信息捷径,稳定梯度,让深层网络可训练 |
| 层归一化 | 标准化分布,加速收敛,防止梯度消失/爆炸 |
| 前馈网络 | 对每个位置独立做非线性变换,增强表示能力 |
| ReLU | 引入非线性,计算高效,梯度友好 |
例子:一个编码器层
输入
x=1,0,1,0 x = 1, 0, 1, 0 x=1,0,1,0
多头注意力输出
Attn(x)=Z1=0.848,2.872,1.594,1.599 Attn(x) = Z_1 = 0.848, 2.872, 1.594, 1.599 Attn(x)=Z1=0.848,2.872,1.594,1.599
残差 + LayerNorm
残差:
x+Z1=1.848,2.872,2.594,1.599x + Z_1 = 1.848, 2.872, 2.594, 1.599x+Z1=1.848,2.872,2.594,1.599
LayerNorm(计算过程见第一节):
LN1=−0.7288,1.2339,0.7010,−1.2061 \text{LN}_1 = -0.7288, 1.2339, 0.7010, -1.2061 LN1=−0.7288,1.2339,0.7010,−1.2061
前馈网络
第一层线性(单位阵):
y1=−0.7288,1.2339,0.7010,−1.2061y_1 = -0.7288, 1.2339, 0.7010, -1.2061y1=−0.7288,1.2339,0.7010,−1.2061
ReLU:
y1relu=0,1.2339,0.7010,0y_1^{\text{relu}} = 0, 1.2339, 0.7010, 0y1relu=0,1.2339,0.7010,0
第二层线性(单位阵):
FFN=0,1.2339,0.7010,0\text{FFN} = 0, 1.2339, 0.7010, 0FFN=0,1.2339,0.7010,0
第二次残差 + LayerNorm
残差:
LN1+FFN=−0.7288,1.2339,0.7010,−1.2061+0,1.2339,0.7010,0=−0.7288,2.4678,1.4020,−1.2061 \begin{aligned} \text{LN}_1 + \text{FFN} &= -0.7288, 1.2339, 0.7010, -1.2061 + 0, 1.2339, 0.7010, 0 \\ &= -0.7288, 2.4678, 1.4020, -1.2061 \end{aligned} LN1+FFN=−0.7288,1.2339,0.7010,−1.2061+0,1.2339,0.7010,0=−0.7288,2.4678,1.4020,−1.2061
LayerNorm:
-
均值:
μ=−0.7288+2.4678+1.4020−1.20614=1.93494=0.483725 \mu = \frac{-0.7288 + 2.4678 + 1.4020 - 1.2061}{4} = \frac{1.9349}{4} = 0.483725 μ=4−0.7288+2.4678+1.4020−1.2061=41.9349=0.483725
-
方差:
- −0.7288−0.483725=−1.212525-0.7288 - 0.483725 = -1.212525−0.7288−0.483725=−1.212525,平方 = 1.4702
- 2.4678−0.483725=1.9840752.4678 - 0.483725 = 1.9840752.4678−0.483725=1.984075,平方 = 3.9365
- 1.4020−0.483725=0.9182751.4020 - 0.483725 = 0.9182751.4020−0.483725=0.918275,平方 = 0.8432
- −1.2061−0.483725=−1.689825-1.2061 - 0.483725 = -1.689825−1.2061−0.483725=−1.689825,平方 = 2.8555
总和 = 9.1054,除以 4:
σ2=2.27635 \sigma^2 = 2.27635 σ2=2.27635
σ=2.27635≈1.5088 \sigma = \sqrt{2.27635} \approx 1.5088 σ=2.27635 ≈1.5088
- 归一化:
- −1.212525/1.5088≈−0.8036-1.212525 / 1.5088 \approx -0.8036−1.212525/1.5088≈−0.8036
- 1.984075/1.5088≈1.31501.984075 / 1.5088 \approx 1.31501.984075/1.5088≈1.3150
- 0.918275/1.5088≈0.60860.918275 / 1.5088 \approx 0.60860.918275/1.5088≈0.6086
- −1.689825/1.5088≈−1.1200-1.689825 / 1.5088 \approx -1.1200−1.689825/1.5088≈−1.1200
假设 γ=1\gamma = 1γ=1,β=0\beta = 0β=0,最终输出:
Output=−0.8036,1.3150,0.6086,−1.1200 \text{Output} = -0.8036, 1.3150, 0.6086, -1.1200 Output=−0.8036,1.3150,0.6086,−1.1200
这就是"你"经过一个完整 Transformer 编码器层后的表示。
总结
| 概念 | 通俗解释 | 数值例子中的体现 |
|---|---|---|
| LayerNorm | 把向量标准化成均值 0、方差 1,再缩放平移 | 1.848,2.872,2.594,1.599→−0.7288,1.2339,0.7010,−1.20611.848, 2.872, 2.594, 1.599 \to -0.7288, 1.2339, 0.7010, -1.20611.848,2.872,2.594,1.599→−0.7288,1.2339,0.7010,−1.2061 |
| 残差 | 输入直接加到子层输出上 | x+Z1=1.848,2.872,2.594,1.599x + Z_1 = 1.848, 2.872, 2.594, 1.599x+Z1=1.848,2.872,2.594,1.599 |
| FFN | 两层线性 + 激活,逐位置独立处理 | ReLU 后 0,1.2339,0.7010,00, 1.2339, 0.7010, 00,1.2339,0.7010,0 |
| ReLU | max(0,x)\max(0, x)max(0,x),非线性、简单、梯度好 | 负值变 0,正值不变 |
| 在多头注意力中的作用 | 注意力负责交互,残差和 LayerNorm 稳定训练,FFN 增强表示 | 最终输出 −0.8036,1.3150,0.6086,−1.1200-0.8036, 1.3150, 0.6086, -1.1200−0.8036,1.3150,0.6086,−1.1200 |
一句话: 多头注意力让模型"看"序列中其他位置,残差连接保证信息不丢、梯度好传,层归一化让分布稳定,前馈网络和 ReLU 给每个位置独立的非线性变换。四者配合,Transformer 才能堆得很深、训得很稳。