深度学习中的 logits 、softmax,TensorFlow中的 tf.nn.softmax_cross_entropy_with_logits 、tf.nn.sparse_soft...对比

一、logits 和 softmax

补充

最前加一句,不知道对不对,以后再回来验证(2019/8/27):(在神经网络编写代码过程中,logits 并不是专指经过logit(p/1-p)函数处理过的输出。现在假设有神经网络进行分类,类别数目为m,输出为y1,做一个映射使得y1与类别的维度相同,y1 --> y2,再把 y2 作为softmax输入值 得到各个类别的概率,这里的y2被叫做logits。也就是softmax的与类别维度相同的输入都可以被叫做 logits ?)

接上,前面的想法是对的(2019/8/28):
在其他文章看到这个解释:
logits: 未归一化的概率, 一般也就是 softmax层的输入。所以logits和lables的shape一样
也可以做为sigmoid的输入
在这里插入图片描述

正文开始

1、什么是logits?

logit(A) 函数被称A事件发生的对数几率。

说到Logits,首先要弄明白什么是Odds?

在英文里,Odds的本意是指几率、可能性。它和我们常说的概率又有什么区别呢?

在统计学里,概率(Probability)描述的是某事件A出现的次数与所有事件出现的次数之比:

p ( A ) = A 发 生 的 次 数 所 有 事 件 发 生 的 总 次 数                  ( 公 式 1 ) p_{(A)}=\frac{A发生的次数}{所有事件发生的总次数} ~~~~~~~~~~~~~~~~(公式1) p(A)=A                1

很显然,概率 P是一个介于0到1之间的实数; P=0,表示事件A一定不会发生,而P=1,则表示事件A一定会发生。

以掷骰子为例,由于骰子为6面,任意一面上点数概率都是相同。所以,事件A:掷出点数为1的概率为:

p = 1 6 p=\frac{1}{6} p=61

对比而言,Odds指的是事件发生的概率与事件不发生的概率之比:

O d d s ( A ) = p ( A 发 生 ) p ( A 不 发 生 )                         ( 公 式 2 ) Odds_{(A)}=\frac{p_{(A发生)}}{p_{(A不发生)}}~~~~~~~~~~~~~~~~~~~~~~~(公式2) Odds(A)=p(A)p(A)                       2

还拿掷骰子的例子说事,掷出点数为1的Odds为:

O d d s ( A ) = 1 / 6 5 / 6 Odds(A)=\frac{1/6}{5/6} Odds(A)=5/61/6

很明显,Odds和概率之间的关系为:

O d d s ( A ) = p 1 − p Odds(A)=\frac{p}{1-p} Odds(A)=1pp

进一步简化可知,

O d d s ( A ) = 发 生 事 件 A 次 数 其 他 事 件 的 次 数 ( 即 不 发 生 A 的 次 数 )                ( 公 式 3 ) Odds(A)= \frac{发生事件A次数 } {其他事件的次数(即不发生A的次数)}~~~~~~~~~~~~~~ (公式3) OddsA=AA              (3

换句话说,事件A的Odds 等于 事件A出现的次数 和 其它(非A)事件出现的次数 之比;

相比之下,事件A的概率 等于 事件A出现的次数 与 所有事件的次数 之比。

很容易推导得知:

概率P(A)和Odds(A)的值域是不同的。前者被锁定在[0,1]之间,而后者则是 [ 0 , + ∞ ] [0,+\infty] [0,+] .

这说了半天,有何logit有什么关系呢?

注意Logit一词的分解,对它(it)Log(取对数),这里“it”就是Odds。下面我们就可以给出Logit的定义了:

l o g i t ( O d d s ) = l o g ( p 1 − p )                               ( 公 式 4 ) logit(Odds)=log(\frac{p}{1-p})~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(公式4) logit(Odds)=log(1pp)                             (4

公式4实际上就是所谓Logit变换。

补充: logit 函数在逻辑回归中也有用到(19/8/27):
逻辑回归模型
p ( y = 1 ∣ x ) = e x p ( w ⋅ x ) 1 + e x p ( w ⋅ x ) p(y=1|x)=\frac{exp^{(w\cdot x)}}{1+exp^{(w\cdot x)}} p(y=1x)=1+exp(wx)exp(wx)
p ( y = 0 ∣ x ) = 1 1 + e x p ( w ⋅ x ) p(y=0|x)=\frac{1}{1+exp^{(w\cdot x)}} p(y=0x)=1+exp(wx)1
这里为了方便表示,对 w 和 x 进行了扩充, w = ( w 1 , w 2 , w 3 . . . . b ) T w=(w^1,w^2,w^3....b)^T w=(w1,w2,w3....b)T,    x = ( x 1 , x 2 , x 3 . . . . . 1 ) T ~~x=(x^1,x^2,x^3.....1)^T   x=(x1,x2,x3.....1)T

对其应用 logit 函数变换 ,
l o g i t ( p y = 1 ) = l o g p ( y = 1 ∣ x ) p ( y = 0 ∣ x ) = l o g e x p ( w ⋅ x ) 1 + e x p ( w ⋅ x ) 1 1 + e x p ( w ⋅ x ) = w ⋅ x logit(p_{y=1})=log\frac{p(y=1|x)}{p(y=0|x)}=log\frac{\frac{exp^{(w\cdot x)}}{1+exp^{(w\cdot x)}}}{\frac{1}{1+exp^{(w\cdot x)}}}=w\cdot x logit(py=1)=logp(y=0x)p(y=1x)=log1+exp(wx)11+exp(wx)exp(wx)=wx

这就是说,在逻辑斯蒂回归中,输出 y = 1 y=1 y=1的对数几率是 x 的线性函数。

2、Logit变换的意义在哪里

与概率不同的地方在于,Logit的一个很重要的特性,就是它没有上下限,如图1所示。

在这里插入图片描述
通过变换,Logit的值域没有上下界限,这就给建模提供了方便。

想象这么一个场景,我们想研究某个事件A发送的概率P,P值的大小和某些因素相关,例如研究有毒药物的使用剂量大小(x)和被测小白鼠的死亡率(P)之间的关系。

很显然,死亡率P和x是正相关的,但由于P的值域在[0,1]之间,而x的取值范围要宽广得多。P不太可能是x的线性关系或二次函数,一般的多项式函数也不太适合,这就给此类函数的拟合(回归分析)带来麻烦。

此外,当P接近于0或1的时候,即使一些因素变化很大,P的值也不会有显著变化。

例如,对于高可靠系统,可靠度P已经是0.997了,倘若在改善条件、提高工艺和改进体系结构,可靠度的提升只能是小数点后后三位甚至后四位,单纯靠P来度量,已经让我们无所适从,不知道改善条件、提高工艺和改进体系结构到底有多大作用。

再比如,宏观来看,灾难性天气发送的概率P非常低(接近于0),但这类事件类似于黑天鹅事件(特征为:影响重大、难以预测及事后可解释),由于P对接近于0的事件不敏感,通过P来度量,很难找到刻画发生这类事件的前兆信息。

这时,Logit函数的优势就体现出来了。从图1可以看出,在P=0或P=1附近,Logit非常敏感(值域变化非常大)。通过Logit变换,P从0到1变化时,Logit是从到。Logit值域的不受限,让回归拟合变得容易了!

通常,Logit对数的底是自然对象e,这里我们把Odds用符号 θ \theta θ表示,则有:

θ = l n p 1 − p                           ( 公 式 5 ) \theta=ln\frac{p}{1-p}~~~~~~~~~~~~~~~~~~~~~~~~~(公式5) θ=ln1pp                         (5)

显然,知道 θ \theta θ后,我们可以推导出概率:

p = e θ 1 + e θ                              ( 公 式 6 ) p=\frac{e^\theta}{1+e^\theta}~~~~~~~~~~~~~~~~~~~~~~~~~~~~(公式6) p=1+eθeθ                            (6)

通常,我们先借助Logit变换,让我们方便拟合数据(即逻辑回归),然后再变换回我们熟悉的概率。就是这么一个循环,为数据分析提供了便利。
如果我们在把公式(6)做一下变形,如分子和分母同乘以 ,可得到公式(7):

p = e θ ⋅ e − θ e − θ ⋅ ( 1 + e θ ) = 1 1 + e − θ                 ( 公 式 7 ) p=\frac{e^\theta\cdot e^{-\theta}}{e^{-\theta}{\cdot}(1+e^\theta)}=\frac{1}{1+e^{-\theta}}~~~~~~~~~~~~~~~(公式7) p=eθ(1+eθ)eθeθ=1+eθ1               (7)

如果你认真观察的话,就会发现,它其实就是在神经网络种广泛使用的Sigmoid函数,又称对数几率函数(logistic function)。

通常,我们把公式(5)表示的 便于拟合的“概率替代物” 称为logits。事实上,在多分类(如手写识别等)中,某种分类器的输出(即分类的打分),也称为logits,即使它和Odds的本意并没有多大联系,但它们通过某种变换,也能变成“概率模型”,比如下面我们即将讲到的Softmax变换。

3、softmax函数

由于logis本身并不是一个概率,所以我们需要把logist的值变化成“概率模样”。这时Softmax函数该出场了。Softmax把一个系列的概率替代物(logits)从[-inf, +inf] 映射到[0,1]。除此之外,Softmax还保证把所有参与映射的值累计之和等于1,变成诸如[0.95, 0.05, 0]的概率向量。这样一来,经过Softmax加工的数据可以当做概率来用(如图2所示)。
在这里插入图片描述
经过softmax的加工,就变成“归一化”的概率(设为p1),这个新生成的概率p1,和labels所代表的概率分布(设为p2)一起作为参数,用来计算交叉熵。

这个差异信息,作为我们网络调参的依据,理想情况下,这两个分布尽量趋近最好。如果有差异(也可以理解为误差信号),我们就调整参数,让其变得更小,这就是损失(误差)函数的作用。

二、TensorFlow中的 ①tf.nn.softmax_cross_entropy_with_logits 、②tf.nn.sparse_softmax_entropy_with_logits对比

两个函数参数一样,不同的是tf.nn.softmax_cross_entropy_with_logits 的 labels 参数输入的是概率形式
(_sentinel=None, labels=None, logits=None, dim=-1, name=None)
Computes softmax cross entropy between logits and labels

  1. 这个操作的输入logits是未经缩放的,该操作内部会对logits使用softmax操作
  2. 参数labels,logits必须有相同的形状 [batch_size, num_classes] 和相同的类型(float16, float32, float64)中的一种
    参数:_sentinel: 一般不使用
    labels: labels的每一行labels[i]必须为一个概率分布
    logits: 未缩放的对数概率
    dims: 类的维度,默认-1,也就是最后一维
    name: 该操作的名称
    返回值:长度为batch_size的一维Tensor

函数的功能就是计算labels和logits之间的交叉熵(cross entropy)。

第一个参数基本不用。此处不说明。
第二个参数label的含义就是一个分类标签,所不同的是,这个label在①中是分类的概率,比如说[0.2,0.3,0.5],labels的每一行必须是一个概率分布(即概率之合加起来为1)。

现在来说明第三个参数logits,logit的值域范围[-inf,+inf](即正负无穷区间)。我们可以把logist理解为原生态的、未经缩放的,可视为一种未归一化的l“概率替代物”,如[4, 1, -2]。它可以是其他分类器(如逻辑回归等、SVM等)的输出。

例如,上述向量中“4”的值最大,因此,属于第1类的概率最大,“1”的值次之,所以属于第2类的概率次之。

交叉熵(Cross Entropy是Shannon信息论中一个重要概念,主要用于度量两个概率分布间的差异性信息。

下面用个小例子来看看这两个函数的用法

TensorFlow2.0


# tf.nn.sparse_softmax_entropy_with_logits()

# 词汇表大小为3,语料包含两个单词【2,0】
word_labels=tf.constant([2,0])  # 数值
predict_logit=tf.constant([[2.0,-1.0,3.0],[1.0,0.0,-.5]])
loss=tf.nn.sparse_softmax_cross_entropy_with_logits(labels=word_labels,logits=predict_logit)
loss

# <tf.Tensor: id=15, shape=(2,), dtype=float32, numpy=array([0.32656264, 0.4643688 ], dtype=float32)>


# tf.nn.softmax_cross_entropy_with_logits

word_prob_distribution=tf.constant([[0,0,1],[1,0,0]],dtype=tf.float32) # 概率
loss=tf.nn.softmax_cross_entropy_with_logits(labels=word_prob_distribution,logits=tf.nn.softmax(predict_logit))
loss

# <tf.Tensor: id=86, shape=(2,), dtype=float32, numpy=array([0.7544037, 0.8267176], dtype=float32)>

与前面函数相似的还有 tf.nn.sigmoid_cross_entropy_with_logits

  • 39
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Systemd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值