• 正确理解TensorFlow中的logits


    softmax是在一个n分类问题中,输入一个n维的logits向量,输出一个n维概率向量,其物理意义是logits代表的物体属于各类的概率。即softmax的输出是一个n维的one_hot_prediction。
    softmax_cross_entropy_with_logits输出的是一个batch_size维的向量,这个向量的每一维表示每一个sample的one_hot_label和one_hot_prediction 之间的交叉熵。
    softmax_cross_entropy的输出是前述batch_size维的向量的均值。

    总结观点:

    logits与 softmax都属于在输出层的内容,

    logits = tf.matmul(X, W) + bias

    再对logits做归一化处理,就用到了softmax:

    Y_pred = tf.nn.softmax(logits,name='Y_pred')

    ——————————————————————

    Unscaled log probabilities of shape [d_0, d_1, ..., d_{r-1}, num_classes] and dtype float32 or float64.

    可以理解logits ——【batchsize,class_num】是未进入softmax的概率,一般是全连接层的输出,softmax的输入

    注,一般将没有加激活函数的称为Logits,加了softmax后称为Probabilities,经过softmax后,有把最大值放大的过程,相当于把强的变得更强,把弱的变得更弱。

    我正想通过tensorflow API文档在这里。在tensorflow文档中,他们使用了一个叫做关键字logits。它是什么?API文档中的很多方法都是这样写的

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

    如果写的是logits只有这些Tensors,为什么要保留一个不同的名字logits?

    另一件事是有两种方法我不能区分。他们是

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

    他们之间有什么不同?文档对我不明确。我知道是什么tf.nn.softmax。但不是其他。一个例子会非常有用。

    假设您有两个张量,其中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×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_trueone-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_true?我们可以使用交叉熵损失来衡量错误。

    Formula for cross-entropy loss

    我们可以逐行计算交叉熵损失并查看结果。下面我们可以看到,训练实例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

    我们可以用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()。


    参考:https://www.jianshu.com/p/6c9b0cc6978b

  • 相关阅读:
    洛谷 P2678 跳石头
    洛谷 P1145 约瑟夫
    LibreOJ #515. 「LibreOJ β Round #2」贪心只能过样例
    洛谷 P2966 [USACO09DEC]牛收费路径Cow Toll Paths
    网络编程 --- TCP
    进程
    并发编程
    网络编程 --- UDP
    网络编程
    面向对象编程 --- 反射
  • 原文地址:https://www.cnblogs.com/wynlfd/p/14097568.html
Copyright © 2020-2023  润新知