何为归一化
一般意义上的归一化指的就是将不同scale的特征,基于它们各自的均值和标准差进行值压缩。处理后的值具有0均值和单位方差。
为何需要归一化
归一化通常用于解决不同特征的scale差异过大导致参数训练困难的问题。通常情况下,如果我们不对不同scale的特征进行处理而直接使用梯度下降的方法去进行优化,会导致不同scale的特征权值更新优化的方向不均衡的情况发生。举个简单的例子,假设我们只有两个特征f1和f2。其中f1的scale很小,范围在10-20之间,而f2的scale相对较大,范围在100-200之间。w1 和 w2分别对应它们的权重。那么由于特征f2的scale较大的缘故,w2一点微小的变化就会对最终结果产生巨大的影响,也会使损失函数的结果产生巨大的变化。体现在下图中就是w2 维度上的等loss曲线分布密集,而w1维度上的等loss曲线分布稀疏。 显然,这样的loss曲线分布会导致从图中任意的一个起始点到最终的loss最小值点的优化过程非常缓慢,因为我们需要配合f2这个大scale的数值而选择比较小的学习率,不然非常容易产生优化过冲而一直到不了loss最小值点。
然而,如果我们通过归一化技术就可以很好的解决这个问题,通过将f2的scale调整为和f1一样,我们可以放心的选择比较大的学习率而不用担心优化过冲的发生。最终的loss曲线和w1,w2的关系就会变成如下图所示的正圆形。 可以这么说,当需要使用梯度下降来进行参数优化的时候,归一化都是一个非常有用的技术。
深度学习中的归一化
那么在深度学习中,归一化是否重要呢?答案是肯定的。因为当前神经网络训练的核心算法反向传播同样基于梯度下降。
和其他基于梯度下降进行参数更新的算法一样,神经网络的输入同样也需要归一化来保证更加快速的收敛速度。但是,问题远不止于此。对于包含多个hidden layer的深层网络来说,随着每一层权重的不断更新,输入给下一层的数据的分布一直在不停的变化,导致下一层总是需要基于新的分布来进行参数的优化更新,这样就给模型的训练带来了极大的不稳定因素,导致模型总是无法收敛。换句话说,优化的前提是必须有相对不变的部分,通过固定这部分来对另一部分进行调整。而如果每个部分都在变,那优化过程就难以实现。这种在网络训练中,hidden layer输出分布不断变化的情况也被称之为Internal Covariate Shift。
技术一:Batch Normalization
为了解决上面的Internal Covariate Shift 问题,在2015年,一种被称为Batch Normalization的技术被提出。它的核心思想就是基于每个训练batch去计算每个维度特征的均值和标准差,从而对batch内的每个维度的数据做标准化。使得每个hidden layer的输出的分布被拉回标准正态分布。但是在真实情况下,我们又可能不希望输出的分布都是均值为0,方差为1的分布,比如针对一些特定的激活函数,非标准正态分布的输入效果更好。因此我们在完成上述的标准化后又会添加两个可学习参数gamma & beta 来对归一化后的数据进行分布的线形变换(缩放 + 平移),具体如何变换依赖网络的学习。
在使用Batch Normalization的时候,需要注意的一点是我们需要尽可能调大Batch Size 保证均值和方差的值具有足够的统计学意义,能够尽可能逼近完整训练集的均值和方差。
总的来说,Batch Normalization能够显著提高神经网络的训练稳定性,加速收敛,减轻对网络初始权重的依赖,并能够带来一定的正则化效果,替代dropout等技术。同时当我们使用sigmoid等激活函数的时候,Batch Normalization 还能够有效防止梯度消失的产生。
但是不可否认的是,Batch Normalization 仍存在一些比较明显的问题,首先就是对Batch size有比较高的要求,不能设置太小,不然会导致计算的均值和方差十分不稳定。而这也就意味着对于某些小批次的在线学习,Batch Normalization 无法适用。其次为了在inference阶段应用于单条样本的预测,在实际使用中,我们需要存储训练过程中的所有的均值方差的统计量用于inference阶段,这对内存的消耗十分巨大。还有就是Batch Normalization 无法应用于诸如RNN这样的网络结构。
技术二:Layer Normalization
上面说到的Batch Normalization 是基于batch进行归一化,换句话说,这是一种强batch依赖的技术,因此当batch数量少或者batch内样本的存在差异的时候,Batch Normalization的使用就会受到限制。RNN就是一个很好的例子。RNN可以看作是一个隐藏层共享参数的MLP,随着时间节点的增加,MLP的层数也在增加,最终的层数由输入数据的时间节点个数(序列长度)决定,因此这是一种结构动态的网络。如果我们想应用Batch Normalization就需要对每个时间节点都去做均值方差的计算。但是一般batch内每条序列的长度都是不同,当我们去计算靠后位置的时间节点层的均值和方差时,可能只剩下某一条或两条样本,基于这些样本的统计信息不能反映全局分布,因此对于RNN来说,Batch Normalization并不适用。
为了摆脱对batch大小的依赖,一种被称为Layer Normalization的技术在2016年被提出。相比于Batch Normalization 在 batch维度上做归一化,Layer Normalization直接选择在不同维度的特征上做归一化。对于MLP,可以直接理解为对某一层的多维输出做归一化操作。而对于RNN来说,我们同样可以应用在每个时间节点上。考虑在时间节点t, RNN的输入,一个是t-1时刻的隐藏层输出h(t-1), 另一个是t时刻的输入xt 那么对于H维的输出at, layer normalization的过程如下
Batch Normalization vs Layer Normalization
总的来说,Batch Normalization 和 Layer Normalization 都是非常有效的归一化手段,不同的是,BN取的是不同样本的同一维特征进行归一化,而LN取的是同一个样本的不同维特征进行归一化。在两者均适用的场景下,一般优先选择BN, 原因是LN 对不同维度的特征进行归一化会损失比较多的信息(scale包含的信息),导致网络的表达能力下降,而BN针对同一维度的特征进行压缩就不会有太大的问题。
写在最后
除了上面提到的Batch Normalization 以及 Layer Normalization, 目前还有许多主流的归一化技术,包括Instance Normalization (另一种尝试减少对batch依赖的归一化手段), Group Normalization(主要针对分布式学习) 以及对权重进行标准化的Weight Standardization技术等等,在这篇文章中就不一一展开了。总而言之,归一化看似是神经网络学习的一个小trick, 但实际上则是一个大杀器,对网络的学习起到至关重要的作用。
Reference:
深度学习中的归一化技术全面总结 Batch Normalization by 李宏毅 模型优化之Layer Normalization
|