python - tf.keras.BatchNormalization 给出意外的输出
问题描述
import tensorflow as tf
tf.enable_eager_execution()
print(tf.keras.layers.BatchNormalization()(tf.convert_to_tensor([[5.0, 70.0], [5.0, 60.0]])))
print(tf.contrib.layers.batch_norm(tf.convert_to_tensor([[5.0, 70.0], [5.0, 60.0]])))"
上述代码的输出(在 Tensorflow 1.15 中)是:
tf.Tensor([[ 4.99 69.96] [ 4.99 59.97]], shape=(2, 2), dtype=float32)
tf.Tensor([[ 0. 0.99998] [ 0. -0.99998]], shape=(2, 2), dtype=float32)
我的问题是为什么同一个函数给出完全不同的输出。我也玩了一些函数的参数,但结果是一样的。对我来说,第二个输出是我想要的。此外,pytorch 的 batchnorm 也提供与第二个相同的输出。所以我认为这是keras的问题。
知道如何在 keras 中修复 batchnorm 吗?
解决方案
Batch Normalization 层在训练和推理中具有不同的行为:
在训练期间(即使用 fit() 或使用参数 training=True 调用层/模型时),层使用当前批次输入的均值和标准差对其输出进行归一化。
在推理过程中(即使用 evaluate() 或 predict() 或使用参数 training=False (这是默认值)调用层/模型时,层使用均值和标准差的移动平均值对其输出进行归一化它在训练期间看到的批次。
因此,第一个结果是由于 defaulttraining=False
而第二个是由于 default is_training=True
。
如果您想要相同的结果,您可以尝试:
x = tf.convert_to_tensor([[5.0, 70.0], [5.0, 60.0]])
print(tf.keras.layers.BatchNormalization()(x, training=True).numpy().tolist())
print(tf.contrib.layers.batch_norm(x).numpy().tolist())
#output
#[[0.0, 0.9999799728393555], [0.0, -0.9999799728393555]]
#[[0.0, 0.9999799728393555], [0.0, -0.9999799728393555]]
或者
x = tf.convert_to_tensor([[5.0, 70.0], [5.0, 60.0]])
print(tf.keras.layers.BatchNormalization()(x).numpy().tolist())
print(tf.contrib.layers.batch_norm(x, is_training=False).numpy().tolist())
#output
#[[4.997501850128174, 69.96502685546875], [4.997501850128174, 59.97002410888672]]
#[[4.997501850128174, 69.96502685546875], [4.997501850128174, 59.97002410888672]]
推荐阅读
- google-cloud-dataprep - 是否可以安排 Dataprep 同一个作业根据时间处理不同的数据源?
- r - 将文件夹中的单独df转换为r中的单个df
- javascript - 当您从 chrome 访问时,如何防止 target="_blank" 链接被 PWA 应用程序打开?
- fullcalendar - 远程桌面会话上的 Internet Explorer 11 时间线年视图显示带有 longdatestring 的日期
- r - 如何限制模糊连接只返回一个匹配项
- scala - Spark重新分区到特定资源
- java - 即使客户端代码使用 needClientAuth(true) 设置,单向 TLS 套接字通信仍在进行
- php - 根据产品属性条款有条件地应用 WooCommerce 优惠券
- html - 如何检查来自firebase的日期是否等于今天
- django - 无法从 python 3.6 中的其他包导入模块