--- created: 2025-08-03 21:19:11 tags: - "Research" - "基础" - "Transformer" - "LayerNorm" - "归一化" --- ### 为什么要做 normalization Normalization通过将一部分不重要的信息损失掉,以此来**降低拟合难度以及过拟合的风险**,从而**加速模型收敛**。其目的是**让分布稳定下来**(**降低各个维度数据的方差**) - 不同的特征具有不同数量级的数据,它们对线性组合后的结果的影响所占比重就很不相同,数量级大的特征显然影响更大。做Normalization可以协调在特征空间上的分布,**更好地进行梯度下降**; - 在神经网络中,特征经过线性组合后,还要经过激活函数,如果某个特征数量级过大,在经过激活函数时,就会提前进入它的饱和区间(比如sigmoid激活函数),即不管如何增大这个数值,它的激活函数值都在 1 附近,不会有太大变化,这样激活函数就对这个特征不敏感。 在神经网络用 SGD 等算法进行优化时,不同量纲的数据会使网络失衡,很不稳定。 ### Normalization方式 主要包括以下几种方法:BatchNorm(2015年)、LayerNorm(2016年)、InstanceNorm(2016年)、GroupNorm(2018年)。 - BatchNorm: batch方向做归一化,算NHW的均值,对小batchsize效果不好;BN主要缺点是对batchsize的大小比较敏感,由于每次计算均值和方差是在一个batch上,所以如果batchsize太小,则计算的均值、方差不足以代表整个数据分布; - LayerNorm: channel方向做归一化,算CHW的均值,主要对RNN作用明显; - InstanceNorm: 一个channel内做归一化,算H*W的均值,用在风格化迁移;因为在图像风格化中,生成结果主要依赖于某个图像实例,所以对整个batch归一化不适合图像风格化中,因而对HW做归一化。可以加速模型收敛,并且保持每个图像实例之间的独立。 - GroupNorm: 将channel方向分group,然后每个group内做归一化,算(C//G)HW的均值;这样与batchsize无关,不受其约束。在batchsize<16的时候, 可以使用这种归一化。 - SwitchableNorm: 将BN、LN、IN结合,赋予权重,让网络自己去学习归一化层应该使用什么方法。 - Weight Standardization: 权重标准化,2019年约翰霍普金斯大学研究人员提出。 ![image.png](https://raw.githubusercontent.com/student-zsbd/myImageHost/master/20241031112931.png) ### 在Transformer中为什么选择LayerNorm, 而不是BatchNorm - BN是在同一维度进行归一化,但**对于一些问题来说,一个序列的输入同一”维度“上的信息可能不是同一个维度。** 这么说可能有些绕,举一个NLP的例子来看: 下面是一个batch size=2案例,第一个batch是"你好", 第二个是"机器学习" 按BN方式,在第一"维度"进行归一化的话就是将"你"和"机"的特征进行归一化,但这明显不是一个维度的信息。显然BN在此处使用是很不合理的。NLP中同一batch样本的信息关联不大(差异很大,但要学习的就是这种特征),更多应该概率句子内部(单个样本内部)维度的归一化。 - 为什么[[CNN-卷积层, 池化层 与 全连接层|图像处理]]用batch normalization效果好,而[[Transformer|自然语言处理]]用 layer normalization好? >CV使用BN是认为不同卷积核feature map(channel维)之间的差异性很重要,LN会损失channel的差异性,对于batch内的不同样本,同一卷积核提取特征的目的性是一致的,所以使用BN仅是为了进一步保证同一个卷积核在不同样本上提取特征的稳定性。 > > 而NLP使用LN是认为batch内不同样本同一位置token之间的差异性更重要,而embedding维,网络对于不同token提取的特征目的性是一致的,使用LN是为了进一步保证在不同token上提取的稳定性。 ### 作用 1. **稳定训练**:LayerNorm有助于稳定模型的训练过程,因为它减少了不同层之间激活值的方差,使得梯度分布更加一致。 2. **加速收敛**:由于LayerNorm减少了激活值的方差,它可以帮助模型更快地收敛。 3. **提高泛化能力**:LayerNorm通过规范化特征,有助于提高模型对输入数据分布变化的鲁棒性,从而提高模型的泛化能力。 4. **辅助反向传播**:LayerNorm有助于更有效地进行反向传播,因为它确保了在网络的每一层中梯度的规模大致相同,减少了梯度消失或爆炸的风险。 5. **与残差连接协同工作**:LayerNorm通常与[[残差链接 (Residual Skip Connect)]]一起使用,在残差连接之后应用LayerNorm可以进一步稳定训练,并允许更有效地信息流动。 6. **保持特征尺度一致性**:在深层网络中,不同层的特征尺度可能会有很大差异,LayerNorm通过规范化特征,保持了特征尺度的一致性。 ### 实现 在Transformer模型中,层归一化(Layer Normalization,简称LayerNorm)的实现通常遵循以下步骤: 1. **计算均值和方差**: 对于给定的输入张量 \($X$\),其形状为 \($[batch\_size, seq\_length, hidden\_size]$\),LayerNorm首先计算每个样本在该层的激活值的均值和方差。具体来说,对于每个样本(假设独立于批次),沿着`hidden_size`维度计算均值 \($\mu$\) 和方差 \($\sigma^2$\)。 $$ \mu = \frac{1}{H} \sum_{i=1}^{H} X_{i} $$$$ \sigma^2 = \frac{1}{H} \sum_{i=1}^{H} (X_{i} - \mu)^2 $$ 其中,\($H$\) 是隐藏层的大小,也就是 \($hidden\_size$\)。 2. **归一化**: 使用计算得到的均值和方差对每个激活值进行归一化处理,使得新的激活值的分布具有0的均值和1的方差。 $$ \hat{X} = \frac{X - \mu}{\sqrt{\sigma^2 + \epsilon}} $$ 其中,\($\epsilon$\) 是一个很小的常数(例如 \($1e-6$\)),用于防止除以0的情况。 3. **缩放和平移**: 归一化后的值通过两个可学习的参数进行缩放和平移,这两个参数分别是 \($\gamma$\)(缩放因子)和 \($\beta$\)(偏移因子)。这两个参数的维度与 \($hidden\_size$\) 相同。 $$ Y = \gamma \hat{X} + \beta $$ 其中,\($Y$\) 是LayerNorm后的输出。 在实际的深度学习框架中,如PyTorch或TensorFlow,LayerNorm的实现通常封装成了一个模块或层,可以很容易地集成到模型中。以下是使用PyTorch实现LayerNorm的简单示例: ```python import torch import torch.nn as nn class TransformerLayerNorm(nn.Module): def __init__(self, hidden_size, eps=1e-6): super(TransformerLayerNorm, self).__init__() self.gamma = nn.Parameter(torch.ones(hidden_size)) self.beta = nn.Parameter(torch.zeros(hidden_size)) self.eps = eps def forward(self, x): mean = x.mean(dim=-1, keepdim=True) std = x.std(dim=-1, keepdim=True) x = (x - mean) / (std + self.eps) x = self.gamma * x + self.beta return x ``` 在Transformer模型中,LayerNorm通常在每个子层([[Self-Attention|自注意力层]]和前馈网络层)之后应用,并且是在残差连接之前。这样的顺序有助于模型在训练过程中保持稳定的激活分布。