tf.keras.BatchNormalization 给出意外输出
tf.keras.BatchNormalization giving unexpected output
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 吗?
批量归一化层在训练和推理中有不同的行为:
在训练期间(即当使用fit()
或使用参数training=True
调用layer/model时),该层使用当前批次输入的均值和标准差对其输出进行归一化。
推理期间(即使用evaluate()
或predict()
时或使用参数调用layer/model时training=False
(这是默认值),该层使用它在训练期间看到的批次的均值和标准差的移动平均值对其输出进行归一化。
因此,第一个结果是默认 training=False
,第二个是默认 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]]
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 吗?
批量归一化层在训练和推理中有不同的行为:
在训练期间(即当使用
fit()
或使用参数training=True
调用layer/model时),该层使用当前批次输入的均值和标准差对其输出进行归一化。推理期间(即使用
evaluate()
或predict()
时或使用参数调用layer/model时training=False
(这是默认值),该层使用它在训练期间看到的批次的均值和标准差的移动平均值对其输出进行归一化。
因此,第一个结果是默认 training=False
,第二个是默认 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]]