自定义损失函数的结果与内置损失函数的结果不匹配

时间:2019-06-18 11:32:57

标签: python tensorflow machine-learning

我已经在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 [..............................]-预计到达时间:46:37-损失:0.8810-acc :0.50

2/650 [.....................]-预计到达时间:41:27-损失:0.4405-acc :0.40

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

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

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

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

7/650 [..............................]-预计到达时间:37:29-损失:0.1259-acc :0

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

1/650 [.....................]-预计到达时间:48:15-损失:2.4260-acc :0.31

2/650 [..............................]-预计到达时间:42:09-损失:3.1842-acc :0.46

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

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

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

6/650 [.....................]-预计到达时间:37:58-损失:5.1865-acc :0.45

7/650 [.....................]-预计到达时间:37:41-损失:5.8239-acc :0.43

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

9/650 [.....................]-预计到达时间:37:12-损失:5.5973-acc :0.47

输入是来自MURA数据集的图像。为了使测试保持一致,在两个测试中均传递相同的图像。

1 个答案:

答案 0 :(得分:2)

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

您有:

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值?-但我认为这样小的差异可以忽略不计)