sparse_softmax_cross_entropy_with_logits和softmax_cross_entropy_with_logits有什么区别?


111

我最近遇到了tf.nn.sparse_softmax_cross_entropy_with_logits,但我不知道与tf.nn.softmax_cross_entropy_with_logits有什么区别。

是唯一的区别在于训练矢量y必须是独热编码使用时sparse_softmax_cross_entropy_with_logits

阅读API,与相比,我找不到其他任何区别softmax_cross_entropy_with_logits。但是,为什么我们需要额外的功能呢?

如果提供了一键编码的训练数据/矢量,softmax_cross_entropy_with_logits结果应该不会与相同sparse_softmax_cross_entropy_with_logits


1
我有兴趣比较一下两者的性能(例如带专用图像标签);我希望稀疏版本更有效,至少在内存方面更有效。
杨艺博

1
另请参阅此问题该问题讨论了张量流中的所有交叉熵函数(事实证明它们很多)。
Maxim

Answers:


175

具有两个不同的功能很方便,因为它们产生相同的结果。

区别很简单:

  • 对于sparse_softmax_cross_entropy_with_logits,标签的形状必须为[batch_size],且dtype为int32或int64。每个标签的范围都是int [0, num_classes-1]
  • 对于softmax_cross_entropy_with_logits,标签的形状必须为[batch_size,num_classes]且类型为float32或float64。

中使用的标签是中使用的标签softmax_cross_entropy_with_logits一种最新版本sparse_softmax_cross_entropy_with_logits

另一个微小的区别是,使用sparse_softmax_cross_entropy_with_logits,您可以给-1作为标签,使该标签上有损失0


15
-1是否正确?正如文档所述:“标签中的每个条目必须是[0,num_classes)中的索引。当此op在CPU上运行时,其他值将引发异常,并为GPU上的相应损失和梯度行返回NaN。”
user1761806

1
[0,num_classes)= [0,num_classes-1]
Karthik C

24

我只想在已接受的答案中添加2件事,您也可以在TF文档中找到它们。

第一:

tf.nn.softmax_cross_entropy_with_logits

注意:尽管这些类是互斥的,但它们的概率不是必须的。所需要的只是标签的每一行都是有效的概率分布。如果不是,则梯度的计算将不正确。

第二:

tf.nn.sparse_softmax_cross_entropy_with_logits

注意:对于此操作,给定标签的概率被认为是排他的。也就是说,不允许使用软类,并且标签矢量必须为logit的每一行(每个小批量条目)为真实类提供单个特定的索引。


4
如果类不是互斥的,我们应该使用什么。我的意思是,如果我们要组合多个类别标签?
Hayro '17

我也读过这个。因此,这意味着我们将类概率应用于交叉熵,而不是将其作为一个向量。
Shamane Siriwardhana

@Hayro-您是说无法执行一种热编码吗?我认为您将不得不考虑其他模型。这里提到类似“构建4个二进制逻辑回归分类器会更合适”这样的东西,首先要确保可以分离这些类。
阿什利(Ashley)

21

这两个函数都计算出相同的结果,而sparse_softmax_cross_entropy_with_logits直接在稀疏标签上计算交叉熵,而不是使用一键编码进行转换。

您可以通过运行以下程序来验证这一点:

import tensorflow as tf
from random import randint

dims = 8
pos  = randint(0, dims - 1)

logits = tf.random_uniform([dims], maxval=3, dtype=tf.float32)
labels = tf.one_hot(pos, dims)

res1 = tf.nn.softmax_cross_entropy_with_logits(       logits=logits, labels=labels)
res2 = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=tf.constant(pos))

with tf.Session() as sess:
    a, b = sess.run([res1, res2])
    print a, b
    print a == b

在这里,我创建了一个logits长度随机的向量,dims并生成了一个热编码标签(其中in pos为1,其他元素为0)。

之后,我计算softmax和稀疏softmax并比较它们的输出。尝试重新运行几次,以确保始终产生相同的输出

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.