什么是 "batch normalizaiton"?为什么使用它?它如何影响预测?

What is "batch normalizaiton"? why using it? how does it affect prediction?

最近,许多深度架构使用 "batch normalization" 进行训练。

什么是"batch normalization"?它在数学上有什么作用?它对训练过程有什么帮助?

在训练过程中如何使用批量归一化?它是插入模型中的特殊层吗?我需要在每一层之前归一化,还是只需要归一化一次?

假设我使用批量归一化进行训练。这会影响我的测试时间模型吗?我应该在我的 "deploy" 网络中用一些 other/equivalent layer/operation 替换批归一化吗?


关于batch normalization只涵盖了这个问题的一部分,我的目标是希望得到更详细的答案。更具体地说,我想知道批量归一化训练如何影响测试时间预测,即 "deploy" 网络和网络的 TEST 阶段。

批量归一化适用于可能遭受有害漂移的层。数学很简单:找到每个分量的均值和方差,然后应用标准变换将所有值转换为相应的 Z 分数:减去均值并除以标准差。这确保了组件范围非常相似,因此它们每个都有机会影响训练增量(在反向传播中)。

如果您使用网络进行纯测试(没有进一步的训练),那么只需删除这些层;他们完成了他们的工作。如果您在测试/预测/分类时进行训练,请将它们留在原地;这些操作根本不会损害您的结果,并且几乎不会减慢前向计算的速度。

至于 Caffe 的细节,Caffe 确实没有什么特别之处。计算是一个基本的统计过程,对于任何框架来说都是相同的代数。当然,将对支持向量和矩阵数学的硬件进行一些优化,但这些只是简单地利用芯片的内置运算。


对评论的回应

如果你能负担得起一点额外的训练时间,是的,你会想要在每一层进行归一化。在实践中,不太频繁地插入它们——比如,每 1-3 个开始——就可以了。

您可以在部署中忽略这些,因为它们已经完成了它们的工作:没有反向传播时,就没有权重漂移。此外,当模型在每个批次中只处理一个实例时,Z 分数始终为 0:每个输入都恰好是批次的平均值(即整个批次)。

作为对的补充,在测试期间,批量归一化层将使用来自不同训练迭代的平均mean/variance/scale/shift值来归一化其输入(减去均值并除以标准差)。

而原文google's batch normalization paper只说应该是移动平均法,并没有给出更详尽的解释。 caffe和tensorflow都采用了指数移动平均法

根据我的经验,simple moving average method usually better than an exponential moving average method, as far as to the validation accuracy(Maybe it need more experiments). For a compare, you can refer to here(I tried the two moving average methods implementations in channel_wise_bn_layer, compared with the batch norm layer in BVLC/caffe)。

物有所值 this link 有一个在 cifar10 分类网中使用 "BatchNorm" 层的示例。

具体来说,它将层拆分为 TRAINTEST 阶段:

layer {
  name: "bn1"
  type: "BatchNorm"
  bottom: "pool1"
  top: "bn1"
  batch_norm_param {
    use_global_stats: false
  }
  param {
    lr_mult: 0
  }
  param {
    lr_mult: 0
  }
  param {
    lr_mult: 0
  }
  include {
    phase: TRAIN
  }
}
layer {
  name: "bn1"
  type: "BatchNorm"
  bottom: "pool1"
  top: "bn1"
  batch_norm_param {
    use_global_stats: true
  }
  param {
    lr_mult: 0
  }
  param {
    lr_mult: 0
  }
  param {
    lr_mult: 0
  }
  include {
    phase: TEST
  }
}

批量归一化解决了一个称为“内部协变量偏移”的问题。 要了解它为何有帮助,您首先需要了解协变量偏移实际上是什么。

“Covariates”只是输入“features”的别称,常写为X。Covariate shift是指training/test数据的不同部分的特征分布不同,打破了i.i.d 大多数 ML 使用的假设。这个问题经常出现在医疗数据(你有来自一个年龄组的训练样本,但你想对来自另一个年龄组的东西进行分类)或金融(由于不断变化的市场条件)。

“内部协变量偏移”是指在神经网络内发生的协变量偏移,即从(比如说)第 2 层到第 3 层。发生这种情况是因为,随着网络学习和权重更新,输出的分布网络中特定层的变化。这会迫使更高层适应这种漂移,从而减慢学习速度。

BN 通过使网络中间层之间流动的数据看起来像白化数据来提供帮助,这意味着您可以使用更高的学习率。由于 BN 具有正则化效果,这也意味着您可以经常移除 dropout(这很有用,因为 dropout 通常会减慢训练速度)。