这些方法在理论上并没有太大不同,但在实现上有许多差异:
1) tf.nn.softmax_cross_entropy_with_logits
是为单类标签设计的,而tf.losses.log_loss
可用于多类分类。tf.nn.softmax_cross_entropy_with_logits
如果您提供多类标签,则不会抛出错误,但是您的梯度将无法正确计算,并且训练很可能会失败。
来自官方文档:
注意:虽然这些类别是互斥的,但它们的概率不一定是互斥的。所需要的只是每行标签都是有效的概率分布。如果不是,梯度的计算将不正确。
2) tf.nn.softmax_cross_entropy_with_logits
首先在预测之上计算(从名称中可以看出)soft-max 函数,而 log_loss 不会执行此操作。
3) tf.losses.log_loss
从某种意义上说,具有更广泛的功能,您可以对损失函数的每个元素进行加权,或者可以指定epsilon
,用于计算,以避免 log(0) 值。
4)最后,tf.nn.softmax_cross_entropy_with_logits
返回批次中每个条目的损失,同时tf.losses.log_loss
返回减少的(默认情况下所有样本的总和)值,可以直接在优化器中使用。
UPD:另一个区别是计算损失的方式,对数损失考虑负类(向量中有 0 的那些)。简而言之,交叉熵损失迫使网络为正确的类产生最大的输入,并且不关心负类。对数损失同时完成这两个任务,它迫使正确的类具有更大的值和更小的负值。用数学表达式表示如下:
交叉熵损失:
对数损失:
其中i是对应的类。
例如,如果您有 labels=[1,0] 且 Predictions_with_softmax = [0.7,0.3],则:
1) 交叉熵损失:-(1 * log(0.7) + 0 * log(0.3)) = 0.3567
2)对数损失: - (1*log(0.7) + (1-1) * log(1 - 0.7) +0*log(0.3) + (1-0) log (1- 0.3)) = - (log (0.7) + 对数 (0.7)) = 0.7133
然后如果您使用默认值tf.losses.log_loss
然后你需要划分log_loss
输出非零元素的数量(这里是 2)。所以最后:tf.nn.log_loss = 0.7133 / 2 = 0.3566
在这种情况下,我们得到了相等的输出,但情况并非总是如此