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-07
和 y_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_crossentropy
在 y_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
我正在尝试用 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-07
和 y_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_crossentropy
在 y_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