Py学习  »  机器学习算法

硬核!深度学习中的Normalization必知必会

AINLP • 3 年前 • 238 次点击  

作者 |  史晓峰

NewBeeNLP公众号

在深度学习领域,往往需要处理复杂的任务场景,一般使用较深层数的模型进行网络设计,这就涉及到复杂困难的模型调参:学习率的设置,权重初始化的设置以及激活函数的设置等。

深度学习之所以难以训练,一个重要的原因在神经网络中层与层之间存在着极强的关联性,并且目前绝大部分使用的都是基于梯度下降的方法进行反向传播训练。

当网络的底层发生微弱变化时,这些变化会随着层数的增加被放大,意味着对于高层网络要不断进行参数更新以适应底层参数的变化,如此导致了训练的困难,很容易会出现梯度爆炸或者梯度消失的情况,导致模型训练失败。

本文主要分析深度学习中的各种标准化方法(「BN,LN,IN,GN,WN」)的原理,来帮助实现对深度学习网络的训练。

深度学习中的 Normalization,因为神经网络里主要有两类实体:神经元或者连接神经元的边,所以按照规范化操作涉及对象的不同可以分为两大类。

  • 一类是对第 L 层每个神经元的激活值或者说对于第L+1 层网络神经元的输入值进行 Normalization操作,比如BatchNorm/LayerNorm/InstanceNorm/GroupNorm 等方法都属于这一类;
  • 另外一类是对神经网络中连接相邻隐层神经元之间的边上的权重进行规范化操作,比如 Weight Norm 就属于这一类。

一般机器学习里看到的损失函数里面加入的对参数的的 L1/L2 等正则项,本质上也属于这第二类规范化操作。L1 正则的规范化目标是造成参数的稀疏化,就是争取达到「让大量参数值取得 0 值的效果」,而 L2 正则的规范化目标是有效减小原始参数值的大小。有了这些规范目标,通过具体的规范化手段来改变参数值,以达到避免模型过拟合的目的。

Droupout

droupout的原理

Droupout的提出是为了解决模型的过拟合问题,为了解决过拟合问题,一般会采用模型集成的方法,即训练多个模型进行组合。droupout作用于每份小批量训练数据,随机丢弃部分神经元的机制相当于每次迭代的过程,都在训练不同结构的神经网络。

「droupout可以看做是一种深度网络的集成方法,是一种轻量化的Bagging;也可以看成是一种数据增强的方法,可以认为通过网络层面上实现数据的增强。」

在Droupout的实现中,要求某个神经元以某一给定的概率丢弃,在当前batch训练中暂停该神经元。那么对于N个神经元节点的网络,在droupout作用下,可以看做是 个模型的集成,这 个模型的可以认为原始模型的子网络,他们共享部分权重,并且具有相同的网络层数,并且模型整体的参数数目不变,这样就极大的简化了要实现bagging所需的运算或者时所需的训练数据量。

「对于任意一个神经元,在每个batch的训练过程中,都与一组随机的神经元集合进行共同运算,这个过程就减少了全体神经元之间的联合适应性,减少过拟合的风险」

具体的计算方法在各个介绍dropout的文章中均有所介绍,这里简明扼要,如下所示

没有droupout的网络的神经网络的计算方程为

如果加入了droupout,那么计算方程就变成了

这里的伯努利函数表示是的是按照给定的概率p,将激活值y变为0。如果给定droupout-rate=p,那么经过droupout之后该层的神经元激活值与没有droupout的时候的比值为 ,并且我们知道在预测阶段是不使用droupout的,因此一般情况下,在包含droupout操作的网络中,在该层之后要对权重乘以稀疏 ,这样在预测的时候就可以直接使用权重了。

BatchNormalization

按照BN论文所述,BN主要针对深度学习模型中的存在的ICS问题进行的设计。

内部协变量转移ICS

在深度学习网络的训练过程中,由于网络中参数的变化而引起内部节点数据分布发生变化的过程称为内部协变量转移(Internal Covariate Shift-ICS)。

正如开篇所述,在神经网络中,对于各个层之间的输出,由于在层内经过权重点乘和非线性激活的操作,每个层之间的输入信号的分布显然会发生变化,并且这种变化随着模型深度的增加会不断增大。

ICS会造成的问题

  • 随着网络深度的增加,高层的网络参数要不断适应新的数据分布,会使训练周期变长;
  • 前向传播时,如果使用sigmoid或者tanh激活函数,随着深度的增加,高层的网络参数受到底层参数的影响,会使得在进行梯度反向求导时,高层的网络输出落入激活函数的饱和区,也就是梯度消失。

如何缓解ICS问题

针对ICS带来的问题和形成的原因(网络深度增加,层与层之间的数据分布发生改变,并且改变不断累积),一般有两种解决方法

  • 使用非饱和的激活函数,例如使用Relu或者Elu等激活函数,可以一定程度解决梯度消失的问题
  • 让神经网络层与层之间输入保持在一个稳定的分布中,也就是数据Normalization处理

白化whitening

在机器学习中一般使用的PCA或者ZCA白化方法,对输入的数据分布进行变换。主要实现以下的数据转换

  • 输入数据具有相同的均值和方差

    • PCA控制所有的特征分布均值为0,方差为1
    • ZCA控制所有的特征分布均值为0,方差相同
  • 去除特征的相关性

但是直接对数据进行白化处理会存在两个问题

  • 计算成本过高,在每次训练的时候对神经网络每一层都进行白化操作
  • 白化改变了数据分布,会改变网络层中输入数据本身的表达能力,底层网络学习到的参数信息会被白化操作丢失了

针对白化存在的问题,提出了BN,一方面是简化计算过程,降低计算开销;另一方面是「经过批规范化使输出的数据尽量保留原始的数据特征」,可以认为BN也是一种白化操作方法,相比白化更简单,并且「设置了学习参数,使得BN可以一定程度保留原始的数据特征」

Batch的含义是,BN操作针对一个MiniBatch的数据样本,Normalization是指数据标准化。

BN中对每个MiniBatch中的样本的每个特征进行单独的标准化处理,「处理之后每个特征变成均值为0,标准化为 的分布」;并且在白化的基础上在增加一个线性变换,使输出的数据能够尽量恢复原本输入数据的表达能力。

MLP训练过程

前向传播

在训练过程中,使用MiniBatch进行网络训练

如图1所示为MLP神经网络中的某一层,当前层的节点数量为4,也就是当前层的输入的数据特征数量为4,也就是4行;在当前MiniBatch中包含m个样本,也就是m列。对于BN来说,针对的是一个MiniBatch上的每个特征上单独进行的标准化处理,处理方式就是针对每个特征,计算当前MiniBatch中的该特征的均值和方差,然后对原始数据进行缩放和平移标准化处理。

对于MLP中的计算过程如下

  • 输入:每个MiniBatch的数据 ,样本数量为

  • 学习参数:线性变换参数

  • 算法步骤为:

    计算当前MiniBatch中所有样本的每个特征的均值和方差,也就是在特征的维度上计算均值和方差,统计的范围是当前MiniBatch中的样本

    其中参数 是一个很小的常数,是为了防止原数据的方差为

    经过该处理,意味着对「原始数据进行规范化处理,使得当前层的输入的每个特征的分布的均值为 ,方差为 。即满足关系式 。这样会使得数据分布变得统一并且稳定,但是这同样导致了数据表达能力的缺失,「为了使得规范化的数据尽量保留原始数据的信息,在BN中引入两个可学习参数,对标准化的数据进行线性变换」

    经过上述操作,如果可学习参数满足关系 ,这相当于对数据进行了反向变换 ,保留了原始输入的数据信息。

    • 对规范化的数据进行缩放和平移处理得到批规范化处理后的数据
    • 根据每个特征的均值和方差,对输入数据进行规范化处理得到
    • 在当前MiniBatch上计算每个特征的平均值 和方差

如上就是训练阶段BN层前向传播的计算过程。

反向传播

BN层,学习参数为

根据上述的前向过程,使用目标函数对BN层参数进行更新。

通过链式求导进行参数更新。

测试过程

正如上面训练过程部分的计算,训练的时候按照每个Batch进行数据训练和参数更新,但是在测试的时候,每次只输入一个数据而不像训练时候使用的是一个Batch的数据,并且测试阶段使用的是测试阶段固定的参数,不涉及参数更新,因此BN的计算和训练阶段有所不同。

在训练阶段针对每个BN层固定并保留了每个MiniBatch数据特征的均值和方差 ,并计算均值和方差的无偏估计

根据这个无偏估计对测试数据在BN阶段进行标准化

其中参数 是网络模型训练阶段学习到的参数。

上述为BN在MLP的计算过程

CNN中BN的应用


如图所示为卷积计算过程,只考虑单个样本,输入数据为 ,使用两个 的卷积核,步长为2进行计算,得到的输出维度为

「和MLP方式不同,对于卷积中BN的应用特别说明。」

CNN中,以二维卷积为例,输入的数据维度为 ,表示数据样本数量为 ,特征图的高度为 ,宽度为 ,上一层卷积核的数量为 。那么对于BN 的维度上进行特征的标准化处理, 可以看做卷积对上一层进行了 次卷积计算,得到了 个特征,在这个 个特征中,每个特征对应的样本数量为 ,并且每个样本的位置为 ,这意味着对于每个特征,该特征包含的数据的数量为

训练过程

前向传播

在训练时,以MiniBatch为最小单位进行迭代

  • 输入:待进入激活函数的变量NHWC

  • 学习参数:

  • 算法过程

    整体算法按照论文所述如下

在训练阶段,在图中所示的行 对应输入变量的特征,也就是 ,对每一个特征进行BN计算,由此需要循环计算BN,在每次循环中,按照图中所示方法进行MiniBatch计算,计算方法和MLP的方式相同,也就是说在MLP的基础上,CNN会在卷积核数量上进行BN的循环计算。

测试过程

在上图中同样描述了在Inference阶段BN的计算,在C维度上,进行BN的Inference计算。

BN的作用

  • 「BN使网络中每层的数据分布相对稳定,加速模型的学习速度」

    BN会使得每层的数据的均值和方差控制在一定的范围内,上层网络不必不断去适应底层网络中的输入的变化,实现了层与层之间的解耦,允许每一层进行独立学习,会提高神经网络的学习速度。

  • 「BN使模型对网络中参数不太敏感,简化调参过程,学习更稳定」

    在深度学习网络中,调参艰难且复杂,学习率过大的话,参数更新的步伐过大,容易出现震荡和不收敛,使用BN可以使得网络不收到参数数值大小的影响。

    如果参数为 ,对其进行缩放为 ,输入数据为 ,那么原来的值为 ,方差为 ,对于缩放之后的值,假设均值为 ,方差为 ,则存在关系式

    对数据进行BN处理,忽略公式中的参数

    也就是经过BN处理后,数据 是相同的。

    对参数进行更新

    可以看到权重的缩放不会影响到对 的梯度计算

    BN之后对参数的更新,可以得到如果权重越大,也就是 越大, 越小,「这意味着权重 的梯度更小,如此BN就保证了梯度不会依赖于参数的缩放,使得参数的更新处在更加稳定的状态。」

    「如此,BN抑制了参数变化会随着网络深度增加被放大的问题,使得网络对参数大小的适应能力更好。」

  • 「BN允许网络使用饱和性激活函数,缓解梯度消失」

    正如ICS带来的问题,随着网络的深度和复杂性增加,底层网络的变化会累积到高层网络中,会导致模型的训练了很容易进入到激活函数的梯度饱和区;通过BN处理,数据都变成期望为0方差为1的高斯分布,使得激活函数的数据数据更容易落在激活函数的梯度非饱和区,并且通过学习参数 可以使得BN之后的数据对原始数据的信息得以保留。

  • 「BN具有一定正则化效果」

    每一个batch的数据的均值和方差会有所不同,这为网络学习过程中增加了随机噪音,这个Droupout通过随机舍弃神经元为网络带来噪音的方式相似,在一定程度上对模型起到了正则化的效果。

BN的思考

  • BN以每个MiniBatch对每个特征进行规范化处理,这要求每个MiniBatch的统计量是整体统计量的近似估计,这就意味着每个MiniBatch和整体数据应该是近似同分布的,如此,如果Minibatch比较小的话,那么不同Batch之间的数据分布差异性会更大;
  • 分布差距较小的MiniBatch的数据可以认为规范化处理给模型带来了噪声,可以增加模型的泛化能力;如果每个MiniBatch的数据分布差距较大,那么不同的MiniBatch的数据将会进行不同的数据变换,着会增加模型的训练难度;
  • BN适用于每个MiniBatch的数据分布差距不大的情况,并且训练数据要进行充分的shuffle,不然效果反而变差,增大训练难度;
  • BN不适用于动态的网络结构和RNN网络。
  • BN由于基于MiniBatch的归一化统计量来代替全局统计量,相当于在梯度计算中引入了噪声,因此一般不适用与生成模型,强化学习等对噪声敏感的网络中。

LayerNormalization

正如上述BN由于使用的是MiniBatch的统计量,因此无法处理RNN网络结构。对于RNN网络结构来说,当前时间步输出的改变和下一个时间的输入高度相关,为了减小ICS的影响,对每层的神经元的输入数据进行归一化处理。

在某一个时间步,假设当前的数据维度为 ,在 维度上进行标准化,和BN不同的是,BN计算Batch中所有样本的每个特征的标准化,LN分别对单个样本进行计算,对每个样本的所有特征进行标准化。计算方式相比BN更加简单。

LN在MLP,CNN和RNN的应用如下所示

「LN一般只用于RNN的场景下,在CNN中LN规范化效果不如BN,WN,GN,IN的」

计算方式

计算当前层的参数的平均值和方差

其中 对应着当前层神经元的数量,也就是RNN中隐藏层节点数,计算所有隐藏层节点的均值和方差,然后使用整个隐藏层的均值和方差来对当前隐藏层进行标准化。

标准化之后经过缩放和平移得到LN之后的输出输出

参数 是学习参数 和BN类似,规范化后的数据进行缩放和平移,以保留原始数据的信息。

LN思考以及和BN的区别

  • LN针对当个训练样本进行规范化,不像BN那样依赖于一个MiniBatch的数据,因此避免了不同样本之间的相互影响,可以适用于动态网络场景,RNN和自然语言处理领域
  • LN不需要保存MiniBatch的均值和方差,相比BN计算量更小
  • BN针对单个神经元进行规范化,不同神经元的输入经过平移和缩放使不同神经元的分布在不同的区间中,LN对于整个一层的神经元进行转换,所有的输入全部控制在同一个区间范围内。在CNN中,假设输入的是一张图片,同一层的输入特征表征着不同的特征,例如有的位置神经元表征的是颜色信息,有的位置神经元表征的是形状信息,那么这个时候BN是更合适的,使不同的特征信息进行分别处理,但是如果这种输入使用LN处理,将一个样本的所有特征的分布全部标准化到一个统一的区间,显然会降低模型的表达能力。

LN 有效的原因研究

在NLP中,尤其是在BERT等各种变体中,目前基本都是使用LN归一化,那么为什么LN是有效的呢?2019年关注了论文“Understanding and Improving Layer Normalization”,按照论文所属,均值跟方差对梯度的正则化才是层归一化有效的原因,而不是之前广泛认识的前向向量分布稳定性,另外根据论文所述,层归一化的参数部分增加了模型过拟合的风险,引入的参数在很多任务中都带来了效果的下降。

根据链式求导法则

其中 是模型的损失, 对应着经过LN标准化之后的向量, 对应着原始数据输入,根据上面部分LN的推导,存在关系式

对于原始输入,未经过LN正则化,损失函数对输入变量 的梯度

是梯度的均值和方差

如果经过LN正则化,也就是

那么损失函数 的梯度为

对应的均值和方差为

那么满足关系

如此,LN实现了对梯度的缩放和平移变换

Inastance Normalization(IN)

「InstanceNormalization主要是针对CNN设计,并且是为了弥补BN的对batch的依赖。」

LN去放弃了BN对batch的依赖,为了能够统计均值和方差,把同层内所有神经元的响应值作为统计范围。为了进一步缩小统计范围,减少噪声的输入,对于CNN,同一个卷积层内,每一个卷积核都会产生一个输出通道,每个输出通道对应一个二维平面,尺寸都为 ,也包含多个激活神经元。在卷积层中来说,将单个样本的每个输出通道内的神经元会作为一个集合来统计均值和方差。使用该二维平面统计得到的均值和方差,对该二维平面内的元素进行标准化。

MLP和RNN无法使用InstanceNormalization,可以将InstanceNormalization看做Btahc=1的BN。

「InstanceNormalization对于图像生成任务效果明显优于BN,在图像分类上不如BN。」

GroupNormalization(GN)

对于LN使用同层所有神经元作为统计范围,用于RNN中。IN将CNN中同一卷积层中每个卷积核对应的输出通道单独作为统计范围。虽然LN用于RNN中,IN用于CNN中,但是可看出这是两种计算情况,LN使用当前层的所有神经元,IN使用当前的单个featuremap,设计的GN的统计范围是介于两者之间,对CNN的在输出通道上进行分组,在分组范围内进行统计。

「GN在要求batch比较小的场景下或者目标检测,视频分类等任务由于BN」

WeightNormalization

目前没有API的方式可以实现权重归一化,对于前面的BN和LN,都是将输入的数据进行规范化,WN是从权重的角度进行规范化,WN将权值向量 在欧式范数和其方向上进行解耦成参数向量 和参数标量 ,在训练时使用SGD分别优化这两个参数。

WN和BN不同,与样本数量无关,可以用于batchsize较小和RNN等动态场景中;并且WN不会在梯度计算中像BN那样引入噪声。

WN训练方法

在神经网络中,一个节点的计算可以表示为

其中 是一个k维的特征向量, 是该神经元节点的输出,输出是一个标量。在计算得到损失之后会根据损失使用SGD的优化策略对参数 进行更新。

WN的归一化策略将 分解

其中 表示 的欧氏范数,当 并且 时,WN会被还原为普通的计算方式。

如果将参数 固定为 时,只对参数 进行优化,相当于只优化 的方向,并保留其范数的大小;如果固定参数 ,只对参数 进行优化 ,相当于只优化 的范数,并且保留其方向。

在优化 时,一般优化 参数 来实现,即

参数更新方式

其中 是损失函数值, 表示损失函数 对参数 求偏导。

进行整理可以得到

上述转换可以看出WN的两个重要特征

  • 表明WN对权重梯度进行了 的缩放

  • 表明WN将梯度投影到远离 的方向

    观察式子 ,可以得到 垂直,所以 会非常接近参数 的垂直方向,如此对矫正梯度更新方向非常有效。

    和梯度更新值中的噪声量成正比,而且 是和更新量成反比,所以当更新值中噪音较多时,更新值就会变小,也就是WN具有自稳定的作用。由此在训练的时候可以使用较大的学习率。

WN&BN的关系

假设 分别为 的期望和方差,如果使用BN的方式进行标准化

当网络只有一层并且输入样本服从期望为0,方差为1的独立分布时,有 并且 ,此时BN和WN是等价的。

Mean-Only Batch Normalization

在每一层的layer的激活函数之前

虽然将权重 进行了分离,但是每一层激活函数之前的输出的均值仍然与 有关。将BN和WN进行结合,采用移动平均计算每个minibatch的均值 ,由此

在激活函数之前的 的反向传播的损失函数为

这相当于只进行减去均值的BN,舍弃了BN中的除去方差的操作,这样处理就避免了BN中除去方差带来的额外噪声。

WN 相比BN的优势

  • WN对权重W进行规范化,没有引入batch的依赖,适用于RNN网络,BN不能用于RNN,这是因为RNN是变长的,RNN是基于timestep进行计算,如果直接使用BN,需要保存每个time step下batch的均值和方差,效率很低
  • BN基于batch进行均值和放计算,而不是基于整个Training Set来计算,这相当于在梯度计算的时候引入了噪声。BN不适合对噪声敏感的强化学习,生成模型。WN通过对标量g和向量V对权重W进行规范化,重写向量v是固定的。
  • 不需要额外空间保存batch的均值和方差,在实现WN时,对训练过程中的正向传递和反向计算的计算开销更小。

Normalization为什么有效

  • 权重伸缩不变性

    回忆上面BN,LN的计算方式,当权重进行缩放使,得到规范化之后的值是不变的

    这是因为当权重缩放时,对应的均值和方差都会等比例缩放,最终分子分母相抵消。

    这个性质带来的好处

    • 提高反向传播的效率

      避免了反向传播时会因为梯度过大或者过小导致出现梯度爆炸或消失的问题

    • 具有参数正则化的效果,可以使用更高的学习率

      下层的权重值越大,其梯度就会越小,如此,参数的变化就会越稳定,这相当于实现了参数正则化的效果,避免参数的大幅震荡,提高了网络的泛化能力。

  • 数据伸缩不变性

    当数据x按照常量进行伸缩时,得到的规范化后的值保持不变

    其中

    「数据伸缩不变性仅对BN,LN,CN有效,这三种规范化方式,都是对输入的数据进行规范化,当数据进行缩放时,对应的均值和方差都会变化。」

    「数据伸缩不变性可以有效的减少梯度弥散,减少对学习率的选择」

本文参考资料

[1]

Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift: https://arxiv.org/abs/1502.03167

[2]

How Does Batch Normalization Help Optimization?: https://arxiv.org/abs/1805.11604

[3]

深度学习中的Normalization模型: http://www.cvmart.net/community/article/detail/368

[4]

机器之心:深度学习的Normalization: https://www.jiqizhixin.com/articles/2018-08-29-7

[5]

详解深度学习中的Normalization,BN/LN/WN: https://zhuanlan.zhihu.com/p/33173246

[6]

Batch Normalization原理与实战: https://zhuanlan.zhihu.com/p/34879333

[7]

知乎:WN: https://zhuanlan.zhihu.com/p/55102378

[8]

Blog: BN,WN,LN: http://mlexplained.com/2018/01/13/weight-normalization-and-layer-normalization-explained-normalization-in-deep-learning-part-2/

[9]

加速网络收敛——BN、LN、WN与selu: http://skyhigh233.com/blog/2017/07/21/norm/

[10]

Batchnorm原理详解: https://cloud.tencent.com/developer/article/1052868


- END -


由于微信平台算法改版,公号内容将不再以时间排序展示,如果大家想第一时间看到我们的推送,强烈建议星标我们和给我们多点点【在看】。星标具体步骤为:

(1)点击页面最上方"AINLP",进入公众号主页。

(2)点击右上角的小点点,在弹出页面点击“设为星标”,就可以啦。

感谢支持,比心

欢迎加入AINLP技术交流群
进群请添加AINLP小助手微信 AINLPer(id: ainlper),备注NLP技术交流

推荐阅读

这个NLP工具,玩得根本停不下来

完结撒花!李宏毅老师深度学习与人类语言处理课程视频及课件(附下载)

从数据到模型,你可能需要1篇详实的pytorch踩坑指南

如何让Bert在finetune小数据集时更“稳”一点

模型压缩实践系列之——bert-of-theseus,一个非常亲民的bert压缩方法

文本自动摘要任务的“不完全”心得总结番外篇——submodular函数优化

Node2Vec 论文+代码笔记

模型压缩实践收尾篇——模型蒸馏以及其他一些技巧实践小结

中文命名实体识别工具(NER)哪家强?

学自然语言处理,其实更应该学好英语

斯坦福大学NLP组Python深度学习自然语言处理工具Stanza试用

关于AINLP

AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括文本摘要、智能问答、聊天机器人、机器翻译、自动生成、知识图谱、预训练模型、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLPer(id:ainlper),备注工作/研究方向+加群目的。


阅读至此了,分享、点赞、在看三选一吧🙏

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/110896
 
238 次点击