BatchNormalize(批量归一化)
BatchNormalize可以保证深度神经网络训练过程中使得每一层神经网络的输入保持相同的分布。我们一起来看看这个2015年就提出来的 这一思想的原理和意义。
一、BatchNormalize的引入
BatchNormalize一文在机器学习领域带来了很大的影响。数据的预处理是训练数据很重要的一个 环节,博主准备抽空写一篇关数据预处理的文章。我们来分析通过减均值、白化达到加快训练的一个例子,首先,图像数据是高度相关 的,假设其分布如下图a所示(简化为2维)。由于初始化的时候,我们的参数一般都是0均值的,因此开始的拟合y=Wx+b,基本过原点附近, 如图b红色虚线。因此,网络需要经过多次学习才能逐步达到如紫色实线的拟合,即收敛的比较慢。如果我们对输入数据先作减均值操作, 如图c,显然可以加快学习。更进一步的,我们对数据再进行去相关操作,使得数据更加容易区分,这样又会加快训练,如图d。
白化的方式有好几种,常用的有PCA白化:即对数据进行PCA操作之后,在进行方差归一化。这样数据基本满足0均值、单位方差、弱相关性。 文章作者首先考虑,对每一层数据都使用白化操作,但分析认为这是不可取的。因为白化需要计算协方差矩阵、求逆等操作,计算量很大, 此外,反向传播时,白化操作不一定可导。于是,便引出了Batch Normalization方法。
二、BatchNormalize的解析
在每一层的激活函数之后,例如ReLU=max(Wx+b,0)之后,应当对数据进行归一化。然而,文章中说这样做在训练初期,分界面还在剧烈变化时, 计算出的参数不稳定,所以退而求其次,在Wx+b之后进行归一化。因为初始的W是从标准高斯分布中采样得到的,而W中元素的数量远大于x, Wx+b每维的均值本身就接近0、方差接近1,所以在Wx+b后使用Batch Normalization能得到更稳定的结果。
文中使用了类似z-score的归一化方式:每一维度减去自身均值,再除以自身标准差,由于使用的是随机梯度下降法,这些均值和方差也只 能在当前迭代的batch中计算,故作者给这个算法命名为Batch Normalization。这里有一点需要注意,像卷积层这样具有权值共享的层, Wx+b的均值和方差是对整张map求得的,在batch_size * channel * height * width这么大的一层中,对总共batch_sizeheightwidth 个像素点统计得到一个均值和一个标准差,共得到channel组参数。
在Normalization完成后,Google的研究员仍对数值稳定性不放心,又加入了两个参数gamma和beta,使得
注意到,如果我们令gamma等于之前求得的标准差,beta等于之前求得的均值,则这个变换就又将数据还原回去了。在他们的模型中,这两 个参数与每层的W和b一样,是需要迭代求解的。文章中举了个例子,在sigmoid激活函数的中间部分,函数近似于一个线性函数(如下图所 示),使用BN后会使归一化后的数据仅使用这一段线性的部分。
可以看到,在[0.2, 0.8]范围内,sigmoid函数基本呈线性递增,甚至在[0.1, 0.9]范围内,sigmoid函数都是类似于线性函数的,如果 只用这一段,那网络不就成了线性网络了么,这显然不是大家愿意见到的。至于这两个参数对ReLU起的作用文中没说。
算法原理到这差不多就讲完了,对于公式,求均值和方差就不用说了,在BP的时候,我们需要求最终的损失函数,对gamma和beta两个参数 的导数,还要求损失函数对Wx+b中的x的导数,以便使误差继续向后传播。求导公式如下:
具体的公式推导就不写了,有兴趣的读者可以自己推一下,主要用到了链式法则。
在训练的最后一个epoch时,要对这一epoch所有的训练样本的均值和标准差进行统计,这样在一张测试图片进来时,使用训练样本中 的标准差的期望和均值的期望对测试数据进行归一化,注意这里标准差使用的期望是其无偏估计:
论文中将Batch Normalization的作用夸的有些离谱,我们一起看看:
- 可以使用更高的学习率。如果每层的scale不一致,实际上每层需要的学习率是不一样的,同一层不同维度的scale往往也需要不同大小 的学习率,通常需要使用最小的那个学习率才能保证损失函数有效下降,Batch Normalization将每层、每维的scale保持一致,那么我们 就可以直接使用较高的学习率进行优化。
- 移除或使用较低的dropout。 dropout是常用的防止overfitting的方法,而导致overfit的位置往往在数据边界处,如果初始化权重就 已经落在数据内部,overfit现象就可以得到一定的缓解。论文中最后的模型分别使用10%、5%和0%的dropout训练模型,与之前的40%-50% 相比,可以大大提高训练速度。
- 降低L2权重衰减系数。 还是一样的问题,边界处的局部最优往往有几维的权重(斜率)较大,使用L2衰减可以缓解这一问题,现在用 了Batch Normalization,就可以把这个值降低了,论文中降低为原来的5倍。
- 取消Local Response Normalization层。 由于使用了一种Normalization,再使用LRN就显得没那么必要了。而且LRN实际上也没那么work。
- 减少图像扭曲的使用。 由于现在训练epoch数降低,所以要对输入数据少做一些扭曲,让神经网络多看看真实的数据。
三、实验
这一部分我就不细说了,因为我在CNN那篇文章中已经说过了使用方法,请移步到这里
谢谢观看,希望对您有所帮助,欢迎指正错误,欢迎一起讨论!!!