什么是logits,softmax和softmax_cross_entropy_with_logits?

Shu*_*his 328 python machine-learning tensorflow

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

tf.nn.softmax(logits, name=None)
Run Code Online (Sandbox Code Playgroud)

如果写的是什么是那些logitsTensors,为什么保持一个不同的名称,如logits

另一件事是我有两种方法无法区分.他们是

tf.nn.softmax(logits, name=None)
tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)
Run Code Online (Sandbox Code Playgroud)

它们之间有什么区别?这些文档对我来说并不清楚.我知道是什么tf.nn.softmax呢.但不是另一个.一个例子将非常有用.

dga*_*dga 401

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]]
Run Code Online (Sandbox Code Playgroud)

相反,tf.nn.softmax_cross_entropy_with_logits在应用softmax函数之后计算结果的交叉熵(但它以更加数学上仔细的方式一起完成).它类似于以下结果:

sm = tf.nn.softmax(x)
ce = cross_entropy(sm)
Run Code Online (Sandbox Code Playgroud)

交叉熵是一个汇总度量:它对元素进行求和.tf.nn.softmax_cross_entropy_with_logits形状[2,5]张量的输出具有形状[2,1](第一维被视为批次).

如果你想要做的优化,以尽量减少交叉熵你的最后一层后softmaxing,你应该使用tf.nn.softmax_cross_entropy_with_logits的,而不是自己做的,因为它涵盖了数值不稳定的极端情况在数学上正确的方式.否则,你最终会通过在这里和那里添加小ε来破解它.

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

  • 你的第一行是双倍软化.softmax_cross_entropy_with_logits期望未缩放的logits,而不是tf.nn.softmax的输出.你只需要`tf.nn.softmax_cross_entropy_with_logits(tf.add(tf.matmul(x,W,b))`. (14认同)
  • @dga我认为你的代码中有一个拼写错误,`b`需要在括号之外,`tf.nn.softmax_cross_entropy_with_logits(tf.add(tf.matmul(x,W),b)` (6认同)
  • Upvoted-但是当你说"softmax的输出形状与输入相同时,你的答案稍微不正确 - 它只是将值标准化".Softmax不只是"挤压"这些值,使它们的总和等于1.它还重新分配它们,这可能是它被使用的主要原因.请参阅/sf/ask/1203125521/,尤其是Piotr Czapla的答案. (4认同)
  • “理解单位的相对比例是线性的”是什么意思。你第一句话的一部分是什么意思? (2认同)

sta*_*010 266

精简版:

假设您有两个张量,其中y_hat包含每个类的计算得分(例如,从y = W*x + b)并y_true包含一个热编码的真实标签.

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

如果将分数解释为非y_hat标准化的日志概率,则它们是对.

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

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

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

total_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))
Run Code Online (Sandbox Code Playgroud)

长版:

在神经网络的输出层中,您可能会计算一个数组,其中包含每个训练实例的类别分数,例如计算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]])
Run Code Online (Sandbox Code Playgroud)

请注意,值未规范化(即行不加1).为了对它们进行归一化,我们可以应用softmax函数,该函数将输入解释为非标准化日志概率(也称为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]])
Run Code Online (Sandbox Code Playgroud)

完全理解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
Run Code Online (Sandbox Code Playgroud)

所以现在我们有每个训练实例的类概率,我们可以采用每行的argmax()来生成最终的分类.从上面,我们可以生成训练实例1属于"Class 2"并且训练实例2属于"Class 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.]])
Run Code Online (Sandbox Code Playgroud)

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

交叉熵损失公式

我们可以逐行计算交叉熵损失并查看结果.下面我们可以看到训练实例1的损失为0.479,而训练实例2的损失则高达1.200.这个结果是有道理的,因为在上面的例子中,y_hat_softmax表明训练实例1的最高概率是"Class 2",它匹配训练实例1 y_true; 然而,训练实例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])
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

请注意total_loss_1total_loss_2产生基本相同的结果,最后的数字有一些小的差异.但是,您也可以使用第二种方法:它需要少一行代码并积累较少的数值误差,因为softmax是为您完成的softmax_cross_entropy_with_logits().


Ian*_*low 48

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

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

logits是输出模型的非标准化日志概率(在softmax标准化应用于它们之前输出的值).

  • @auro因为它在交叉熵计算期间对值(内部)进行了规范化.'tf.nn.softmax_cross_entropy_with_logits`的要点是评估模型偏离金标签的程度,而不是提供标准化输出. (7认同)
  • 我知道了.为什么不调用函数tf.nn.softmax_cross_entropy_sans_normalization? (2认同)
  • @SerialDev,不可能从tf.nn.sparse_softmax_cross_entropy_with_logits中获取概率。要获取概率,请使用“ tf.nn.softmax”。 (2认同)

uke*_*emi 16

术语的数学动机

当我们希望将输出限制在 0 到 1 之间,但我们的模型架构输出不受约束的值时,我们可以添加一个归一化层来强制执行此操作。

常见的选择是sigmoid函数。1在二元分类中,这通常是逻辑函数,在多类任务中,这通常是多项逻辑函数(又名softmax)。2

如果我们想将新的最终层的输出解释为“概率”,那么(暗示)我们的 sigmoid 的无约束输入必须是inverse-sigmoid(概率)。在逻辑案例中,这相当于我们概率的对数赔率(即赔率的对数),又名logit

softmax这就是为什么在 Tensorflow 中调用 的参数logits- 因为假设softmax是模型中的最后一层,并且输出p被解释为概率,则该层的输入x可解释为 logit:

在此输入图像描述 在此输入图像描述

广义术语

在机器学习中,倾向于概括从数学/统计/计算机科学中借用的术语,因此在 Tensorflow 中logit(通过类比)被用作许多标准化函数的输入的同义词。


  1. 虽然它具有良好的特性,例如易于微分,以及前面提到的概率解释,但它有点任意
  2. softmax可能更准确地称为 soft arg max,因为它是argmax 函数的平滑逼近


小智 5

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

除此之外,Tensorflow 优化了应用激活函数然后使用自己的激活和成本函数计算成本的操作。因此,它是一个很好的做法,使用:tf.nn.softmax_cross_entropy()tf.nn.softmax(); tf.nn.cross_entropy()

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

  • 上面的答案明明没看问题。。都说的都一样,都知道,但不回答问题本身 (2认同)

Ten*_*ort 5

Tensorflow 2.0 Compatible Answer : Logits 和相关函数的解释dgastackoverflowuser2010非常详细。

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

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

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 的更多信息,请参阅此迁移指南