当前位置: 首页 > 科技观察

深度学习中batchnormalization的陷阱

时间:2023-03-16 21:54:58 科技观察

BatchNormalization技术(BatchNormalization)是最近在深度学习中兴起的一种有效技术。它已被广泛证明是有效的,并将很快用于研究和应用。去。这篇文章假设读者知道什么是批量归一化,并且对它的工作原理有一定的了解。如果您是这个概念的新手,或者需要复习一下,可以在下面的链接(http://blog.csdn.net/malefactor/article/details/51476961)中找到批量归一化的简要概述。本文使用两种不同的方法实现神经网络。在每一步输入相同的数据。这些网络具有完全相同的损失函数、完全相同的超参数和完全相同的优化器。然后在完全相同数量的GPU上进行训练。结果是一个版本的准确性比另一个版本低2%,而且这种性能下降似乎是稳定的。我们以一个简单的MNIST和SVHN分类问题为例。在第一个实现中,一批MNIST数据和一批SVHN数据被采样、合并在一起,然后馈送到网络。在第二个实现中,创建了两个共享权重的网络副本。一个副本提供MNIST数据,另一个副本提供SVHN数据。请注意,在这两种实现中,一半数据是MNIST,另一半是SVHN。另外,由于第二种实现共享权重,所以两个模型的参数个数相同,更新方式也相同。简单想想,这两个模型训练的时候梯度应该是一样的。同样的道理。但是加入batchnormalization之后情况就不一样了。在第一个实现中,MNIST数据和SVHN数据都包含在同一批数据中。而在第二种方法中,模型分两批进行训练,一批仅针对MNIST数据,另一批针对SVHN数据。出现这个问题的原因是在训练过程中,两个网络在共享参数的同时,也共享了数据集的均值和方差的移动平均值。此参数的更新也适用于两组数据集。在第二种方法中,图中上方的网络使用MNIST数据的均值和方差估计值进行训练,而下方的网络则使用SVHN数据的均值和方差估计值进行训练。但由于移动平均线在两个网络之间共享,因此移动平均线收敛于MNIST和SVHN数据的平均值。因此,在测试时,测试集使用的批量归一化(一个数据集的平均值)的规模和平移与模型预期的(两个数据集的平均值)不同。当测试规范化与训练规范化不同时,模型会得到以下结果。该图是在另一个具有五个随机种子的类似数据集(示例中不是MNIST或SVHN)上的最佳、中等和最差模型性能。当使用两个具有共享权重的网络时,不仅性能会显着下降,而且输出结果的方差也会增加。只要单个小批量数据不能代表整个数据分布,就会出现此问题。这意味着在不随机打乱输入的情况下使用批量归一化是危险的。这在最近流行的生成对抗网络(GAN)中也很重要。GAN中的鉴别器通常是在假数据和真实数据的混合体上训练的。如果在鉴别器中使用批量归一化,则在纯假数据批次或纯真实数据批次之间交替是不正确的。每个小批量需要是两者的均匀混合(每个50%)。值得一提的是,在实践中,使用单独的批量归一化变量同时共享其他变量的网络结构给出了最好的结果。虽然这实现起来比较复杂,但确实比其他方法更有效(见下图)。Batchnormalization:万恶之源看了上面的问题,作者得出结论,如果能用,就不用batchnormalization了。这个结论是从工程的角度来分析的。一般来说,当代码出现问题时,原因往往不外乎以下两种:明显的错误。比如输入错误的变量名,或者忘记调用某个函数。代码对与之交互的其他代码的行为具有未声明的依赖性,并且确实不满足某些条件。这些错误往往更有害,因为通常需要很长时间才能弄清楚代码所依赖的条件。这两个错误都是不可避免的。可以通过使用更简单的方法和重用现有代码来减少II类错误。批量归一化方法有两个基本属性:在训练期间,单个输入xi的输出受小批量中其他xj的约束。测试时,模型的计算路径发生变化。因为现在它使用移动平均而不是小批量平均来进行归一化。很少有其他优化方法具有这些属性。通过这种方式,实施批量归一化代码的人很容易假设输入在小批量中是不相关的,或者训练与测试做同样的事情。没有人会质疑这种方法。当然,你可以把batchnormalization看成黑盒归一化,而且效果很好。但在实践中,抽象泄漏总是存在的,batchnormalization也不例外,其特性使其更容易出现泄漏。你为什么不放弃批量归一化?计算机科学界有一篇著名的文章:Dijkstra的《GoTo语句是有害的》。在其中,Dijkstra认为应该避免使用goto语句,因为它会使代码更难阅读,并且任何使用goto的程序都可以在没有goto语句的情况下以不同的方式重写。作者想声明“batchnormalization是有害的”,但是找不到很好的理由。毕竟batchnormalization太有用了。是的,batchnormalization确实有问题。但是当你做的一切都正确时,模型确实训练得更快。batchnormalizedpaper的引用次数超过1400不是白说的。批量归一化有很多替代方案,但它们也有各自的缺点。层归一化(LayerNormalization)在与RNN结合使用时更有效,但在卷积层中使用时有时会出现问题。WeightNormalization和CosineNormalization都是比较新的归一化方法。weightnormalization一文表明weightnormalization可以应用于一些batchnormalization不起作用的问题。但这些方法至今没有太大用处,或许只是时间问题。Layernormalization、weightnormalization、cosinenormalization都解决了上述batchnormalization的问题。如果你正在处理一个新问题并且想冒一些风险,建议尝试这些归一化方法。毕竟无论使用哪种方法,都需要进行超参数调整。调整后,各种方法之间应该差别不大。(如果你足够勇敢,你甚至可以尝试批量重归一化(BatchRenormalization),但它仍然只在测试时使用移动平均线。)使用批量归一化可以看作是深度学习中的“魔鬼契约”。”。换取高效的训练,丢失了可能的异常结果(insanity)。每个人都在签这份合同。译者注作者对“batchnormalizationisharmful”和“尽可能不要使用batchnormalization”的观点有些偏激.但是文中提到的batchnormalization的陷阱确实是要提防的,因为batchnormalization的有效性,很多深度学习研究者确实把它当成一个“神奇的黑匣子”,应用到每一个可用的地方。因为这个简单粗暴的方法对于提高训练速度是非常有效的,但是大家很难把准确率的下降归咎于batchnormalization,毕竟从来没有人提到过batchnormalization会降低训练准确率。但是,训练和测试时数据集不一致的情况确实很常见。翻译器做的人工模拟训练数据集的方法会遇到这种问题。建议大家在使用batchnormalization之前仔细考虑以下问题:我的训练数据集中的每批样本是否平均?我的每批训练数据集的均值是否与测试时的移动平均值一致?否则,只需使用以下一种或多种方法来避免论文中的问题:随机抽取训练数据集以确保批平均;像文中的例子一样修改模型,避免上述问题;使用层归一化和归一化权重归一化或余弦归一化而不是批量归一化;不使用归一化方法。