点击上方“AI公园”,关注公众号
作者:Harrison Jansma
编译:ronghuaiyang
在本文中,我会回顾一下batch normalization的用处。我也会在Keras中实现一下batch normalization,并在训练中得到了实际的提升。代码可以在https://github.com/harrisonjansma/Research-Computer-Vision/tree/master/07-28-18-Implementing-Batch-Norm找到。
Batch Normalization的一个直觉的解释
训练中的问题
问题1:当网络在训练时,前一层的权值会变换,导致后面的层的输入也会变化的比较厉害。每一层都必须调整权值来适应每个batch的输入的分布。这会使得模型的训练变慢。如果我们可以让每一层的输入的分布变得相似,那么整个网络就会把精力集中在训练不同的类别上,而不是适应不同的分布上。
另外一个batch之间不同的分布的影响是梯度的消失。梯度消失问题是一个大问题,特别是对于sigmoid的激活函数。如果g(x)表示sigmoid激活函数,当|x| 增加,g′(x) 趋向于0。
问题1,当输入的分布变化时,神经网络的输出也在变化。这就导致了神经网络的输出偶尔会进入到sigmoid函数的饱和区域。一旦到了饱和区域,神经元就无法更新权值了,没有梯度回传到前面的层去。那么,我们如何防止神经元的输出变化到饱和区域呢?
如果我们可以限制神经元的输出在0的附近,我们可以确保每一层都可以通过反向传播回传比较大的梯度。这会使得训练速度加快,得到更加准确的结果。
Batch Norm解决方案
Batch normalization减轻了输入的变化的影响。通过对神经元的输出进行归一化,激活函数的输入都是在0附近的,这就保证了没有梯度的消失,解决了第二个问题。
Batch normalization将每一层的输出变换成一个单位的高斯分布。由于这些输出被输入到一个激活函数中,激活后的值也是一个正态的分布。
因为一层的输出是下一层的输入,每一层的输入的分布对于不同的batch来说就不会有太大的变化。通过减小输入层的分布的变化,我们解决了第一个问题。
数学解释
通过batch normalization,我们寻找一个以0为中心的,单位方差的分布作为每一层的激活函数的输入。在训练的时候,我们用激活的输入x减去这个batch中的均值μ来得到以0为中心的分布。
然后,我们用x除以这个batch的方差,这里需要一个很小的数来防止除0操作, 也就是σ+ϵ。这样确保了所有的激活函数的输入分布具有单位方差。
最后,我们将x通过一个线性变换,通过一个缩放和偏移,得到了 batch normalization的输出。确保这个归一化的作用会保持住,尽管网络在反向传播的时候会有变化。
当测试模型的时候,我们并不使用batch的均值和方差,因为这可能影响模型。而是计算均值和方差的移动平均来估计训练集的分布。这样的估计是在训练的过程中对所有的batch的均值和方差进行计算得到的。
Batch Normalization的好处
batch normalization的好处如下:
1. 帮助防止网络中的梯度消失线性,特别是使用饱和的非线性激活函数的时候(如sigmoid,tanh)
使用batch normalization,我们确保激活函数的输入不会落入到饱和区域。batch normalization将输入的分布变换到单位高斯分布(0均值,单位方差)。
2. 模型正则化
也许有,Ioffe和Svegeddy声称有这个作用,但是并没有在这个问题上展开说。也许这个效果来自于层的输入的归一化?
3. 允许更高的学习率
通过防止训练时候梯度消失的问题,我们可以使用更高的学习率。Batch normalization同样减少了对于参数尺度的依赖。大的学习了可以增加参数的尺度,从而在反向传播的时候造成梯度的放大,对于这,我需要更多了解一下。
Keras的实现
导入包
数据加载和预处理
在这里,我们使用了 Cifar 100的数据集,难度合理,不会训练很长时间。预处理只做了0均值的处理,以及一个图像的变换的生成器。
在Keras中构建模型
我们的网络结构由 3x3 的卷积层堆叠而成,卷积后面接最大化池化和dropout。每个网络中有5个卷积block。最后一层是全连接层,有100个节点,使用softmax作为激活函数。
我们构建了4个不同的卷积神经网络,每个或者使用sigmoid或者使用ReLU激活函数,或者使用了 batch normalization,或者没有。我们会对比每个网络的有效的loss。
Model训练
Sigmoid不使用Batch Normalization
训练卡住了,使用100个类,模型并不比随机猜好(10%的准确率)。
Sigmoid使用Batch Normalization
和不用 batch normalization不一样,模型总算是有点起色了,这应该是 batch normalization的减轻了梯度消失的作用。
ReLU不使用Batch Normalization
使用ReLU,不使用 batch normalization,有一点初始的提升,收敛到了一个局部最小中。
ReLU使用Batch Normalization
和sigmoid一样, batch normalization在训练中提高了网络的能力。
不同结构的对比
我们可以清楚的看到 batch normalization的好处。ReLU 和sigmoid 的模型在没有batch normalization的时候,都没有训练的很好。可能是梯度消失的原因。使用了batch normalization的模型训练的更快,而且效果更好。
结论
batch normalization减少了训练的时间,提高了神经网络的稳定性。对于sigmoid和ReLU都有效果。
英文原文链接:https://towardsdatascience.com/intuit-and-implement-batch-normalization-c05480333c5b
本文可以任意转载,转载时请注明作者及原文地址。
请长按或扫描二维码关注我们