1. 在讲BN之前我要向大家提出几个问题,就是为什么要引入BN呢?在神经网络训练的时候输入图片不是引入了image normalization吗?所以BN到底是什么呢?
- Batch Normalization是由google提出的一种训练优化方法。
- 原论文地址:https://arxiv.org/abs/1502.03167
2.引入BN的原因?
我们在图像预处理过程中通常会对图像进行标准化处理,也就是image normalization,使得每张输入图片的数据分布能够统均值为u,方差为h的分布。这样能够加速网络的收敛。但是当一张图片输入到神经网络经过卷积计算之后,这个分布就不会满足刚才经过image normalization操作之后的分布了,可能适应了新的数据分布规律,这个时候将数据接入激活函数中,很可能一些新的数据会落入激活函数的饱和区,导致神经网络训练的梯度消失,如下图所示当feature map的数据为10的时候,就会落入饱和区,影响网络的训练效果。这个时候我们引入Batch Normalization的目的就是使我们卷积以后的feature map满足均值为0,方差为1的分布规律。在接入激活函数就不会发生这样的情况。
3.BN如何做?
下图展示了一个batch size为2(两张图片,每张图片有3个通道,其中颜色红,绿,蓝分别代表r,g,b通道。)的Batch Normalization的原理,首先会统计每个通道数目所有点的像素值,求得均值和方差,然后在每个通道上分别用该点的像素值减均值除方差得到该点的像素值,此过程就是BN。最后将其接入到激活函数中。
下面这张图是我从原论文截取的BN算法流程:
这里我将用一个详细的例子来解析BN是如何计算得到的,我以batch-size为2来说明情况,如下图所以,其中红,绿,蓝分别代表图像不同的通道,假设假设feature map1、feature map2分别是由image1、image2经过一系列卷积池化后得到的特征矩阵。其中每个网格的值代表该点的像素值,分别统计feature map1 和feature map2每个通道的像素值,得到一个矩阵,在使用BN的计算公式计算经过BN以后每个通道每个像素点的像素值。计算公式也如下。
3. 使用BN时需要注意的问题
(1)训练时要将traning参数设置为True,在验证时将trainning参数设置为False。在pytorch中可通过创建 模型的model.train()和model.eval()方法控制。
(2)batch size尽可能设置大点,设置小后表现可能很糟糕,设置的越大求的均值和方差越接近整个训练集的均值和方差。
(3)一般将bn层放在卷积层(Conv)和激活层(例如Relu)之间,且卷积层不要使用偏置bias。
下面我来用公式证明为什么不要使用篇置:
所以使用偏置只会徒增网络的参数,导致训练起来更加的费劲。