【发布时间】:2020-08-27 12:21:10
【问题描述】:
对二元交叉熵不使用二元基本真值是否有意义?有什么正式的证明吗?
看起来像在实践中使用:例如在https://blog.keras.io/building-autoencoders-in-keras.html 中,即 mnist 图像不是二进制图像,而是灰色图像。
这里是代码示例:
1.正常情况:
def test_1():
print('-'*60)
y_pred = np.array([0.5, 0.5])
y_pred = np.expand_dims(y_pred, axis=0)
y_true = np.array([0.0, 1.0])
y_true = np.expand_dims(y_true, axis=0)
loss = keras.losses.binary_crossentropy(
K.variable(y_true),
K.variable(y_pred)
)
print("K.eval(loss):", K.eval(loss))
输出:
K.eval(loss): [0.6931472]
2.非二元真实值情况:
def test_2():
print('-'*60)
y_pred = np.array([0.0, 1.0])
y_pred = np.expand_dims(y_pred, axis=0)
y_true = np.array([0.5, 0.5])
y_true = np.expand_dims(y_true, axis=0)
loss = keras.losses.binary_crossentropy(
K.variable(y_true),
K.variable(y_pred)
)
print("K.eval(loss):", K.eval(loss))
输出:
K.eval(loss): [8.01512]
3.[0,1]范围外的真值:
def test_3():
print('-'*60)
y_pred = np.array([0.5, 0.5])
y_pred = np.expand_dims(y_pred, axis=0)
y_true = np.array([-2.0, 2.0])
y_true = np.expand_dims(y_true, axis=0)
loss = keras.losses.binary_crossentropy(
K.variable(y_true),
K.variable(y_pred)
)
print("K.eval(loss):", K.eval(loss))
输出:
K.eval(loss): [0.6931472]
由于某种原因,test_1 和 test_3 中的丢失是相同的,可能是因为将 [-2, 2] 裁剪为 [0, 1] 但我在 Keras 代码中看不到裁剪代码。
同样有趣的是,test_1 和 test_2 的损失值有很大差异,但在第一种情况下,我们有 [0.5, 0.5] 和 [0.0, 1.0],在第二种情况下,我们有 [0.0, 1.0] 和 [0.5, 0.5] ],这是相同的值,但顺序相反。
在 Keras 中 binary_crossentropy 定义为:
def binary_crossentropy(y_true, y_pred):
return K.mean(K.binary_crossentropy(y_true, y_pred), axis=-1)
def binary_crossentropy(target, output, from_logits=False):
"""Binary crossentropy between an output tensor and a target tensor.
# Arguments
target: A tensor with the same shape as `output`.
output: A tensor.
from_logits: Whether `output` is expected to be a logits tensor.
By default, we consider that `output`
encodes a probability distribution.
# Returns
A tensor.
"""
# Note: tf.nn.sigmoid_cross_entropy_with_logits
# expects logits, Keras expects probabilities.
if not from_logits:
# transform back to logits
_epsilon = _to_tensor(epsilon(), output.dtype.base_dtype)
output = tf.clip_by_value(output, _epsilon, 1 - _epsilon)
output = tf.log(output / (1 - output))
return tf.nn.sigmoid_cross_entropy_with_logits(labels=target,
logits=output)
【问题讨论】:
标签: python keras deep-learning loss-function cross-entropy