批处理化
批处理化
批处理化作为及其重要的优化技术,在此给出详细的笔记记录。
Batch Normalization(批处理化)
Batch Normalization作为最近一年来DL的重要成果,已经广泛被证明其有效性和重要性。花书对于BN的介绍较为模糊,是从抽象的数学角度进行解释的,我认为其并没有写出BN的本质好处。因此在查阅论文《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》后,给出一些理解。
机器学习领域有个很重要的假设:iid.独立同分布假设,就是假设训练数据和测试数据是满足相同分布的,这是通过训练数据获得的模型能够在测试集获得好的效果的一个基本保障。那BatchNorm的作用是什么呢?BatchNorm就是在深度神经网络训练过程中使得每一层神经网络的输入保持相同分布的。
为什么深度神经网络随着网络深度加深,训练起来越困难,收敛越来越慢?这是个在DL领域很接近本质的好问题。通常来说,深度越深,其模型的函数表示越复杂,梯度更可能发生消失和爆炸,这回导致在浅层的网络很难学到“知识”,所以开发出例如预训练和迁移学习等技术,同时研究者也在想办法解决梯度消失和梯度爆炸的问题。可以看到很多论文都是解决这个问题的,比如ReLU激活函数,再比如Residual Network,BN本质上也是解释并从某个不同的角度来解决这个问题的。
“Internal Covariate Shift”问题
BN是用来解决“Internal Covariate Shift”问题的,那么首先得理解什么是“Internal Covariate Shift”?
论文首先说明Mini-Batch SGD相对于One Example SGD的两个优势:梯度更新方向更准确;并行计算速度快;但是SGD训练也有缺点:超参数调起来很麻烦。(用BN就能解决很多SGD的缺点)
接着引入covariate shift的概念:如果ML系统实例集合<X,Y>中的输入值X的分布老是变,这不符合IID假设,网络模型很难稳定的学规律。对于深度学习这种包含很多隐层的网络结构,在训练过程中,因为各层参数不停在变化,所以每个隐层都会面临covariate shift的问题,也就是在训练过程中,隐层的输入分布老是变来变去,这就是所谓的“Internal Covariate Shift”,Internal指的是深层网络的隐层,是发生在网络内部的事情,而不是covariate shift问题只发生在输入层。然后提出了BatchNorm的基本思想:能不能让每个隐层节点的激活输入分布固定下来呢?这样就避免了“Internal Covariate Shift”问题了。
BN不是凭空出现的,它是有启发来源的:之前的研究表明如果在图像处理中对输入图像进行白化(Whiten)操作的话——所谓白化,就是对输入数据分布变换到0均值,单位方差的正态分布——那么神经网络会较快收敛,那么BN作者就开始推论了:图像是深度神经网络的输入层,做白化能加快收敛,那么其实对于深度网络来说,其中某个隐层的神经元是下一层的输入,意思是其实深度神经网络的每一个隐层都是输入层,不过是相对下一层来说而已,那么能不能对每个隐层都做白化呢?这就是启发BN产生的原初想法,而BN也确实就是这么做的,可以理解为对深层神经网络每个隐层神经元的激活值做简化版本的白化操作。(如果说人话,就是BN把网络近似解耦了,每一层都可以看作一个一层的神经网络,输入是同分布的,那么这时候训练不就非常快了吗,网络又浅,分布还是一样的,开心坏了!当然BN的真正优势并不是如此简单,其导致训练的加快是由于其将梯度拉到了大梯度范围内)
BatchNorm的基本思想
BN的基本思想其实相当直观:因为深层神经网络在做非线性变换前的激活输入值(就是那个\(x=WU+B\),\(U\)是输入)随着网络深度加深或者在训练过程中,其分布逐渐发生偏移或者变动,之所以训练收敛慢,一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近(对于Sigmoid函数来说,意味着激活输入值\(WU+B\)是大的负值或正值),所以这导致反向传播时低层神经网络的梯度消失,这是训练深层神经网络收敛越来越慢的本质原因,而BN就是通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0方差为1的标准正态分布,其实就是把越来越偏的分布强制拉回比较标准的分布,这样使得激活输入值落在非线性函数对输入比较敏感的区域,这样输入的小变化就会导致损失函数较大的变化,意思是这样让梯度变大,避免梯度消失问题产生,而且梯度变大意味着学习收敛速度快,能大大加快训练速度。
一句话就是:对于每个隐层神经元,把逐渐向非线性函数映射后向取值区间极限饱和区靠拢的输入分布强制拉回到均值为0方差为1的比较标准的正态分布,使得非线性变换函数的输入值落入对输入比较敏感的区域,以此避免梯度消失问题。因为梯度一直都能保持比较大的状态,所以很明显对神经网络的参数调整效率比较高,就是变动大,就是说向损失函数最优值迈动的步子大,也就是说收敛地快。BN说到底就是这么个机制,方法很简单,道理很深刻。经过BN后,目前大部分Activation的值落入非线性函数的线性区内,其对应的导数远离导数饱和区,这样来加速训练收敛过程。
但是每一层都进行标准化是否会使得网络的表达能力变弱呢?BN为了保证网络的表达能力,对变换后的满足均值为0方差为1的x又进行了scale加上shift操作\((y=scale*x+shift)\),每个神经元增加了两个参数scale和shift参数,这两个参数是通过训练学习到的,意思是通过scale和shift把这个值从标准正态分布左移或者右移一点并长胖一点或者变瘦一点,每个实例挪动的程度不一样,这样等价于非线性函数的值从正中心周围的线性区往非线性区动了动。核心思想应该是想找到一个线性和非线性的较好平衡点,既能享受非线性的较强表达能力的好处,又避免太靠非线性区两头使得网络收敛速度太慢。当然,这是我的理解。
BN的具体操作流程,由下图所示:

实际效果上,原作者比较了对于Inception模型利用batch normalization的效果,可看出它能以更少的训练步数达到更高的准确度,是非常有效的方法。

小结
BatchNorm效果非常好,①极大提升了训练速度,收敛过程大大加快;②增加分类效果,一种解释是这是类似于Dropout的一种防止过拟合的正则化表达方式,所以不用Dropout也能达到相当的效果;③调参过程也简单多了,对于初始化要求没那么高,而且可以使用大的学习率等。

浙公网安备 33010602011771号