TensorFlow 2.X中Hinge损失官方接口与手动实现结果不一致问题求解
差异原因解答
核心遗漏点
Hinge损失针对二分类任务设计,要求真实标签y_true的取值为{-1, 1},而非你使用的{0, 1}。TensorFlow内置的tf.keras.losses.Hinge接口会自动对输入的0值标签做转换,将所有0替换为-1后再代入公式计算,你自己实现的代码缺少这一步处理。
官方接口计算过程
你给出的示例中,原始y_true = [[0., 1.], [0., 0.]],官方接口内部先转换为:
[[-1., 1.], [-1., -1.]]
再代入公式loss = maximum(1 - y_true * y_pred, 0)逐元素计算:
- 第一行第一列:
max(1 - (-1)*0.6, 0) = 1.6 - 第一行第二列:
max(1 - 1*0.4, 0) = 0.6 - 第二行第一列:
max(1 - (-1)*0.4, 0) = 1.4 - 第二行第二列:
max(1 - (-1)*0.6, 0) = 1.6
最后对所有元素求均值:(1.6 + 0.6 + 1.4 + 1.6) / 4 = 1.3,和官方输出一致。
你的代码结果说明
你直接使用0值标签计算,0乘任何值结果都是0,逐元素计算结果为:
- 第一行第一列:
max(1 - 0*0.6, 0) = 1 - 第一行第二列:
max(1 - 1*0.4, 0) = 0.6 - 第二行第一列:
max(1 - 0*0.4, 0) = 1 - 第二行第二列:
max(1 - 0*0.6, 0) = 1
均值为(1 + 0.6 + 1 + 1) / 4 = 0.9,和你得到的结果一致。
修正后的实现代码
只需要增加标签转换逻辑即可对齐官方结果:
import tensorflow as tf y_true = tf.Variable([[0., 1.], [0., 0.]]) y_pred = tf.Variable([[0.6, 0.4], [0.4, 0.6]]) def hinge_loss(y_true, y_pred): # 将0值标签转换为Hinge损失要求的-1 y_true = tf.where(y_true == 0, -1., y_true) return tf.reduce_mean(tf.math.maximum(1. - y_true * y_pred, 0.)) print("Hinge Loss :: ", hinge_loss(y_true, y_pred).numpy())
运行后输出为1.3,和官方接口结果一致。
内容的提问来源于stack exchange,提问作者Jay Prakash Thakur
相关产品推荐
相关产品推荐

