什么是logits,softmax和softmax_cross_entropy_with_logits?
machine-learning
python
tensorflow
10
0

我正在这里浏览tensorflow API文档。在tensorflow文档中,他们使用了一个名为logits的关键字。它是什么? API文档中的许多方法都将其编写为

tf.nn.softmax(logits, name=None)

如果写的是那些logits只是Tensors ,为什么logits保留一个不同的名称,如logits

另一件事是,我无法区分两种方法。他们是

tf.nn.softmax(logits, name=None)
tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)

它们之间有什么区别?这些文档对我来说还不清楚。我知道tf.nn.softmax做什么。但是没有其他。一个例子将非常有帮助。

参考资料:
Stack Overflow
收藏
评论
共 6 个回答
高赞 时间 活跃

简洁版本:

假设您有两个张量,其中y_hat包含每个类的计算得分(例如,来自y = W * x + b),而y_true包含一键编码的true标签。

y_hat  = ... # Predicted label, e.g. y = tf.matmul(X, W) + b
y_true = ... # True label, one-hot encoded

如果将y_hat的分数解释为未归一化的对数概率,则它们为logits

此外,以这种方式计算的总交叉熵损失为:

y_hat_softmax = tf.nn.softmax(y_hat)
total_loss = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), [1]))

基本上等于使用softmax_cross_entropy_with_logits()函数计算的总交叉熵损失:

total_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))

长版:

在神经网络的输出层中,您可能会计算一个包含每个训练实例的类分数的数组,例如来自计算y_hat = W*x + b 。作为示例,下面我创建了一个y_hat作为2 x 3数组,其中行对应于训练实例,列对应于类。因此,这里有2个训练实例和3个课程。

import tensorflow as tf
import numpy as np

sess = tf.Session()

# Create example y_hat.
y_hat = tf.convert_to_tensor(np.array([[0.5, 1.5, 0.1],[2.2, 1.3, 1.7]]))
sess.run(y_hat)
# array([[ 0.5,  1.5,  0.1],
#        [ 2.2,  1.3,  1.7]])

请注意,这些值未规范化(即,各行的总和不等于1)。为了对其进行归一化,我们可以应用softmax函数,该函数将输入解释为归一化的对数概率(aka logits ),并输出归一化的线性概率。

y_hat_softmax = tf.nn.softmax(y_hat)
sess.run(y_hat_softmax)
# array([[ 0.227863  ,  0.61939586,  0.15274114],
#        [ 0.49674623,  0.20196195,  0.30129182]])

完全了解softmax输出在说什么很重要。下面我显示了一个表格,可以更清楚地表示上面的输出。可以看出,例如,训练实例1为“等级2”的概率为0.619。每个训练实例的类概率均已标准化,因此每行的总和为1.0。

                      Pr(Class 1)  Pr(Class 2)  Pr(Class 3)
                    ,--------------------------------------
Training instance 1 | 0.227863   | 0.61939586 | 0.15274114
Training instance 2 | 0.49674623 | 0.20196195 | 0.30129182

因此,现在我们有了每个训练实例的类概率,在这里我们可以采用每一行的argmax()来生成最终分类。从上面可以生成训练实例1属于“类别2”,训练实例2属于“类别1”。

这些分类正确吗?我们需要根据训练集中的真实标签进行衡量。您将需要一个一次性编码的y_true数组,其中行再次是训练实例,而列又是类。下面,我创建了一个y_true单热点数组示例,其中训练实例1的真实标签为“ Class 2”,训练实例2的真实标签为“ Class 3”。

y_true = tf.convert_to_tensor(np.array([[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]]))
sess.run(y_true)
# array([[ 0.,  1.,  0.],
#        [ 0.,  0.,  1.]])

是概率分布y_hat_softmax接近的概率分布y_true ?我们可以使用交叉熵损失来测量误差。

交叉熵损失的公式

我们可以逐行计算交叉熵损失并查看结果。在下面我们可以看到训练实例1的损失为0.479,而训练实例2的损失为1.200。这个结果是有道理的,因为在上面的示例中y_hat_softmax表明训练实例1的最高概率是“类别2”的,它与y_true中的训练实例1相匹配;但是,针对训练实例2的预测显示出“类别1”的最高概率,这与真实的类别“类别3”不匹配。

loss_per_instance_1 = -tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1])
sess.run(loss_per_instance_1)
# array([ 0.4790107 ,  1.19967598])

我们真正想要的是所有训练实例的总损失。因此我们可以计算:

total_loss_1 = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1]))
sess.run(total_loss_1)
# 0.83934333897877944

使用softmax_cross_entropy_with_logits()

相反,我们可以使用tf.nn.softmax_cross_entropy_with_logits()函数来计算总交叉熵损失,如下所示。

loss_per_instance_2 = tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true)
sess.run(loss_per_instance_2)
# array([ 0.4790107 ,  1.19967598])

total_loss_2 = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))
sess.run(total_loss_2)
# 0.83934333897877922

请注意, total_loss_1total_loss_2产生的结果基本相同,但最后几位的差异很小。但是,您也可以使用第二种方法:它减少了一行代码,并且减少了数值误差,因为softmax是在softmax_cross_entropy_with_logits()内部为您完成的。

收藏
评论

Logits只是意味着该函数在较早的图层的未缩放输出上运行,并且理解单位的相对缩放是线性的。特别是,这意味着输入的总和可能不等于1,这意味着值不是概率(输入可能为5)。

tf.nn.softmax仅产生将softmax函数应用于输入张量的结果。 softmax“压缩”输入,以便sum(input) = 1 :这是一种归一化方法。 softmax的输出形状与输入相同:它只是将值标准化。 softmax的输出可以解释为概率。

a = tf.constant(np.array([[.1, .3, .5, .9]]))
print s.run(tf.nn.softmax(a))
[[ 0.16838508  0.205666    0.25120102  0.37474789]]

相比之下, tf.nn.softmax_cross_entropy_with_logits在应用softmax函数之后会计算结果的交叉熵(但它会在数学上更加仔细地一起进行)。它类似于以下结果:

sm = tf.nn.softmax(x)
ce = cross_entropy(sm)

交叉熵是一个汇总指标:跨元素求和。形状为[2,5]张量的tf.nn.softmax_cross_entropy_with_logits的输出为形状[2,1] (将第一维视为批处理)。

如果要进行优化以最小化交叉熵,并且要在最后一层之后进行软最大化,则应使用tf.nn.softmax_cross_entropy_with_logits而不是自己进行操作,因为它以数学上正确的方式涵盖了数值不稳定的拐角情况。否则,您最终会在这里和那里添加少量epsilon,从而对其进行破解。

编辑于2016-02-07:如果您具有单类标签,而一个对象只能属于一个类,则现在可以考虑使用tf.nn.sparse_softmax_cross_entropy_with_logits这样您就不tf.nn.sparse_softmax_cross_entropy_with_logits标签转换为密集的标签了。 -热阵列。在0.6.0版本之后添加了此功能。

收藏
评论

tf.nn.softmax计算通过softmax层的前向传播。计算模型输出的概率时,可以在评估模型时使用它。

tf.nn.softmax_cross_entropy_with_logits计算softmax层的成本。仅在训练期间使用。

logits是模型输出的未归一化对数概率 (将softmax归一化之前对它们输出的值)。

收藏
评论

softmax都是logit,这就是J. Hinton一直在Coursera视频中重复的内容。

收藏
评论

以上答案对所提问题有足够的描述。

除此之外,Tensorflow还优化了以下操作:应用激活函数,然后使用其自身的激活以及成本函数来计算成本。因此,使用以下方法是一个好习惯:在tf.nn.softmax_cross_entropy()上使用tf.nn.softmax(); tf.nn.cross_entropy()

您可以在资源密集型模型中找到它们之间的显着差异。

收藏
评论

Tensorflow 2.0兼容答案dgastackoverflowuser2010的解释关于Logits及其相关功能非常详细。

所有这些功能在Tensorflow 1.x使用时Tensorflow 1.x可以正常工作,但是如果将代码从1.x (1.14, 1.15, etc) Tensorflow 1.x 1.x (1.14, 1.15, etc)迁移到2.x (2.0, 2.1, etc..) Tensorflow 1.x 2.x (2.0, 2.1, etc..) ,则使用这些函数结果错误。

因此,为社区的利益,如果我们从1.x to 2.x迁移1.x to 2.x ,则为所有功能指定2.0兼容的调用。

1.x中的功能

  1. tf.nn.softmax
  2. tf.nn.softmax_cross_entropy_with_logits
  3. tf.nn.sparse_softmax_cross_entropy_with_logits

从1.x迁移到2.x的相应功能

  1. tf.compat.v2.nn.softmax
  2. tf.compat.v2.nn.softmax_cross_entropy_with_logits
  3. tf.compat.v2.nn.sparse_softmax_cross_entropy_with_logits

有关从1.x迁移到2.x的更多信息,请参阅此迁移指南

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号