cross_entropy-----交叉熵是深度學習中常用的一個概念,一般用來求目標與預測值之間的差距。
在介紹softmax_cross_entropy,binary_cross_entropy、sigmoid_cross_entropy之前,先來回顧一下信息量、熵、交叉熵等基本概念。
---------------------
信息論
交叉熵是信息論中的一個概念,要想了解交叉熵的本質,需要先從最基本的概念講起。
一、信息量
首先是信息量。假設我們聽到了兩件事,分別如下:
事件A:巴西隊進入了2018世界杯決賽圈。
事件B:中國隊進入了2018世界杯決賽圈。
僅憑直覺來說,顯而易見事件B的信息量比事件A的信息量要大。究其原因,是因為事件A發生的概率很大,事件B發生的概率很小。所以當越不可能的事件發生了,我們獲取到的信息量就越大。越可能發生的事件發生了,我們獲取到的信息量就越小。那么信息量應該和事件發生的概率有關。

二、什么是熵
熵
對於某個事件,有n種可能性,每一種可能性都有一個概率p(xi)
這樣就可以計算出某一種可能性的信息量。舉一個例子,假設你拿出了你的電腦,按下開關,會有三種可能性,下表列出了每一種可能的概率及其對應的信息量

注:文中的對數均為自然對數
我們現在有了信息量的定義,而熵用來表示所有信息量的期望,即:

其中n代表所有的n種可能性,所以上面的問題結果就是

二、 相對熵(KL散度)
相對熵又稱KL散度,如果我們對於同一個隨機變量 x 有兩個單獨的概率分布 P(x) 和 Q(x),我們可以使用 KL 散度(Kullback-Leibler (KL) divergence)來衡量這兩個分布的差異
在機器學習中,P往往用來表示樣本的真實分布,比如[1,0,0]表示當前樣本屬於第一類。Q用來表示模型所預測的分布,比如[0.7,0.2,0.1]
KL散度的計算公式:

三、什么是交叉熵
交叉熵
對式3.1變形可以得到:

其中p代表label或者叫groundtruth,q代表預測值
在機器學習中,我們需要評估label和predicts之間的差距,使用KL散度剛剛好,即

由於KL散度中的前一部分恰巧就是p的熵,p代表label或者叫groundtruth,故−H(p(x))不變,故在優化過程中,只需要關注交叉熵就可以了,所以一般在機器學習中直接用用交叉熵做loss,評估模型。
交叉熵:

四、softmax_cross_entropy
以tensorflow中函數softmax_cross_entropy_with_logits為例,在二分類或者類別相互排斥多分類問題,計算 logits 和 labels 之間的 softmax 交叉熵。

數據必須經過 One-Hot Encoding 編碼
tf.one_hot

用 mnist 數據舉例,如果是目標值是3,那么 label 就是[0,0,0,1,0,0,0,0,0,0],除了第4個值為1,其他全為0。
該函數把一個維度上的 labels 作為一個整體判斷,結果給出整個維度的損失值。
這個函數傳入的 logits 是 unscaled 的,既不做 sigmoid 也不做 softmax ,因為函數實現會在內部更高效得使用 softmax 。
softmax_cross_entropy_with_logits計算過程
1、對輸入進行softmax

舉個例子:假設你的輸入S=[1,2,3],那么經過softmax層后就會得到[0.09,0.24,0.67],這三個數字表示這個樣本屬於第1,2,3類的概率分別是0.09,0.24,0.67。
2、計算交叉熵

L是損失,Sj是softmax的輸出向量S的第j個值,前面已經介紹過了,表示的是這個樣本屬於第j個類別的概率。yj前面有個求和符號,j的范圍也是1到類別數T,因此label——y是一個1*T的向量,里面的T個值,而且只有1個值是1,其他T-1個值都是0。真實標簽對應的位置的那個值是1,其他都是0。所以這個公式其實有一個更簡單的形式:

來舉個例子吧。假設一個5分類問題,然后一個樣本I的標簽y=[0,0,0,1,0],也就是說樣本I的真實標簽是4,假設模型預測的結果概率(softmax的輸出)p=[0.1,0.15,0.05,0.6,0.1],可以看出這個預測是對的,那么對應的損失L=-log(0.6),也就是當這個樣本經過這樣的網絡參數產生這樣的預測p時,它的損失是-log(0.6)。那么假設p=[0.15,0.2,0.4,0.1,0.15],這個預測結果就很離譜了,因為真實標簽是4,而你覺得這個樣本是4的概率只有0.1(遠不如其他概率高,如果是在測試階段,那么模型就會預測該樣本屬於類別3),對應損失L=-log(0.1)。
補充:sparse_softmax_cross_entropy_with_logits
sparse_softmax_cross_entropy_with_logits 是 softmax_cross_entropy_with_logits 的易用版本,除了輸入參數不同,作用和算法實現都是一樣的。
區別是:softmax_cross_entropy_with_logits 要求傳入的 labels 是經過 one_hot encoding 的數據,而 sparse_softmax_cross_entropy_with_logits 不需要。
五、binary_cross_entropy
binary_cross_entropy是二分類的交叉熵,實際是多分類softmax_cross_entropy的一種特殊情況,當多分類中,類別只有兩類時,即0或者1,即為二分類,二分類也是一個邏輯回歸問題,也可以套用邏輯回歸的損失函數。
1、利用softmax_cross_entropy_with_logits來計算二分類的交叉熵
來舉個例子,假設一個2分類問題,假如一個batch包含兩個樣本,那么標簽要制成二維,形如
y=[ [1, 0],[0, 1] ],
模型預測輸出也為二維,形如
p=[ [0.8,0.2],[0.4,0.6] ] #(softmax的輸出)
那么對應的損失
L=( -log(0.8) - log(0.6) ) / 2
實際在計算中若采用softmax_cross_entropy_with_logits函數,不要事先做softmax處理。
2、套用邏輯回歸代價損失函數來計算二分類的交叉熵
邏輯回歸的損失函數如下:

來舉個例子,假設一個2分類問題,假如一個batch包含兩個樣本,那么標簽要制成一維,形如
y=[0,1 ],
模型預測輸出也為一維,形如
p=[ 0.2,0.6 ] #sigmoid的輸出,這里一定要預先用sigmod處理,將預測結果限定在0~1之間,
那么對應的損失
L=( - 0*log(0.2) - (1 - 0)*log(1- 0.2) - log(0.6) - (1 -1)*log(1 - 0.6) ) / 2 = ( -log(0.8) - log(0.6) ) / 2
六、sigmoid_cross_entropy
以tensorflow中函數sigmoid_cross_entropy_with_logits為例說明
sigmoid_cross_entropy_with_logits函數,測量每個類別獨立且不相互排斥的離散分類任務中的概率。(可以執行多標簽分類,其中圖片可以同時包含大象和狗。)
import tensorflow as tf
_logits = [[0.5, 0.7, 0.3], [0.8, 0.2, 0.9]]
_one_labels = tf.ones_like(_logits)
# [[1 1 1]
# [1 1 1]]
_zero_labels = tf.zeros_like(_logits)
# [[0 0 0]
# [0 0 0]]
with tf.Session() as sess:
loss = tf.nn.sigmoid_cross_entropy_with_logits(logits=_logits, labels=_one_labels)
print(sess.run(loss))
# [[0.47407699 0.40318602 0.5543552]
# [0.37110069 0.59813887 0.34115386]]
loss = tf.nn.sigmoid_cross_entropy_with_logits(logits=_logits, labels=_zero_labels)
print(sess.run(loss))
# [[0.97407699 1.10318601 0.85435522]
# [1.17110074 0.79813886 1.24115384]]
看看sigmoid_cross_entropy_with_logits函數定義
def sigmoid_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, name=None):
#為了描述簡潔,規定 x = logits,z = labels,那么 Logistic 損失值為:
z * -log(sigmoid(x)) + (1 - z) * -log(1 - sigmoid(x))
= z * -log(1 / (1 + exp(-x))) + (1 - z) * -log(exp(-x) / (1 + exp(-x)))
= z * log(1 + exp(-x)) + (1 - z) * (-log(exp(-x)) + log(1 + exp(-x)))
= z * log(1 + exp(-x)) + (1 - z) * (x + log(1 + exp(-x))
= (1 - z) * x + log(1 + exp(-x))
= x - x * z + log(1 + exp(-x))
該函數與 softmax_cross_entropy_with_logits的區別在於:softmax_cross_entropy_with_logits中的labels 中每一維只能包含一個 1,而sigmoid_cross_entropy_with_logits中的labels 中每一維可以包含多個 1。
softmax_cross_entropy_with_logits函數把一個維度上的 labels 作為一個整體判斷,結果給出整個維度的損失值,而 sigmoid_cross_entropy_with_logits 是每一個元素都有一個損失值,都是一個二分類(binary_cross_entropy)問題。
轉自:https://www.jianshu.com/p/47172eb86b39