【问题标题】:What is "batch normalizaiton"? why using it? how does it affect prediction?什么是“批量标准化”?为什么要使用它?它如何影响预测?
【发布时间】:2017-05-07 06:40:15
【问题描述】:

最近,许多深度架构使用“批量标准化”进行训练。

什么是“批量标准化”?它在数学上做了什么?它对培训过程有何帮助?

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

假设我使用批量标准化进行训练。这会影响我的测试时间模型吗?我应该用我的“部署”网络中的一些其他/等效层/操作替换批量标准化吗?


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

【问题讨论】:

  • batch normalization in neural network 的可能重复项。如果这不能让您得到完整的答案,请告诉我。
  • @Prune 感谢您发现这个问题。但是,它仅部分涵盖了我的问题。我仍然想知道这一层的实际数学运算,我们应该分别对每一层进行标准化吗?我们应该在测试时(即在“部署”甚至在测试阶段)用什么替换这种标准化?
  • @Prune 此外,我希望得到一个更具体的caffe 实现方式的答案。

标签: machine-learning neural-network deep-learning normalization caffe


【解决方案1】:

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

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

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


回应评论

如果您能负担得起一点额外的训练时间,是的,您会希望在每一层都进行标准化。在实践中,不那么频繁地插入它们——比如说,每 1-3 次开始——就可以了。

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

【讨论】:

  • 感谢您的回答!我还有一些问题:(a) 假设我想安全起见,我是否应该在模型的每一层之前都有一个批量标准化层? (b) 为什么我可以简单地将这一层放到我的“部署”模型中?毕竟它确实对数据进行了一些转换,为什么我可以忽略这些转换?
【解决方案2】:

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

原来的google's batch normalization paper只是说应该是移动平均法,但没有提供更详尽的解释。 caffe 和 tensorflow 都使用指数移动平均法。

根据我的经验,就验证准确性而言,simple moving average method 通常比指数移动平均方法更好(也许需要更多实验)。对比可以参考here(我尝试了channel_wise_bn_layer中的两种移动平均法实现,对比BVLC/caffe中的batch norm层)。

【讨论】:

    【解决方案3】:

    对于它的价值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
      }
    }
    

    【讨论】:

    • 为什么所有 lr_mult 参数都设置为零?
    • @thigi。好问题。 "BatchNorm" 层的独特之处在于它通过梯度反向传播更新其内部参数,而是通过滑动窗口统计信息。因此lr_mult必须为零,以防止 caffe 以错误的方式自动更新参数。
    • 除了/在 caffe 中的 batchNorm 层之后,你还应该使用 scale 层吗? @Shai
    • @user3051460 恐怕没有batch_size: 0案例的经验。
    • 参数 lr_mult 现已弃用。 @Shai
    【解决方案4】:

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

    “协变量”只是输入“特征”的另一个名称,通常写为 X。协变量偏移意味着特征在训练/测试数据的不同部分的分布是不同的,打破了大多数情况下使用的 iid 假设毫升。这个问题经常出现在医疗数据(您有来自一个年龄组的训练样本,但您想对来自另一个年龄组的东西进行分类)或金融(由于不断变化的市场条件)。

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

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

    【讨论】:

      猜你喜欢
      • 2015-11-11
      • 1970-01-01
      • 2011-10-31
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      • 2017-01-10
      • 2011-02-21
      相关资源
      最近更新 更多