Keras(TF后端)中的BatchNormalization实现-激活之前还是之后?

时间:2019-04-24 10:15:55

标签: tensorflow keras deep-learning batch-normalization

请考虑以下代码段

model = models.Sequential()
model.add(layers.Dense(256, activation='relu'))     # Layer 1
model.add(BatchNormalization())
model.add(layers.Dense(128, activation='relu'))     # Layer 2

我在Tensorflow后端上使用Keras。

我的问题是-在Keras的实现中,BN是在激活功能之前还是之后执行的?

要更加清楚,

  1. 是否应在激活之前或之后应用BN尚有争议,原始论文(Ioffe和Szegedy,2015年)建议使用“ BEFORE”,但以下主题的评论显示了不同的观点。 Ordering of batch normalization and dropout?

  2. 在Keras文档(https://keras.io/layers/normalization/)中,它说 “在每批中对上一层的激活进行归一化,即应用一个转换,将平均激活保持在0附近,并将激活标准偏差保持在1附近。”

Keras的文档似乎建议在激活后应用BN(即在上面的示例代码中,在第1层上的“ relu”之后应用BN)。我想确认是否是这种情况?

此外,是否可以配置在激活功能之前还是之后应用BN?

谢谢!

2 个答案:

答案 0 :(得分:3)

BatchNorm之前或之后添加activation仍然是一个公开辩论。作者建议的原始版本效果很好,并已在许多实现中使用。但是许多人发现激活后的BN确实可以很好地工作并有助于更快地收敛。例如,检查this线程中的讨论。

简而言之,这取决于任务!哪个会更好?您必须自己检查。是的,您可以控制订单。例如:

x = Conv2D(64, (3,3), activation=None)(inputs)
x = BatchNormalization()(x)
x = Activation("relu")(x)

x = Conv2D(64, (3,3), activation="relu")(inputs)
x = BatchNormalization()(x)

答案 1 :(得分:0)

除了原始论文在激活前使用批归一化之外,Bengio 的书 Deep Learning, section 8.7.1 给出了一些推理为什么在激活之后(或直接在输入到下一层之前)应用批归一化可能会导致一些问题:

<块引用>

很自然地想知道我们是否应该将批量归一化应用于 输入 X,或转换后的值 XW+b。 Ioffe 和 Szegedy (2015) 推荐后者。更具体地说,XW+b 应该替换为 a XW 的标准化版本。应该省略偏置项,因为它 随着批处理应用的 β 参数变得多余 归一化重新参数化。层的输入通常是 非线性激活函数的输出,例如整流线性 上一层的功能。因此,输入的统计信息是 更非高斯,更不适合线性标准化 操作。

换句话说,如果我们使用 relu 激活,所有负值都映射为零。这可能会导致平均值已经非常接近于零,但剩余数据的分布将严重偏向右侧。尝试将该数据标准化为漂亮的钟形曲线可能不会给出最佳结果。对于 relu 系列之外的激活,这可能不是什么大问题。

有些人在激活后进行批量标准化时会报告更好的结果,而另一些人在激活前进行批量标准化时会得到更好的结果。最好使用这两种配置来测试您的模型,如果激活后的批量标准化显着降低了验证损失,请改用该配置。