【问题标题】:Custom loss function's results does not match with the inbuilt loss function's result自定义损失函数结果与内置损失函数结果不匹配
【发布时间】:2019-11-01 01:02:06
【问题描述】:

我在 tensorflow 中实现了一个自定义的二元交叉熵损失函数。为了测试这一点,我将它与 Tensorflow 中内置的二元交叉熵损失函数进行了比较。但是,在这两种情况下,我得到了非常不同的结果。我无法理解这种行为。

def custom_loss(eps,w1,w2):
    def loss(y_true, y_pred):
        ans = -1*(w1*y_true*tf.log(y_pred+eps) + w2*(1-y_true)*tf.log(y_pred+eps))
        return ans
    return loss

我已将 eps 设置为 1e-6,w1=1 和 w2=1。当我使用损失函数的实现时,损失下降到非常小的值。然而,在 tensorflow 中使用内置损失函数时,出现了稳定的下降。

编辑: 以下是输出:

1:使用自定义实现:

1/650 [.......................] - ETA:46:37 - 损失:0.8810 - acc : 0.50

2/650 [.......................] - ETA:41:27 - 损失:0.4405 - acc : 0.40

3/650 [.......................] - ETA:39:38 - 损失:0.2937 - acc : 0.41

4/650 [.......................] - ETA:38:44 - 损失:0.2203 - acc : 0.45

5/650 [.......................] - ETA:38:13 - 损失:0.1762 - acc : 0.46

6/650 [.......................] - ETA:37:47 - 损失:0.1468 - acc : 0.42

7/650 [.......................] - ETA:37:29 - 损失:0.1259 - acc : 0

  1. 使用 eps=1e-7 的内置损失函数。

1/650 [.......................] - ETA:48:15 - 损失:2.4260 - acc : 0.31

2/650 [.......................] - ETA:42:09 - 损失:3.1842 - acc : 0.46

3/650 [.......................] - ETA:40:10 - 损失:3.4615 - acc : 0.47

4/650 [.......................] - ETA:39:06 - 损失:3.9737 - acc : 0.45

5/650 [.......................] - ETA:38:28 - 损失:4.5173 - acc : 0.47

6/650 [.......................] - ETA:37:58 - 损失:5.1865 - acc : 0.45

7/650 [.......................] - ETA:37:41 - 损失:5.8239 - acc : 0.43

8/650 [.......................] - ETA:37:24 - 损失:5.6979 - acc : 0.46

9/650 [.......................] - ETA:37:12 - 损失:5.5973 - acc : 0.47

输入是来自 MURA 数据集的图像。为了保持测试统一,两个测试都通过了相同的图像。

【问题讨论】:

  • 请提供您的输入、预期输出和实际输出。我也相信 tf 中的二元交叉熵使用 eps=1e-7

标签: python tensorflow machine-learning


【解决方案1】:

您的实施中有一个小错误。

你有:

ans = -1*(w1*y_true*tf.log(y_pred+eps) + w2*(1-y_true)*tf.log(y_pred + eps))

然而,我认为你的目标是:

ans = -1*(w1*y_true*tf.log(y_pred+eps) + w2*(1-y_true)*tf.log(1 - y_pred + eps))

通常我们也会取这个损失的平均值,以便我们的实现:

def custom_loss(eps,w1,w2):
    def loss(y_true, y_pred):
        ans = -1*(w1*y_true*tf.log(y_pred+eps) + w2*(1-y_true)*tf.log(1-y_pred+eps))
        return tf.reduce_mean(ans)
    return loss

我们现在可以针对开箱即用的实现进行测试:

y_true = tf.constant([0.1, 0.2])
y_pred = tf.constant([0.11, 0.19])

custom_loss(y_true, y_pred)                         # == 0.41316
tf.keras.losses.binary_crossentropy(y_true, y_pred) # == 0.41317

并发现结果与许多小数位匹配(我无法解释微小的差异 - 也许是不同的 epsilon 值? - 但我想这么小的差异可以忽略不计)

【讨论】:

  • 我应该提一下,当我查看您之前的问题时,我没有看到此错误!我很高兴你写了一个新问题,但在我肯定会提到它之前我已经注意到它了! :-)
  • 非常感谢 Stewart R。这让我对机器学习中的损失函数有了清晰的理解。
猜你喜欢
  • 1970-01-01
  • 2020-01-12
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 2017-04-04
  • 2017-12-18
相关资源
最近更新 更多