核心内容摘要
申鹤:脚尖上的艺术,腿法间的魅影
1 LayerNorm背景:在神经网络中,每一层输出都将作为下一层的输入。
问题:在训练过程中,前一层参数的微小更新,所带来的输出会导致后一层输入的分布发生剧烈变化。
这就是层与层之间的动态失调。
俗称内部协变量偏移(Internal Covariate Shift)。
现象:比如,第一层参数稍微改了一点点(比如权重从
0.
10.
1
1变成
0.
110.
110.
。
经过非线性激活函数放大,第二层的输入分布就会发生剧烈抖动。
经过非线性激活函数放大,第二层的输入分布就会发生剧烈抖动。
梯度消失与爆炸: 如果没有归一化,神经元的输出可能非常大。
如果你使用的是 tanh 或 sigmoid 激活函数,输入太大就会进入“饱和区”,梯度几乎为 0,模型就“僵死”了。
LayerNorm 把数值强行拉回均值
方差 1 的范围,确保它们正好落在激活函数最敏感(斜率大)的区域。
例子:假设你正在训练一个深层网络,其中一层有一个神经元,它使用的是 Sigmoid 激活函数。
Sigmoid 公式:f(x)=11+e−xf(x) = \frac{1}{1 + e^{-x}}f(x)=1+e−x1求导:f(x)(1-f(x))它的特性:当xxx在000附近时,斜率(梯度)最大(约
0.
250.
250.
;当x5x 5x5或x−5x -5x−5时,曲线变得非常平坦,斜率接近 0。
情况 A:没有归一化(进入饱和区)假设由于前几层的权重初始化得比较大,或者没有控制好,传到这一层的输入向量为:x=[
1
0,
1
0,
1
0,
0]x = [
1
0,
1
0,
1
0,
0]x=[
1
0,
1
0,
1
0,
0]输出:f(
10.
≈
99995f(
10.
\approx
99995f(
10.
≈
99995f(
12.
≈
99999f(
12.
\approx
99999f(
12.
≈
99999你会发现,无论输入是 10 还是 12,输出几乎全是 1。
梯度计算:Sigmoid 的导数是f(x)(1−f(x))f(x)(1 - f(x))f(x)(1−f(x))。
对于x=10x=10x=10,梯度≈
99995×(1−
0.
=
000049\approx
99995 \times (1 -
0.
=
000049≈
99995×(1−
0.
=
000049。
后果: 这个梯度太小了!
在反向传播时,这个微弱的信号传到前一层几乎就消失了。
模型“僵死”了,因为它觉得自己已经做得很好了(输出都是
,或者它根本不知道该往哪改。
公式:为了解决内部协变量偏移这一问题,LayerNorm 通过将每一层神经元的输出强制转化为“均值为
方差为 1”的标准分布,使得不管前面的层怎么折腾,传给后层的信号始终是平稳、可预测的。
如果没有 LN:数值可能非常大(如
或非常小(如
0.
。
如果后面接的是 Sigmoid 或 Tanh 激活函数,这些数值会落入极其平坦的“饱和区”,导致梯度几乎为 0。
有了 LN:它把数值强行拽回到 0 附近。
结果:激活函数的斜率在这里最大,梯度能够顺畅回传,防止了模型因“梯度消失”而彻底僵死。
公式如下:xix_ixi:输入向量xxx中的第iii个元素(特征)。
iii:特征的索引,取值范围是[1,d][1, d][1,d]。
注意,LayerNorm 是在特征维度(最后一个维度)上做归一化,而不是在 Batch 维度。
nnn(或ddd):向量的长度(隐藏层维度)。
σ2+ϵ\sqrt{\sigma^2 + \epsilon}