Batch Normalization
批量归一化:
1、 为什么要进行特征缩放(Feature Scaling)?
当输入数据在不同维度上的数值差异较大时,在前向传播时就会存在同样权重大小的变化在不同维度上的影响不同。如下左图所示,在w1的方向上,损失随w1的变化较慢,而在w2的方向上,损失随w2的变化较快。这样就会存在一个问题:模型在训练的过程中参数更新会呈现出“振荡剧烈”的特点,这对于快速地训练出模型是不利的,此时损失对权重的等高线会是“椭圆型”。而当输入在不同维度上具有相似的分布特征,那么损失对于不同维度的权重变化会表现地比较一致,训练的速度就会加快,直观地表示如下面右图。
2、 如何进行特征缩放?
在输入数据地每一个维度上分别进行缩放,具体的数学处理方式为:求出这些数据的均值和标准差,然后将这个维度上的每一个数据减去均值后再除以标准差,这样就可以将输入数据的每一个维度都缩放到均值为0,标准差为1的分布状态。
3、 什么是Internal Covariate Shift?
在模型训练的过程中,由于每一层的参数都在改变,所以每一层的输入的分布特征也是在改变的,这会降低模型训练的速度,我们将这种每一层输入不断改变的现象叫做Internal Covariate Shift。解决这个问题的方法是对每一层的输入都做归一化处理,这个归一化层通常在全连接层和非线性层之间。事实上,这个方法叫做批量归一化,也就是对于整份输入数据,每次只从其中拿出一部分来训练模型,在这个过程中进行归一化处理,因此叫做批量归一化(Batch Normalization)。
4、 Mini-batch?
模型训练的过程中,我们往往不是一次性将整个训练集的数据输入,而是每次从其中拿出一部分来更新参数。这样做的好处是,由于每次输入的数据量不会太大,参数的更新速度会相对比较快,并且也用到了整个训练集。使用mini-batch相比于每次使用一个数据来更新参数会高效的多。首先,mini-batch是对整个训练集的近似,当batch的数据个数增加时,近似效果会更好;其次,相比于m个数据每次使用一个数据来更新参数,一次性使用m个数据来训练会更加高效。
5、 批量归一化的过程是怎样的?
批量归一化的整个过程可用下面这幅图来表示(摘自李宏毅深度学习ppt),对于每一个维度上的输入,在其与权重矩阵相乘之后,使用激活函数非线性化之前,将其归一化,也就是每一个相乘后的结果减去上层输出的均值μ,再除以上层输出的标准差σ,在下面的这张ppt中表示的就是μ和σ与相关;但是这样会存在一个问题:将这个结果归一化以后,这层网络所代表的东西可能就改变了。例如,对于一个激活函数为sigmoid的全连接层来讲,归一化后的数据都是0均值的,也就是都分布在sigmoid函数的线性区,这其实是对数据的代表能力是有改变的。因此,在批量归一化的方法中引入了参数β和γ,这两个参数被用来缩放和平移归一化后的输入,在网络中,这两个参数是需要被学习的。加入BN层的网络可以看作是将经过归一化的输出作为下面的线性变换层(平移和缩放)的输入,这个线性变换层后面就是激活函数。在反向传播的过程中有一点需要注意,反向传播时必须要经过均值μ和标准差σ,因为μ和σ与相关,当权重改变时,均值和标准差也是改变的。
6、 在测试模型的时候,我们需要计算对于测试集的每一层输出的均值和标准差,理想的方法是对于测试集的所有数据我们都计算一遍,但是这样是不现实的。实际上,在测试的时候,对于每一层输出的均值和标准差我们使用的是在训练过程中这些均值和标准差的滑动平均值。由于在训练的过程中,随着训练次数的增加,均值和标准差是逐渐接近于整个训练集的,因此这样做是合理的。
7、 批量归一化的好处:
①批量归一化使得训练的次数能够减少,这使得训练更深的网络成为可能;
②由于Internal Covariate Shift的减小,在训练网络时可以使用更大的学习率;
③梯度弥散和梯度爆炸会减少,尤其是对于sigmoid激活函数和tanh激活函数;
④训练对参数初始化的依赖更少,比如在一种情况下初始化参数是另一种情况下的k倍,由于归一化的作用,这些权重参数的输出经过归一化后的结果其实是相等的,因为计算表达式的分子分母都会增加k倍;
⑤批量归一化在一定程度上可以减少对正则化的需求;