softmax和softmax_cross_entropy_with_logits有什么区别?
我正在浏览tensorflow API文档。 在tensorflow文档中,他们使用了一个名为logits
的关键字。 它是什么? 在API文档中的很多方法都是这样写的
tf.nn.softmax(logits, name=None)
如果写的是那些logits
只是logits
,为什么保留一个不同的名字像logits
?
另一件事是有两种方法我不能区分。 他们是
tf.nn.softmax(logits, name=None) tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)
他们之间有什么区别? 文件不清楚。 我知道什么是tf.nn.softmax
。 但不是其他。 一个例子将是非常有帮助的。
Logits仅仅意味着该函数对早期图层的未缩放输出进行操作,并且了解单位的相对比例是线性的。 这意味着,特别是,input的总和可能不等于1,这些值不是概率(你可能有一个input5)。
tf.nn.softmax
只产生将softmax函数应用于input张量的结果。 softmax“挤压”input,使sum(input)= 1; 这是一种正常化的方式。 softmax输出的形状与input相同 – 只是将值标准化。 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函数之后计算结果的交叉熵(但是它以更仔细的math方式整合在一起)。 这与以下结果类似:
sm = tf.nn.softmax(x) ce = cross_entropy(sm)
交叉熵是一个汇总度量标准 – 它将元素相加。 形状[2,5]
张量上的tf.nn.softmax_cross_entropy_with_logits
的输出形状为[2,1]
(第一维被视为批处理)。
如果要进行优化以尽量减less交叉熵,并且在最后一层之后软起来,则应该使用tf.nn.softmax_cross_entropy_with_logits
而不是自己做,因为它以math方式覆盖数值不稳定的边angular情况。 否则,你会最终通过在这里和那里添加小的epsilon来入侵它。
(已编辑2016-02-07:如果您有单类标签,对象只能属于一个类,那么现在可以考虑使用tf.nn.sparse_softmax_cross_entropy_with_logits
以便您不必将标签转换为稠密一个热门的数组,这个函数是在0.6.0版本之后添加的。)
简短版本:
假设有两个张量,其中y_hat
包含每个类的计算得分(例如,从y = W * x + b), y_true
包含单热编码的真实标签。
y_hat = ... # Predicted label, eg y = tf.matmul(X, W) + b y_true = ... # True label, one-hot encoded
如果你将y_hat
的分数解释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))
长版本:
在你的neural network的输出层中,你可能会计算一个包含你的训练实例的类别分数的数组,例如从一个计算y_hat = W*x + b
。 作为一个例子,下面我创build了一个y_hat
作为2 x 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函数,将input解释为非归一化的对数概率(又称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
数组,其中行又是训练实例,列是类。 下面我创build了一个示例y_true
one-hot数组,其中训练实例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_hat_softmax
接近y_hat_softmax
中的概率分布? 我们可以使用交叉熵损失来衡量错误。
我们可以逐行计算交叉熵损失并查看结果。 下面我们可以看到,训练样例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_1
和total_loss_2
产生基本相同的结果,而在最后的数字中会有一些小的差异。 但是,您也可以使用第二种方法:由于softmax_cross_entropy_with_logits()
的softmax是为您完成的,因此它只需要less一行代码并累积更less的数字错误。
tf.nn.softmax
计算通过softmax层的前向传播。 在计算模型输出的概率时,可以在评估模型时使用它。
tf.nn.softmax_cross_entropy_with_logits
计算softmax图层的成本。 它只在训练中使用 。
logit是输出模型的非标准化的对数概率 (在将softmax标准化应用于它们之前输出的值)。
以上答案对于所提问题有足够的描述。
除此之外,Tensorflow已经优化了应用激活function的操作,然后使用自己的激活和成本函数来计算成本。 因此,使用: tf.nn.softmax_cross_entropy()
over tf.nn.softmax(); tf.nn.cross_entropy()
是一个好习惯tf.nn.softmax(); tf.nn.cross_entropy()
tf.nn.softmax(); tf.nn.cross_entropy()
您可以在资源密集型模式中find它们之间的显着差异。