Tensorflow 什么是登录?softmax和softmax\u cross\u entropy\u与\u logits之间的区别是什么?

Tensorflow 什么是登录?softmax和softmax\u cross\u entropy\u与\u logits之间的区别是什么?,tensorflow,Tensorflow,在中,他们使用一个名为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做什

在中,他们使用一个名为
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做什么,但另一个不知道。举个例子会很有帮助。

Logits仅仅意味着函数在早期层的无标度输出上运行,并且理解单位的相对标度是线性的。这特别意味着,输入的总和可能不等于1,值不是概率(您可能有一个5的输入)


tf.nn.softmax
只生成将应用于输入张量的结果。softmax“挤压”输入,以便
总和(输入)=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\u cross\u entropy\u with\u logits
在应用softmax函数后计算结果的交叉熵(但它在数学上更加谨慎)。这与以下结果相似:

sm = tf.nn.softmax(x)
ce = cross_entropy(sm)
交叉熵是一个汇总指标:它跨元素求和。
tf.nn.softmax\u cross\u entropy\u在形状
[2,5]
张量上的输出是形状
[2,1]
(第一个维度被视为批次)

如果您想进行优化以最小化交叉熵和在最后一层之后进行的软最大化,您应该使用
tf.nn.softmax\u cross\u entropy\u with_logits
,而不是自己进行优化,因为它以数学上正确的方式覆盖了数值不稳定的拐角情况。否则,你将通过在这里和那里添加小ε来破解它

2016-02-07编辑:
如果你有一个类标签,其中一个对象只能属于一个类,你现在可以考虑使用<代码> TF.NN.SPARSEIOSFTOMXORXIONIGPYPYXY LogLogs<代码>,这样你就不必将标签转换成稠密的一个热数组。此函数是在0.6.0版之后添加的。

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

tf.nn.softmax\u cross\u entropy\u with\u logits
计算softmax层的成本。仅在培训期间使用


Logit是模型输出的非标准化日志概率(对其应用softmax标准化之前输出的值)。

简短版本:

假设您有两个张量,
y\u hat
包含每个类的计算分数(例如,从y=W*x+b),并且
y\u 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\u cross\u entropy\u with_logits()
计算的总交叉熵损失:

长版本:

在神经网络的输出层,您可能会计算一个数组,其中包含每个训练实例的类分数,例如从计算
y\u 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函数,该函数将输入解释为非规范化的对数概率(akalogits),并输出规范化的线性概率

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\u true
一个热数组,其中培训实例1的真标签是“Class 2”,培训实例2的真标签是“Class 3”

y\u hat\u softmax中的概率分布是否接近
y\u中的概率分布为真?我们可以用它来测量误差

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

我们真正想要的是什么
                      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
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.]])
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
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
-tf.reduce_sum(y_true * tf.log(logits))