tf.keras.losses.categorical_crossentropy() 没有输出它应该输出的内容

tf.keras.losses.categorical_crossentropy() does not output what it should output

我正在尝试用 3 类 训练分类器 CNN。我正在尝试解决我的损失函数。我正在测试 tf.keras.losses.CategoricalCrossentropy()tf.keras.losses.categorical_crossentropy().numpy()。我遵循 the tensorflow documentation.

中的独立使用指南

我认为我没有得到应有的正确输出。 当我输入 y_true=[0.,1.,0.]y_pred=[1.,0.,0.] 时,我预计会丢失无穷大(程序中的输出:nan)。但是,我收到的输出是 16.118095。当分类与标签对齐时(即 y_true=[1.,0.,0.]y_pred=[1.,0.,0.]),输出为 1.192093e-07,即使我期望完美的 0.

我对这种行为感到很困惑。同样,对于 1 长向量情况:y_true=[1.]y_pred=[0.] 损失是 16.118095,同样当分类对齐 y_true=[1.]y_pred=[1.] 我收到 1.192093e-07y_true=[0.]y_pred=[0.] 结果是 nan.

我认为总结我得到的结果、我期望的结果以及我输入到损失函数中的值会使事情更具可读性,所以我将在下面这样做:

y_true y_pred Actual Output What I Expect
[0.,1.,0.] [1.,0.,0.] 16.118095 nan or infinity
[1.,0.,0.] [1.,0.,0.] 1.192093e-07 True 0
[0.,1.] [1.,0.] 16.118095 nan or infinity
[1.,0.] [1.,0.] 1.192093e-07 True 0
[1.] [0] nan or infinity nan or infinity
[1.] [1.] 1.192093e-07 True 0

如果这是一个微不足道的问题,我很抱歉,但我真的不知道为什么我会得到我得到的结果。我认为出了点问题,因为我只得到 16 而不是无穷大,但如果没有任何问题,我希望得到保证。如果我错了,我将不胜感激。

原因是 tf.keras.losses.categorical_crossentropyy_pred 等于 1 或 0 时对 y_pred 应用了一个小的偏移量 (1e-7),这就是为什么在您的情况下您看不到您期望的输出。

import tensorflow as tf

def categorical_crossentropy(y_true, y_pred, clip=False):
    if clip == True:
        y_pred = tf.clip_by_value(y_pred, 1e-7, 1 - 1e-7)
    return - tf.experimental.numpy.nansum(y_true * tf.math.log(y_pred))

y_true = [0., 1., 0.]
y_pred = [1., 0., 0.]

print(tf.keras.losses.categorical_crossentropy(y_true, y_pred).numpy())
# 16.118095

print(categorical_crossentropy(y_true, y_pred, clip=True).numpy())
# 16.118095

print(categorical_crossentropy(y_true, y_pred, clip=False).numpy())
# inf

y_true = [1., 0., 0.]
y_pred = [1., 0., 0.]

print(tf.keras.losses.categorical_crossentropy(y_true, y_pred).numpy())
# 1.1920929e-07

print(categorical_crossentropy(y_true, y_pred, clip=True).numpy())
# 1.1920929e-07

print(categorical_crossentropy(y_true, y_pred, clip=False).numpy())
# -0.0

y_true = [0., 1., 0.]
y_pred = [0.05, 0.95, 0.]

print(tf.keras.losses.categorical_crossentropy(y_true, y_pred).numpy())
# 0.051293306

print(categorical_crossentropy(y_true, y_pred, clip=True).numpy())
# 0.051293306

print(categorical_crossentropy(y_true, y_pred, clip=False).numpy())
# 0.051293306