Keras 中的批处理规范化实现(TF 后端) - 激活之前还是之后?



请考虑以下代码片段

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。

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

为了增加更多清晰度,

  1. BN是否应该在激活之前或之后应用是有争议的,原始的(Ioffe和Szegedy 2015)论文建议"BEFORE",但来自以下线程的评论显示了不同的意见。 批量规范化和辍学的排序?

  2. 在 Keras 文档 (https://keras.io/layers/normalization/) 中,它说 "对每批前一层的激活进行归一化,即应用一种变换,使平均激活接近0,激活标准差接近1。">

Keras 的文档似乎表明 BN 是在激活后应用的(即在上面的示例代码中,BN 在第 1 层的"relu"之后应用)。我想确认是不是这样?

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

谢谢!

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

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

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)

除了在激活前使用批量归一化的原始论文之外,Bengio 的《深度学习》一书第 8.7.1 节给出了一些推理,说明为什么在激活后(或直接在下一层输入之前)应用批量归一化可能会导致一些问题:

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

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

有些报告在激活后放置批量归一化时结果更好,而另一些则在激活前进行批量归一化时获得更好的结果。 最好使用这两种配置来测试模型,如果激活后的批量规范化显著减少了验证损失,请改用该配置。

最新更新