什么是logits?softmax和softmax_cross_entropy_with_logits有什么区别?
- 2025-01-17 09:22:00
- admin 原创
- 12
问题描述:
在tensorflow API 文档中,他们使用了一个关键字logits
。它是什么?许多方法的写法如下:
tf.nn.softmax(logits, name=None)
如果logits
只是一个通用Tensor
输入,为什么它被命名为logits
?
其次,下面两种方法有什么区别?
tf.nn.softmax(logits, name=None)
tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)
我知道哪个tf.nn.softmax
是有效的,但不知道其他的。举个例子会很有帮助。
解决方案 1:
softmax+logits 只是意味着该函数对前面层的未缩放输出进行操作,并且理解单位的相对比例是线性的。它特别意味着输入的总和可能不等于 1,值不是概率(您的输入可能是 5)。在内部,它首先将 softmax 应用于未缩放的输出,然后计算这些值的交叉熵与标签定义的“应该”值。
tf.nn.softmax
产生将softmax 函数应用于输入张量的结果。softmax 将输入“压缩”为sum(input) = 1
,并且通过将输入解释为对数概率 (logits) 进行映射,然后将其转换回 0 到 1 之间的原始概率。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]]
有关为什么 softmax 在 DNN 中被广泛使用的更多信息,请参阅此答案。
tf.nn.softmax_cross_entropy_with_logits
将 softmax 步骤与应用 softmax 函数后计算交叉熵损失相结合,但它以更数学上谨慎的方式完成所有操作。它类似于以下结果:
sm = tf.nn.softmax(x)
ce = cross_entropy(sm)
交叉熵是一个总结指标:它对所有元素求和。tf.nn.softmax_cross_entropy_with_logits
形状[2,5]
张量的输出为形状[2,1]
(第一维被视为批次)。
如果您想要进行优化以最小化交叉熵,并且在最后一层之后进行 softmax 处理,则应使用tf.nn.softmax_cross_entropy_with_logits
而不是自己进行优化,因为它以数学上正确的方式涵盖了数值不稳定的极端情况。否则,您最终会通过在这里和那里添加小的 epsilon 来破解它。
编辑于 2016-02-07:
如果您有单类标签,即一个对象只能属于一个类,您现在可以考虑使用,tf.nn.sparse_softmax_cross_entropy_with_logits
这样您就不必将标签转换为密集的独热数组。此功能在 0.6.0 版后添加。
解决方案 2:
简短版本:
假设您有两个张量,其中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
如果将 中的分数解释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 函数,该函数将输入解释为未归一化的对数概率(又名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 的真实标签是“类别 2”,训练实例 2 的真实标签是“类别 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 类”,这与训练实例 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])
我们真正想要的是所有训练实例的总损失。因此我们可以计算:
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_1
和total_loss_2
产生的结果基本相同,只是最后几位数字略有不同。不过,您不妨使用第二种方法:它少用一行代码,累积的数值误差也更少,因为 softmax 是在 内部为您完成的softmax_cross_entropy_with_logits()
。
解决方案 3:
tf.nn.softmax
通过 softmax 层计算前向传播。在评估模型时,计算模型输出的概率时会用到它。
tf.nn.softmax_cross_entropy_with_logits
计算 softmax 层的成本。它仅在训练期间使用。
logits 是模型输出的非标准化对数概率(在应用 softmax 标准化之前输出的值)。
解决方案 4:
学期数学动机
当我们希望将输出限制在 0 和 1 之间,但我们的模型架构输出不受约束的值时,我们可以添加一个规范化层来强制执行这一点。
常见的选择是S 型函数。1在二分类中,这通常是逻辑函数,在多类任务中则是多项逻辑函数(又名softmax)。2
如果我们想将新最后一层的输出解释为“概率”,那么(根据含义)我们的 sigmoid 的无约束输入必须是inverse-sigmoid
(概率)。在逻辑情况下,这相当于我们概率的对数几率(即几率的对数),又名logit:
softmax
这就是为什么在 Tensorflow 中调用 的参数的原因logits
——因为假设softmax
是模型中的最后一层,并且输出p被解释为概率,则该层的输入x可以解释为逻辑回归:
在此处输入图片描述 | 在此处输入图片描述 |
---|
通用术语
在机器学习中,人们倾向于将从数学/统计/计算机科学中借用的术语进行概括,因此在 Tensorflow 中logit
(通过类比)被用作许多规范化函数输入的同义词。
虽然它具有易于区分和前面提到的概率解释等优良特性,但它有点任意。
softmax
可能更准确地称为软arg max,因为它是argmax 函数的平滑近似。
解决方案 5:
以上答案对于所提出的问题有足够的描述。
此外,Tensorflow 还优化了应用激活函数然后使用其自身的激活函数计算成本的操作,然后使用成本函数。因此,使用tf.nn.softmax_cross_entropy()
以下方法是一种很好的做法:tf.nn.softmax(); tf.nn.cross_entropy()
你可以在资源密集型模型中发现它们之间的显著差异。
解决方案 6:
Tensorflow 2.0 兼容答案dga
:对stackoverflowuser2010
Logits 及其相关功能的解释非常详细。
所有这些函数在中使用时都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 中的功能:
tf.nn.softmax
tf.nn.softmax_cross_entropy_with_logits
tf.nn.sparse_softmax_cross_entropy_with_logits
从 1.x 迁移到 2.x 时的相应功能:
tf.compat.v2.nn.softmax
tf.compat.v2.nn.softmax_cross_entropy_with_logits
tf.compat.v2.nn.sparse_softmax_cross_entropy_with_logits
有关从 1.x 迁移到 2.x 的更多信息,请参阅此迁移指南。
解决方案 7:
Logits 是神经网络的非规范化输出。Softmax 是一种规范化函数,它压缩神经网络的输出,使它们全部介于 0 和 1 之间,并且总和为 1。Softmax_cross_entropy_with_logits 是一种损失函数,它接收神经网络的输出(经过 softmax 压缩后)和这些输出的真实标签,并返回损失值。
解决方案 8:
还有一件事我一定要强调,因为 logit 只是一个原始输出,通常是最后一层的输出。这也可以是负值。如果我们使用它,就像下面提到的“交叉熵”评估一样:
-tf.reduce_sum(y_true * tf.log(logits))
那么它就行不通了。因为 -ve 的对数没有定义。因此使用 o softmax 激活将克服这个问题。
解决方案 9:
简短回答:在统计学用法中,与概率 $p \in [0, 1]$ 对应的“logit”通常是指对数概率$\logit(p) = \log(p/(1-p))$。在机器学习用法中,“logit”通常是对数概率$\logit(p) = \log(p)$。
是的,这种不一致的用法非常令人困惑和烦人。
更准确地说,在机器学习环境中,我们使用温度为 $T = 1$ 的softmax 函数,logits向量$z$ 由 $z_i = \log(p_i) + C$ 给出,其中 $p_i$ 是给定数量 $i$ 的概率,任意实数常数 $C$ 在所有 $i$ 中都是相同的(因此 logits 向量是从对数概率向量的常数偏移)。很容易证明,如果我们将这个向量 $z$ 插入 softmax 函数,那么我们就会得到概率 $p_i$。softmax 公式分母的标准化导致常数偏移 $C$ 抵消。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)