我有
y_true = 16
和
y_pred = array([1.1868494e-08, 1.8747659e-09, 1.2777099e-11, 3.6140797e-08, 6.5852622e-11, 2.2888577e-10, 1.4515833e-09, 2.8392664e-09, 4.7054605e-10, 9.5605066e-11, 9.3647139e-13, 2.6149302e-10, 2.5338919e-14, 4.8815413e-10, 3.9381631e-14, 2.1434269e-06, 9.9999785e-01, 3.0857247e-08, 1.3536775e-09, 4.6811921e-10, 3.0638234e-10, 2.0818169e-09, 2.9950772e-10, 1.0457132e-10, 3.2959850e-11, 3.4232595e-10, 5.1689473e-12], dtype=float32)
当我使用 tf.keras.losses.categorical_crossentropy(to_categorical(y_true,num_classes=27),y_pred,from_logits=True)
我得到的损失值是 2.3575358
。
但是如果我使用分类交叉熵的公式来计算损失值
-np.sum(to_categorical(gtp_out_true[0],num_classes=27)*np.log(gtp_pred[0]))
我得到的值是 2.1457695e-06
现在,我的疑问是,为什么函数 tf.keras.losses.categorical_crossentropy
会给出不同的值。
奇怪的是,尽管损失值固定在2.3575,我的模型仍然给出了100%的准确率。下面是训练过程中准确率和损失值的图表图像。
TensorFlow 计算分类交叉熵使用的是什么公式?
回答:
y_pred
作为概率向量,因此你不应该使用 from_logits=True
。将其设置为 False
,你会得到:
>>> print(categorical_crossentropy(to_categorical(16, num_classes = 27), y_pred, from_logits = False).numpy())2.264979e-06
之所以它不等于预期的2.1457695e-06,我认为是因为 y_pred[16] 非常接近1.0,并且 categorical_crossentropy
增加了一些平滑处理。
关于 logits 的讨论,请参见此答案: TensorFlow 中 logits 一词的含义是什么?
如果你每个输入值只能有一个标签,你也可以使用函数的稀疏版本:
print(sparse_categorical_crossentropy(16, y_pred))