sparse_softmax_cross_entropy_with_logits 和 softmax_cross_entropy_with_logits 有啥区别?

Posted

技术标签:

【中文标题】sparse_softmax_cross_entropy_with_logits 和 softmax_cross_entropy_with_logits 有啥区别?【英文标题】:What's the difference between sparse_softmax_cross_entropy_with_logits and softmax_cross_entropy_with_logits?sparse_softmax_cross_entropy_with_logits 和 softmax_cross_entropy_with_logits 有什么区别? 【发布时间】:2016-09-15 16:42:35 【问题描述】:

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

在使用sparse_softmax_cross_entropy_with_logits时,训练向量y必须是one-hot encoded的唯一区别是什么?

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

如果提供一次性编码的训练数据/向量,softmax_cross_entropy_with_logits 是否应该产生与sparse_softmax_cross_entropy_with_logits 相同的结果?

【问题讨论】:

如果两者都可以使用(例如,使用专有图像标签),我有兴趣查看它们的性能比较;我希望稀疏版本更有效,至少在内存方面。 另见this question,它讨论了张量流中的所有交叉熵函数(原来有很多)。 【参考方案1】:

有两个不同的函数是方便,因为它们产生相同的结果。

区别很简单:

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

softmax_cross_entropy_with_logits 中使用的标签是sparse_softmax_cross_entropy_with_logits 中使用的标签的一个热门版本

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

【讨论】:

-1 正确吗?如文档所述:“标签中的每个条目必须是 [0, num_classes) 中的索引。当此操作在 CPU 上运行时,其他值将引发异常,并为 GPU 上的相应损失和梯度行返回 NaN。”跨度> [0, num_classes) = [0, num_classes-1] 这个说法正确吗? “softmax_cross_entropy_with_logits 中使用的标签是 sparse_softmax_cross_entropy_with_logits 中使用的标签的一个热门版本。”是倒退吗?稀疏损失函数不是int为0的,那么稀疏的不是one-hot版本吗?【参考方案2】:

我只想在已接受的答案中添加两件事,您也可以在 TF 文档中找到这些内容。

第一:

tf.nn.softmax_cross_entropy_with_logits

注意:虽然类是互斥的,但它们的概率 不必。所需要的只是每一行标签都是一个 有效的概率分布。如果不是,则计算 渐变会不正确。

第二:

tf.nn.sparse_softmax_cross_entropy_with_logits

注意:对于这个操作,给定标签的概率是 被认为是独家的。也就是说,软类是不允许的,并且 标签向量必须为真实类提供单个特定索引 对于每一行 logits(每个 minibatch 条目)。

【讨论】:

如果类不是互斥的,我们应该使用什么。我的意思是如果我们要组合多个分类标签? 我也读过这个。所以这意味着我们将类概率应用到交叉熵上,而不是把它当作一个单热向量。 @Hayro - 你的意思是你不能做一个热编码?我认为您将不得不查看不同的模型。 This 提到“构建 4 个二元逻辑回归分类器会更合适”之类的东西,首先要确保可以分离类。【参考方案3】:

两个函数计算相同的结果,sparse_softmax_cross_entropy_with_logits 直接在稀疏标签上计算交叉熵,而不是用one-hot encoding 转换它们。

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

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

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

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

【讨论】:

以上是关于sparse_softmax_cross_entropy_with_logits 和 softmax_cross_entropy_with_logits 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章