Batch Normalization测试时is_training为什么要设为False

前言

BN(Batch Normalization)在如今的神经网络中应用广泛,涵盖图像分类、语义分割和目标检测等各个领域,对于防止过拟合起到了巨大的作用。在TensorFlow中,使用BN时通常要设置一个参数——is_training,作为模型处在训练模式或者测试模式的标志。倘若这个参数使用不得当,就会出现推理时精度异常,会出现如下情况:
①batch_size = 1时,无论输入数据是否打乱,推理精度都是极低;
②batch_size 较大时,且输入数据没有打乱时,精度极低;
③当batch_size较大时,且输入数据随机打乱时,精度略高,但会出现重复性误差,即同一批数据,两次推理结果可能不同。
这些情况是常见的BN参数设置错误问题,当读者看完下面对BN的解读,就可以知道出现这些情况的原因,从而更加有效地去运用BN。

BN训练及推理

在BN论文中,算法的计算过程如下所示: μ B \mu_{\mathcal{B}} μB σ B 2 \sigma_{\mathcal{B}}^{2} σB2 γ \gamma γ β \beta β y i y_{i} yi分别为神经网络中当前层所有节点在batch这个维度的均值、方差、尺度、偏置和输出,m为batch大小。 μ B \mu_{\mathcal{B}} μB σ B 2 \sigma_{\mathcal{B}}^{2} σB2为当前Batch的统计值, γ \gamma γ β \beta β为可训练的参数,初始值为1和0。
在这里插入图片描述
举两个例子:
①在一个一维的BP神经网络中,某一层的维度为[10,2000],那么这层的 μ B \mu_{\mathcal{B}} μB σ B 2 \sigma_{\mathcal{B}}^{2} σB2 γ \gamma γ β \beta β y i y_{i} yi的维度分别为[1,2000]、[1,2000]、[1,2000]、[1,2000]和[10,2000]。
②在二维的卷积神经网络中,对于其中的某一层,可以认为一个通道为一个节点,其对应的均值、方差都为2维(point-wise),而尺度和偏置都为一维(channel-wise)。对于输入维度为[10,300,300,100]的这样一个输入,这层的 μ B \mu_{\mathcal{B}} μB σ B 2 \sigma_{\mathcal{B}}^{2} σB2 γ \gamma γ β \beta β y i y_{i} yi的维度分别为[1,300,300,100]、[1,300,300,100]、[1,100]、[1,100]和[10,300,300,100]。

代码如下:

mean = np.mean(x, axis=0)
var = np.var(x, axis=0)
out_ = (x - mean) / np.sqrt(var + eps)
out = gamma * out_ + beta

这便是训练时输出的由来。但是我们知道,在推理时,batch的大小可能是1,这时候如果还是用这样的方式来计算均值和方差显然不make sense。

那么应该怎么做?论文中的做法见下图: γ \gamma γ β \beta β使用训练得到的参数,而 μ B \mu_{\mathcal{B}} μB σ B 2 \sigma_{\mathcal{B}}^{2} σB2则是对所有batch计算出来的 μ B \mu_{\mathcal{B}} μB σ B 2 \sigma_{\mathcal{B}}^{2} σB2 做无偏估计的值,也就是TensorFlow中的moving_mean和moving_variance,然后代入上面的公式进行计算。
在这里插入图片描述
但是这种做法有一个极大的弊端:需要耗费大量的内存空间用于存储每一个batch中每一层的 μ B \mu_{\mathcal{B}} μB σ B 2 \sigma_{\mathcal{B}}^{2} σB2。所以一般采用如下公式进行计算:
r μ B i = β r μ B i − 1 + ( 1 − β ) μ B r \mu_{B i}=\beta r \mu_{B i-1}+(1-\beta) \mu_{B} rμBi=βrμBi1+(1β)μB
r σ B i 2 = β r σ B i − 1 2 + ( 1 − β ) σ B 2 r \sigma_{B i}^{2}=\beta r \sigma_{B i-1}^{2}+(1-\beta) \sigma_{B}^{2} rσBi2=βrσBi12+(1β)σB2

r μ B i r \mu_{B i} rμBi是迭代了 i i i次的moving_mean, r σ B i 2 r \sigma_{B i}^{2} rσBi2则是迭代了 i i i次moving_variance。β是人为设置的参数。

预测异常的原因

①:batch_size = 1时,无论输入数据是否打乱,推理精度都是极低;
解释:batch_size=1时,仅仅对一个样本进行推理时,此时的 μ B \mu_{\mathcal{B}} μB为样本本身, σ B 2 \sigma_{\mathcal{B}}^{2} σB2为0,此时的 x ^ \widehat{x} x 为异常值,自然推理出现问题。
②:batch_size 较大时,且输入数据没有打乱时,精度极低;
解释:当数据没有打乱时,通常在一个batch中所有样本为同类,这样计算出的 μ B \mu_{\mathcal{B}} μB σ B 2 \sigma_{\mathcal{B}}^{2} σB2与moving_mean和moving_variance有较大的差距,使得推理出错。
③当batch_size较大时,且输入数据随机打乱时,精度略高,但会出现重复性误差,即同一批数据,两次推理结果可能不同。
解释:当输入数据打乱时,在一个batch中所有样本类别不完全相同,使得计算出来 μ B \mu_{\mathcal{B}} μB σ B 2 \sigma_{\mathcal{B}}^{2} σB2可能接近moving_mean和moving_variance,最终推理结果精度略高;由于在导入模型参数时重新随机打乱数据,同一个样本在推理时使用的 μ B \mu_{\mathcal{B}} μB σ B 2 \sigma_{\mathcal{B}}^{2} σB2不同,自然结果也就不同。

总结

①对于BN,训练时对样本分布敏感,应在训练前把训练样本打乱。
②TensorFlow中,在训练时应当设置is_training为True,而测试时应当设为False;PyTorch也要注意使用net.train()或者net.test()切换模型。

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值