softmax_cross_entropy_with_logits 和 losses.log_loss 有什么区别?

what's the difference between softmax_cross_entropy_with_logits and losses.log_loss?

tf.nn.softmax_cross_entropy_with_logitstf.losses.log_loss 之间的主要区别是什么?这两种方法都接受 1-hot 标签和 logits 来计算分类任务的交叉熵损失。

这些方法在理论上并没有太大的不同,但是在实现上有很多不同:

1) tf.nn.softmax_cross_entropy_with_logits专为单class标签设计,而tf.losses.log_loss可用于多class class化。如果您提供多个 class 标签,tf.nn.softmax_cross_entropy_with_logits 不会抛出错误,但是您的梯度将无法正确计算并且训练很可能会失败。

来自官方文档:

NOTE: While the classes are mutually exclusive, their probabilities need not be. All that is required is that each row of labels is a valid probability distribution. If they are not, the computation of the gradient will be incorrect.

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 returns 对批次中的每个条目进行损失,而 tf.losses.log_loss returns 减少(默认情况下对所有样本求和)值直接在优化器中使用。

UPD: 另一个区别是计算损失的方式,对数损失考虑了负 classes(向量中有 0 的那些)。很快,交叉熵损失迫使网络为正确的 class 产生最大输入,而不关心负 classes。对数损失同时进行,它迫使正确的 classes 具有较大的值和较小的负值。在数学表达式中,它看起来如下:

交叉熵损失:

对数损失:

其中i是对应的class。

例如,如果您有标签=[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) + log (0.7)) = 0.7133

然后,如果您使用 tf.losses.log_loss 的默认值,则需要将 log_loss 输出除以非零元素的数量(此处为 2)。所以最后:tf.nn.log_loss = 0.7133 / 2 = 0.3566

在这种情况下,我们得到了相等的输出,但情况并非总是如此

基本上有两个区别,

1) tf.nn.softmax_cross_entropy_with_logits中使用的标签是tf.losses.log_loss中使用的标签的一个热门版本。

2) tf.nn.softmax_cross_entropy_with_logits 在计算交叉熵之前在内部计算 softmax 的 logits。

请注意 tf.losses.log_loss 也接受单热编码标签。但是,tf.nn.softmax_cross_entropy_with_logits 只接受带有 one-hot 编码的标签。

希望对您有所帮助。