【NLP251】Transformer精讲 残差链接与层归一化
精讲部分,主要是对Transformer的深度理解方便日后从底层逻辑进行创新,对于仅应用需求的小伙伴可以跳过这一部分,不影响正常学习。
1. 残差模块
何凯明在2015年提出的残差网络(ResNet),Transformer在2016年提出时正好踏上了ResNet的东风,所以就顺其自然的加上了这一部分以提高特征的提取能力,残差模块(Residual Block)是残差网络(ResNet)中的核心组件,其设计原理是为了解决深度神经网络训练中的退化问题,即随着网络层数的增加,网络的性能反而可能下降。残差模块通过引入恒等映射(Identity Mapping)和残差连接(Residual Connection)来缓解这一问题。残差模块是实践证明有效的模块对于数学原理的证明目前还没有较为清晰的推导,我来简单说一下他的原理。
恒等映射(Identity Mapping)
恒等映射是指输入直接通过一个“快捷方式”传递到后面的层,而不需要经过任何变换。这种设计允许输入信息在网络中直接流动,不受中间层的影响。
残差连接(Residual Connection)
残差连接是指将输入 x 直接加到网络的输出上。具体来说,如果网络的输出是 F(x),那么残差模块的最终输出是 F(x)+x。这种设计使得网络可以通过学习残差函数 F(x) 来优化原始函数 H(x),即 H(x)=F(x)+x。
残差函数(Residual Function)
残差函数 F(x) 是网络中需要学习的函数,它表示输入 x 经过一系列变换后的结果。通过残差连接,网络实际上是在学习 F(x) 来逼近目标函数 H(x),而不是直接学习 H(x)。这种设计使得网络更容易优化,因为 F(x) 只需要学习 H(x) 与 x 之间的差异,即H(x)=F(x)+x≈ x。由此我们可知F(x)趋近于0。
激活函数
在残差模块中,通常会在残差连接之后添加一个激活函数(如ReLU),以引入非线性特性。这样可以确保网络的表达能力,同时保持残差连接的线性特性。
权重层(Weight Layers)
残差模块中的权重层可以包括卷积层、全连接层等,用于对输入进行变换。这些权重层通常包含多个层,如图中所示的两个权重层。
当 F(x) 趋近于0时的意义
梯度流:当 F(x) 趋近于0时,残差块的输出 y 将主要由输入 x 决定。这意味着即使在深层网络中,梯度也可以直接通过恒等映射传播回输入层,从而缓解梯度消失问题。
我们可以从数学角度、非严格证明一下它为什么能够解决梯度消失问题。
假设现在存在一个神经网络,它由多个残差结构相连(类似于Transformer的结构)。每个残差结构被定义为F(x,W),这一结构是由一个复杂结构和一个残差链接并行组成的,其中x代表残差输入的数据,W代表该结构中的权重。设xi,xi+1分别代表残差结构F()的输入和输出,设xI代表整个神经网络的输入,令relu激活函数为r(y)=max(0,x),简写为r()。由此可得:
残差网络中的前向传播过程:
残差网络中的反向传播过程:
由于“1+”结构的引入,残差网络能够有效地避免梯度消失现象,即在求解过程中梯度不致变为零。这使得深层网络的梯度可以直接传递至浅层,从而使得整个迭代过程更加稳定。此外,残差网络在更新梯度时将部分乘法操作转化为加法操作,这一改变显著提升了计算效率。
网络深度:残差网络允许构建非常深的网络,因为即使深层网络的权重层输出趋近于0,网络仍然可以通过恒等映射学习到有效的特征表示。
优化难度:当 F(x) 趋近于0时,优化问题变得相对简单,因为网络可以通过调整权重层的输出来最小化损失函数,即使权重层的输出很小或接近0。
特征重用:残差块允许网络在深层中重用浅层的特征表示,从而提高模型的表达能力和泛化能力。
2. 层归一化
层归一化是实践上证明有效的中间过程特征处理方法,在目前大多数网络结构的重要层后都会加一个归一化层,Layer Normalization(层归一化)是一个至关重要的部分,它是一种特定的归一化技术,它在2016年被提出,用于减少训练深度神经网络时的内部协方差偏移(internal covariate shift)。而我们要讲的Transformer也是在同年(2016)层归一化提出不久后发表出来的,所以在构造网络时也加入了从层归一化。
归一化在现在的网络结构中被广泛的应用,之后会出一期详细的进行讲解。链接会被放到这一位置方便小伙伴们学习。
我们来简单讲一下归一化在NLP领域的应用。
首先,为什么要进行归一化操作?
- 减少内部协方差偏移:在深度学习模型训练过程中,参数的更新会影响后续层的激活分布,这可能导致训练过程不稳定。Layer Normalization通过规范化每一层的输出来减轻这种效应,有助于稳定训练过程。
- 加速训练速度:归一化可以使得梯度更稳定,这通常允许更高的学习率,从而加快模型的收敛速度。
- 减少对初始值的依赖:由于Layer Normalization使得模型对于输入数据的分布变化更为鲁棒,因此可以减少模型对于参数初始值的敏感性。
- 允许更深层网络的训练:通过规范化每层的激活,Layer Normalization可以帮助训练更深的网络结构,而不会那么容易出现梯度消失或爆炸的问题。
接下来,第二个问题为什么要进行层归一化?
通过前面的学习我们知道对于自然语言的处理通常是在三个维度上进行的
(batch_ size, vocal_ size, input_ dimensions)或
(batch_ size,time_ step, input_ dimensions )
出去特征维度 input_ dimensions还有两个维度,一个是批次维度,另一个是时间维度或词表维度
也就对应了两种归一化即批归一化(Batch Normalization)和层归一化(Layer Normalization)。
那为什么不进行批归一化呢?其实也不是绝对的,主要是经过以下三方面的考量,为了方便大家理解在说明之前我们先来认识以下这两种归一化方式分别是什么逻辑
在自然语言处理(NLP)中,层归一化(Layer Normalization,LN)比批归一化(Batch Normalization,BN)更常用,原因如下:
-
变长序列:NLP任务中的输入序列长度不固定,层归一化能有效处理变长序列,而批归一化依赖于批次中的数据均值和方差,可能会受到序列长度变化的影响。换句话说就是在三个批次中提取到的特征分别是(填充,0.5775,0.3798)提取到的数据均值和方差就不准确,即便是将填充替换为某一数字,仍然无法像其他 input_ dimensions数字一样体现有效的特征信息,故而算出的数据均值和方差也会受到影响
-
小批次训练:NLP任务中通常使用较小的批次大小,BN在小批次时较小的样本数很难提取出具有广泛代表意义的数据均值和方差,导致均值和方差估计不稳定,而LN不依赖于批次大小,适应性更强。
-
RNN和Transformer:尤其在Transformer模型中,层归一化能够在每个样本的特征维度上进行归一化,避免了批归一化需要跨样本计算均值和方差的问题,从而提高了模型的训练稳定性。
所以呀基于上述考量我们多采用LN即层归一化方式。