机器学习面试题之——BatchNorm

一、背景知识

1、机器学习领域有个重要假设:IID独立同分布假设,就是假设训练数据和测试数据是满足相同分布的,这是通过训练数据获得的模型能够在测试集获得好的效果的一个基本保障。而BatchNorm就是在深度神经网络训练过程中使得每一层神经网络的输入保持相同分布。

2、Covariate Shift 指训练数据和测试数据存在分布的差异性。这会给网络的泛化性和训练速度带来了影响,我们经常使用的方法是做归一化或者白化。(白化:就是对输入数据分布变换到0均值,单位方差的正态分布)

3、Internal Covariate Shift 指网络训练过程中,每个隐层的输入分布存在差异性。此术语是google小组在论文Batch Normalizatoin中提出来的,其主要描述的是:训练深度网络的时候经常发生训练困难的问题,因为,每一次参数迭代更新后,上一层网络的输出数据经过这一层网络计算后,数据的分布会发生变化,为下一层网络的学习带来困难(神经网络本来就是要学习数据的分布,要是分布一直在变,学习就很难了)。

针对Internal Covariate Shift ,若直接对神经网络的每一层做归一化,会导致学习不到任何东西。因为假设将每一层输出后的数据都归一化到0均值,1方差,满足正太分布,但是,此时有一个问题,每一层的数据分布都是标准正太分布,导致其完全学习不到输入数据的特征,因为,费劲心思学习到的特征分布被归一化了。 

二、BatchNorm伪代码

之所以称之为batchnorm是因为所norm的数据是一个batch的,步骤如下:

1.先求出此次batch的均值;
2.求出此次batch的方差;
3.接下来对x_{i}做归一化
4.最重要的一步,引入缩放和平移变量\gamma和β,计算归一化后的值y_{i}

三、内部原理

1、首先要了解训练层网络收敛越来越慢的原因:深层神经网络在做非线性变换前的激活输入值(就是那个x=WU+B,U是输入)随着网络深度加深或者在训练过程中,其分布逐渐发生偏移或者变动,之所以训练收敛慢,一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近(对于Sigmoid函数来说,意味着激活输入值WU+B是大的负值或正值),所以这导致后向传播时低层神经网络的梯度消失。

2、而BatchNorm通过规范化手段,对于每个隐层神经元,把逐渐向非线性函数映射后向取值区间极限饱和区靠拢的输入分布强制拉回到均值为0方差为1的比较标准的正态分布,使得非线性变换函数的输入值落入对输入比较敏感的区域,以此避免梯度消失问题。因为梯度一直都能保持比较大的状态,所以很明显对神经网络的参数调整效率比较高,就是变动大,就是说向损失函数最优值迈动的步子大,也就是说收敛地快。

3、伪代码中第4步的重要性(即引入平移参数和缩放参数的必要性):若没有第四步,就跟把非线性函数替换成线性函数效果相同。所以BN为了保证非线性的获得,对变换后的满足均值为0方差为1的x又进行了scale加上shift操作(y=scale*x+shift),每个神经元增加了两个参数scale和shift参数,这两个参数是通过训练学习到的,意思是通过scale和shift把这个值从标准正态分布左移或者由移一点并长胖一点或者变瘦一点,每个实例挪动的程度不一样,这样等价于非线性函数的值从正中心周围的线性区往非线性区动了动。核心思想应该是想找到一个线性和非线性的较好平衡点,既能享受非线性的较强表达能力的好处,又避免太靠非线性区两头使得网络收敛速度太慢。

四、BatchNorm好处

  • 调参过程变简单,对于初始化要求没那么高,而且可以使用大的学习率
  • Batchnorm本身上也是一种正则的方式,可以代替其他正则方式如dropout等
  • 降低了数据之间的绝对差异,有一个去相关的性质,更多的考虑相对差异性,因此在分类任务上具有更好的效果。

参考文献:

1、https://blog.csdn.net/qq_25737169/article/details/79048516(提供了代码实现)

2、https://blog.csdn.net/malefactor/article/details/51476961(解释的比较详细,但太多了)

猜你喜欢

转载自blog.csdn.net/cuiy0818/article/details/81261407