跳至主要內容

标准化总结

Genhiy...大约 7 分钟AI正则化

昇腾大模型|结构组件-1——Layer Norm、RMS Norm、Deep Normopen in new window

一般认为,Post-Norm在残差之后做归一化,对参数正则化的效果更强,进而模型的收敛性也会更好;而Pre-Norm有一部分参数直接加在了后面,没有对这部分参数进行正则化,可以在反向时防止梯度爆炸或者梯度消失,大模型的训练难度大,因而使用Pre-Norm较多。

BatchNorm

提示

论文题目:Batch Normalization: Accelerating Deep Network Training byReducing Internal Covariate Shift

论文地址:https://arxiv.org/pdf/1502.03167.pdf

公式及参数

y=xmean(x)Var(x)+epsgamma+beta \mathrm{y}=\frac{x-\mathrm{mean}(x)}{\sqrt{\mathrm{Var}(x)}+eps}*\mathrm{gamma}+\mathrm{beta}

参数:

  • (可学习参数)γ : weight of BatchNorm
  • (可学习参数)β : bias of BatchNorm
  • (统计量)running mean: 预测阶段会使用这个均值
  • (统计量)running var: 预测阶段会使用这个方差

优缺点

BN的优点:

  • 解决内部协变量偏移,简单来说训练过程中,各层分布不同,增大了学习难度,BN缓解了这个问题。当然后来也有论文证明BN有作用和这个没关系,而是可以使损失平面更加的平滑,从而加快收敛速度。
  • 缓解了梯度饱和问题(如果使用sigmoid这种含有饱和区间的激活函数的话),加快收敛。

BN的缺点:

  • Batch size比较小的时候,效果会比较差。因为他是用一个batch中的均值和方差来模拟全部数据的均值和方差。比如你一个batch只有2个样本,那你两个样本的均值和方差就不能很好地代表全班人的均值和方差,所以效果肯定就不好。
  • BN是计算机视觉CV的标配,但在自然语音处理NLP中效果一般较差,取而代之的是LN。

其他信息

Q:BatchNorm2d的参数γ和β数量是跟特征图的数量是一致的,并不是我们直观认为的num_featureHW个参数,这是为什么呢?

A:《百面机器学习》P221是这样解释的: BatchNorm批量归一化在卷积神经网络中应用时,需要注意卷积神经网络的参数共享机制。每一个卷积核的参数在不同位置的神经元当中是共享的,因此同一个特征图的所有神经元也应该被一起归一化!

换句话说就是,你一个特征图用的是共享的卷积核参数,所以这个特征图中的每个神经元(共H*W个)也应该共享参数γ\gamma, β\beta。如果有ff个卷积核,就对应ff个特征图和ff组不同的 γ\gammaβ\beta参数。

另一个解释:

假如某一层卷积层有6个特征图,每个特征图的大小是100*100,这样就相当于这一层网络有6*100*100个神经元,如果采用BN,就会有6*100*100个参数γ、β,这样岂不是太恐怖了。因此卷积层上的BN使用,其实也是使用了类似权值共享的策略,把一整张特征图当做一个神经元进行处理。

卷积神经网络经过卷积后得到的是一系列的特征图,如果min-batch sizes为m,那么网络某一层输入数据可以表示为四维矩阵(m,f,p,q),m为min-batch sizes,f为特征图个数,p、q分别为特征图的宽高。在cnn中我们可以把每个特征图看成是一个特征处理,因此在使用Batch Normalization,mini-batch size 的大小相当于m*p*q,于是对于每个特征图都只有一对可学习参数:γ、β。

总结来说:

对于某个特征图而言,一个batch共有m个这样的特征图,并且每个特征图有pq个神经元,把所有的m*p*q个神经元拉直,然后求得平均值和方差。 对m个这样特征图的pq个神经元的每个神经元,利用求出的平均值和方差做下数据变换。

LayerNorm

LayerNorm是大模型也是transformer结构中最常用的归一化操作,简而言之,它的作用是对特征张量按照某一维度或某几个维度进行0均值,1方差的归一化操作。

nn.LayerNorm(normalized_shape, eps=1e-05, elementwise_affine=True, device=None, dtype=None)
  • normalized_shape:归一化的维度,int(最后一维)list(list里面的维度),还是以(2,2,4)为例,如果输入是int,则必须是4,如果是list,则可以是[4], [2,4], [2,2,4],即最后一维,倒数两维,和所有维度。
  • eps:加在分母方差上的偏置项,防止分母为0。
  • elementwise_affine:是否使用可学习的参数γ\gammaβ\beta,前者开始为1,后者为0,设置该变量为True,则二者均可学习随着训练过程而变化。

BatchNorm 与 LayerNorm

BN抹平了不同特征之间的大小关系,而保留了不同样本之间的大小关系。这样,如果具体任务依赖于不同样本之间的关系,BN更有效,尤其是在CV领域,例如不同图片样本进行分类,不同样本之间的大小关系得以保留。

LN抹平了不同样本之间的大小关系,而保留了不同特征之间的大小关系。所以,LN更适合NLP领域的任务,其中,一个样本的特征实际上就是不同word embedding,通过LN可以保留特征之间的这种时序关系。

Layer Normalization和Batch Normalization一样都是一种归一化方法,因此,BatchNorm的好处LN也有,当然也有自己的好处:比如稳定后向的梯度,且作用大于稳定输入分布。然而BN无法胜任mini-batch size很小的情况,也很难应用于RNN。LN特别适合处理变长数据,因为是对channel维度做操作(这里指NLP中的hidden维度),和句子长度和batch大小无关。BN比LN在inference的时候快,因为不需要计算mean和variance,直接用running mean和running variance就行。

BN和LN在实现上的区别仅仅是:BN是对batch的维度去做归一化,也就是针对不同样本的同一特征做操作。LN是对hidden的维度去做归一化,也就是针对单个样本的不同特征做操作。因此,他们都可以归结为:减去均值除以标准差,施以线性映射。

对于NLP data来说,Transformer中应用BN并不好用,原因是前向和反向传播中,batch统计量及其梯度都不太稳定。而对于VIT来说,BN也不是不能用,但是需要在FFN里面的两层之间插一个BN层来normalized。

RMSNorm

动机是其发现Layernorm在对特征进行norm时,对特征进行平移并不能改变特征的分布,所以其删去了所有平移操作。作者认为这种模式在简化了Layer Norm的同时,可以在各个模型上减少约 7%∼64% 的计算时间。另外,分母处的ϵ\epsilon为防止除零进行的操作。

LayerNorm=xE[x]Var[x]+ϵγ+βRMSNorm=xMean(x2)+ϵγ LayerNorm=\frac{x-E[x]}{\sqrt{Var[x]+\epsilon}}*\gamma+\beta \\ RMSNorm=\frac{x}{\sqrt{Mean(x^{2})+\epsilon}}*\gamma

class RMSNorm(torch.nn.Module):
    def __init__(self, dim: int, eps: float = 1e-6):
        super().__init__()
        self.eps = eps
        self.weight = nn.Parameter(torch.ones(dim))

    def _norm(self, x):
        return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps)  ###RMS Norm公式

    def forward(self, x):
        if rms_norm is not None and x.is_cuda:
            return rms_norm(x, self.weight, self.eps)
        else:
            output = self._norm(x.float()).type_as(x)
            return output * self.weight

Deep Norm

【DL&NLP】再谈Layer-Norm:Pre-LN、Post-LN、DeepNormopen in new window

优质参考资料

【深度学习基础】BatchNorm,LayerNorm,InstanceNorm,GroupNorm 和 WeightNorm 的原理与PyTorch逐行实现open in new window