如何理解深度学习源码里经常出现的logits?

tensorflow/tensorflow
关注者
303
被浏览
476,878

19 个回答

logit原本是一个函数,它是sigmoid函数(也叫标准logistic函数) p(x)=11+exp (x) = \frac{1}{1+e^{-x}} 的反函数: logit(p)=log(p1p)logit(p) = \log\left(\frac{p}{1-p}\right) 。logit这个名字的来源即为logistic unit。

但在深度学习中,logits就是最终的全连接层的输出,而非其本意。通常神经网络中都是先有logits,而后通过sigmoid函数或者softmax函数得到概率 pp 的,所以大部分情况下都无需用到logit函数的表达式。

什么时候我们会真的需要用到logit函数呢?考虑这样一个问题:如果我们拿到了一个黑盒模型的概率输出,想要用这个模型生成一批数据来distill我们自己的模型,但distill过程往往又需要调节温度项来重新计算概率(大概是这么个形式: p(x)=11+ex/Tp(x) = \frac{1}{1+e^{-x/T}} ),此时我们就需要从概率值反推logits了,而反推的过程就如上边的公式所述: logit(p)=log(p1p)logit(p) = \log\left(\frac{p}{1-p}\right) 。所以对于logistic regression来说,logit恰好是输出概率经过logit函数的结果,因此即使我们并没有真正地用到logit函数,也不妨将其称作logit。

但是,目前大家用得更多的是多分类的softmax函数,而它的反函数其实并不是logit函数,而是log函数 log(p)\log(p) ,这样再次经过softmax函数: p^i=elogpijelogpj=pijpj=pi\hat{p}_i =\frac{e^{\log p_i}}{\sum_j e^{\log p_j}} = \frac{p_i}{\sum_j p_j} = p_i ,就得到了原来的概率。这里需要注意的是:所有logits共同减去一个数字,其得到的softmax结果是不变的,所以得到的logits并不一定与原始logits一模一样,而是会相差一个常数。

由此可见,使用logit一词来表示网络最后一层的输出,实际上只适用于logistic regression。而对于现在更多使用的多分类器softmax来说,其反函数应该是log函数,而非logit,继续用logit一词实际上是不恰当的。我个人倾向于使用“分数”或者直接说是最后一个全连接层的输出,这样比较形象,也不至于让初学者摸不到头脑。

参考资料:

维基百科:en.wikipedia.org/wiki/L

补充更细:

也可以这么理解: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就是不必担心值在0和1之间、各种情况相加等于一,但是又可以被容易地转换成那种格式的表示概率的值。

以上说的都不错,一言以蔽之:

深度学习源码中经常出现的logits其实和统计中定义的logit=log(p/1-p)没什么太大关系,就是定义的神经网络的一层输出结果。该输出一般会再接一个softmax layer输出normalize 后的概率,用于多分类。见下图:


Ref:

What is the meaning of the word logits in TensorFlow?

tensorflow.org/tutorial

logtis可以看作神经网络输出的未经过归一化的概率,所以将其结果用于分类任务计算loss时,如求cross_entropy的loss函数会设置from_logits参数。

因此,当from_logtis=False(默认情况)时,可以理解为输入的y_pre不是来自logtis,那么它就是已经经过softmax或者sigmoid归一化后的结果了;当from_logtis=True时,则可以理解为输入的y_pre是logits,那么需要对它进行softmax或者sigmoid处理再计算cross entropy。

如下面的两种方式计算得到的loss都是一样的:

y_pre = np.array([[5, 5], [2, 8]], dtype=np.float)   # 神经网络的输出,未概率归一化
y_true = np.array([[1, 0], [0, 1]], dtype=np.float)
loss = tf.losses.binary_crossentropy(y_true=y_true, y_pred=y_pre, from_logits=True)
print(loss)

y_pre = tf.nn.sigmoid(y_pre)
loss = tf.losses.binary_crossentropy(y_true=y_true, y_pred=y_pre, from_logits=False)
print(loss)