Batch Normalization标准化

2015年提出的《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》优化方法,训练速度大大加快

问题:

由于神经网络包含很多隐层的网络结构,在训练过程中,各层参数不断的变化,导致输入激活函数前数据的分布总是变来变去。即Internal Covariate Shift。在神经元进行非线性变换前的激活输入值x(x=wu+b),随着网络深度的增加或者在训练过程中,其分布发生偏移或者变动,使整体分布向非线性函数的取值区间上下限俩端靠近(比如sigmod函数的正无穷和负无穷方向),从而出现梯度消失现象,训练速度放慢。
然后提出了BatchNorm的基本思想:能不能让每个隐层节点的*激活函数输入
分布固定下来呢(受图像白化操作影响提出的思想)

主要思想:

通过一定手段,将神经网络每层的输入分布强行拉回均值为0方差为1的标准正态分布,使得激活函数的输入值落在非线性函数对输入比较敏感的区域,避免梯度消失现象,使梯度变大,梯度变大,意味着学习收敛速度快,从而大大加快训练速度。
image.png

举例说明下batch normalization就是把上图里的均值为-2的绿色正太分布曲线拉成均值为0的蓝色正态分布曲线

流程方法

没加BN前:

Batch Normalization标准化 - 图2

加了BN:
Batch Normalization标准化 - 图3

对于Mini-Batch SGD来说,一次训练过程里面包含m个训练实例,其具体BN操作就是对于隐层内每个神经元的激活值来说,进行如下变换:

  1. ![](https://cdn.nlark.com/yuque/0/2020/png/559078/1578903559790-a8ed6056-28c4-436e-b59b-892c3f0a79a5.png#align=left&display=inline&height=83&margin=%5Bobject%20Object%5D&originHeight=151&originWidth=372&size=0&status=done&style=none&width=205)<br />经过这个变换后某个神经元的激活x形成了均值为0,方差为1的正态分布,但是一定能保证是均值为0,方差为1的正态分布吗?偏正态不行吗?第二,把数据全部拉到接近0的位置,sigmoid不就接近于一个线性函数了吗,没有起到激活的作用啊(线性激活函数+线性操作等价于一层线性操作)。为了防止这一点,每个神经元增加两个调节参数(scale和shift),这两个参数是通过训练来学习到的,**相当于将这个正态分布左右挪了挪,变胖或者变瘦,在加快收敛速度和保持非线性的之间找到一个平衡用来对变换后的激活反变换**,使得网络表达能力增强,即对变换后的激活进行如下的scale和shift操作,这其实是变换的反操作**:**<br />** ![](https://cdn.nlark.com/yuque/0/2020/png/559078/1578903672526-d401d59b-17aa-4686-857a-577d2efa6a3e.png#align=left&display=inline&height=38&margin=%5Bobject%20Object%5D&originHeight=70&originWidth=376&size=0&status=done&style=none&width=204)<br />就是某个神经元对应的原始的激活x通过减去mini-Batch内m个实例获得的m个激活x求得的均值E(x)并除以求得的方差Var(x)来进行转换。<br />这一步操作核心思想应该是**想找到一个线性和非线性的较好平衡点,既能享受非线性的较强表达能力的好处,又避免太靠非线性区两头使得网络收敛速度太慢。**<br />**<br />论文里的流程:
  2. ![](https://cdn.nlark.com/yuque/0/2020/png/559078/1578903896879-398c808f-491e-4d94-af29-ec34a93d991c.png#align=left&display=inline&height=345&margin=%5Bobject%20Object%5D&originHeight=345&originWidth=479&size=0&status=done&style=none&width=479)<br />**i有uu**

优点:

  1. 不仅仅极大提升了训练速度,收敛过程大大加快
  2. 控制过拟合,可以少用或不用Dropout和正则还能增加分类效果,一种解释是这是类似于Dropout的一种防止过拟合的正则化表达方式,所以不用Dropout也能达到相当的效果
  3. 另外调参过程也简单多了,对于初始化要求没那么高,而且可以使用大的学习率等
  4. 降低网络对初始化权重不敏感

    为什么说BN也会起到一定的正则化作用?

    对于Dropout来讲,给每个隐藏单元一定概率置零的可能,这样就相当于给网络引入了噪声。迫使Dropout后部单元不过分依赖于前面任何一个隐藏单元。
    而BN,因为是在Mini-batch上计算mean、variance,而不是整个数据集上。均值和方差有一些小噪音,在进行缩放过程,γ、β也会引入噪声,这样和dropout类似,它往每个隐藏层的激活值上增加了噪音,所以起到了一定的正则化作用。
    当mini-batch变大时,由于均值方差更加接近真实值,所以噪声会减小,就会减少正则化的效果。

Layer Normalization

上面可知BN存在下面缺点:

  1. 对batch_size非常敏感,受其影响
  2. 不能很方便地用于RNN,rnn输入序列不等长

**为了避免这两个问题,LayerNormalization就应运而生了。

  • 不再对Mini-Batch中的N的样本在各个维度做归一化,而是针对同一层的所有神经元做归一化。归一化公式为:

    1. <br />其中,H指的是一层神经网络的神经元个数。<br />我们再回想下BatchNormalization,其实它是在每个神经元上对batch_size个数据做归一化,每个神经元的均值和方差均不相同。而LayerNormalization则是对**所有神经元**做一个归一化,这就跟batch_size无关了。哪怕batch_size为1,这里的均值和方差只和神经元的个数有关系
  • 测试的时候可以直接利用LN,所以训练时不用保存均值和方差,这节省了内存空间。

下图示意了两种方式的区别。假设有N个样本,每个样本的特征维度为4,图中每个小圆代表一个特征,特征1,特征2等等,特征4。BatchNormalization是在N个同一特征(如特征1)上求均值和方差,这里要对每个特征求1次,共4次。对照一下上面说的,万一有个样本有5个特征,是不是就没法玩了。LayerNormalization呢,别的样本都和我没啥关系,有多少个特征我把这些特征求个均值方差就好了。这也就是为什么一个叫”批归一化“,另一个叫”层归一化“了。理解了这一点,也就理解了为什么Transformer中使用LN而不是BN。
Batch Normalization标准化 - 图4
Batch Normalization标准化 - 图5