tf.nn.softmax_cross_entropy_with_logits

tf.nn.softmax_cross_entropy_with_logits函數是TensorFlow中常用的求交叉熵的函數。其中函數名中的“logits”是個什麼意思呢?它時不時地困惑初學者,下面我們就討論一下。

1. 什麼是logits?
說到Logits,首先要弄明白什麼是Odds?

在英文裏,Odds的本意是指機率、可能性。它和我們常說的概率又有什麼區別呢?

在統計學裏,概率(Probability)描述的是某事件A出現的次數與所有事件出現的次數之比:

 

P(A) = 發生事件A的次數  /  所有事件的次數。     (公式1)

很顯然,概率 P是一個介於0到1之間的實數; P=0,表示事件A一定不會發生,而P=1,則表示事件A一定會發生。

以擲骰子爲例,由於骰子爲6面,任意一面上點數概率都是相同。所以,事件A:擲出點數爲1的概率爲:

對比而言,Odds指的是事件發生的概率與事件不發生的概率之比:

 

Odds(A)= 發生事件A的概率  /  不發生事件A的概率    (公式2)

 

還拿擲骰子的例子說事,擲出點數爲1的Odds爲:

 

很明顯,Odds和概率之間的關係爲:

進一步簡化可知,

  Odds(A)= 發生事件A次數 /  其他事件的次數(即不發生A的次數)   (公式3)

換句話說,事件A的Odds 等於 事件A出現的次數 和 其它(非A)事件出現的次數 之比;

相比之下,事件A的概率 等於 事件A出現的次數 與 所有事件的次數 之比。

很容易推導得知:

概率P(A)和Odds(A)的值域是不同的。前者被鎖定在[0,1]之間,而後者則是.

這說了半天,有何logit有什麼關係呢?

請注意Logit一詞的分解,對它(it)Log(取對數),這裏“it”就是Odds。下面我們就可以給出Logit的定義了:

     (公式4)

公式4實際上就是所謂Logit變換。

 

2.Logit變換的意義在哪裏
與概率不同的地方在於,Logit的一個很重要的特性,就是它沒有上下限,如圖1所示。

 

                                                圖1    Logit的示意圖

 

通過變換,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用符號表示,則有:

     (公式5)

顯然,知道後,我們也容易推導出概率的值來:

       (公式  6)

通常,我們先借助Logit變換,讓我們方便擬合數據(即邏輯迴歸),然後再變換回我們熟悉的概率。就是這麼一個循環,爲數據分析提供了便利。某種程度上,這類變換,非常類似於化學中的催化劑。

在化學反應裏,催化劑能改變反應物化學反應速率而不改變化學平衡,且本身的質量和化學性質在化學反應前後都沒有發生改變。

如果我們在把公式(6)做一下變形,如分子和分母同乘以 ,可得到公式(7):

      (公式7)

如果你認真觀察的話,就會發現,它其實就是在神經網絡種廣泛使用的Sigmoid函數,又稱對數機率函數(logistic function)。

通常,我們把公式(5)表示的便於擬合的“概率替代物”稱爲logits。事實上,在多分類(如手寫識別等)中,某種分類器的輸出(即分類的打分),也稱爲logits,即使它和Odds的本意並沒有多大聯繫,但它們通過某種變換,也能變成“概率模型”,比如下面我們即將講到的Softmax變換。

3. TensorFlow中的Softmax函數
再回到softmax函數的討論上。

tf.nn.softmax_cross_entropy_with_logits(
    _sentinel=None,
    labels=None,
    logits=None,
    dim=-1,
    name=None
)
這個函數的功能就是計算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信息論中一個重要概念,主要用於度量兩個概率分佈間的差異性信息。

由於logis本身並不是一個概率,所以我們需要把logist的值變化成“概率模樣”。這時Softmax函數該出場了。Softmax把一個系列的概率替代物(logits)從[-inf, +inf] 映射到[0,1]。除此之外,Softmax還保證把所有參與映射的值累計之和等於1,變成諸如[0.95, 0.05, 0]的概率向量。這樣一來,經過Softmax加工的數據可以當做概率來用(如圖2所示)。

經過softmax的加工,就變成“歸一化”的概率(設爲p1),這個新生成的概率p1,和labels所代表的概率分佈(設爲p2)一起作爲參數,用來計算交叉熵。

這個差異信息,作爲我們網絡調參的依據,理想情況下,這兩個分佈儘量趨近最好。如果有差異(也可以理解爲誤差信號),我們就調整參數,讓其變得更小,這就是損失(誤差)函數的作用。

最終通過不斷地調參,logit被鎖定在一個最佳值(所謂最佳,是指讓交叉熵最小,此時的網絡參數也是最優的)。softmax和交叉熵的工作流程如圖3所示

 

圖3 從Odds值到概率值(圖片來源:互聯網)

 

下面我們列舉一個案例說明:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu May 10 08:32:59 2018
@author: yhilly
"""
 
import tensorflow as tf
 
labels = [[0.2,0.3,0.5],
          [0.1,0.6,0.3]]
logits = [[4,1,-2],
          [0.1,1,3]]
 
logits_scaled = tf.nn.softmax(logits)
result = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits)
 
with tf.Session() as sess:
    print (sess.run(logits_scaled))
    print (sess.run(result))
運行結果:

[[0.95033026 0.04731416 0.00235563]
 [0.04622407 0.11369288 0.84008306]]
[3.9509459 1.6642545]
需要注意的是:


(1)如果labels的每一行是one-hot表示,也就是隻有一個地方爲1(或者說100%),其他地方爲0(或者說0%),還可以使用tf.sparse_softmax_cross_entropy_with_logits()。之所以用100%和0%描述,就是讓它看起來像一個概率分佈。
(2)tf.nn.softmax_cross_entropy_with_logits()函數已經過時 (deprecated),它在TensorFlow未來的版本中將被去除。取而代之的是

tf.nn.softmax_cross_entropy_with_logits_v2()。

 (3)參數labels,logits必須有相同的形狀 [batch_size, num_classes] 和相同的類型(float16, float32, float64)中的一種,否則交叉熵無法計算。

(4)tf.nn.softmax_cross_entropy_with_logits 函數內部的 logits 不能進行縮放,因爲在這個工作會在該函數內部進行(注意函數名稱中的 softmax ,它負責完成原始數據的歸一化),如果 logits 進行了縮放,那麼反而會影響計算正確性。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章