關於交叉熵(cross entropy),你了解哪些


二分~多分~Softmax~理預

一、簡介

 在二分類問題中,你可以根據神經網絡節點的輸出,通過一個激活函數如Sigmoid,將其轉換為屬於某一類的概率,為了給出具體的分類結果,你可以取0.5作為閾值,凡是大於0.5的樣本被認為是正類,小於0.5則認為是負類

 然而這樣的做法並不容易推廣到多分類問題。多分類問題神經網絡最常用的方法是根據類別個數n,設置n個輸出節點,這樣每個樣本神經網絡都會給出一個n維數組作為輸出結果,然后我們運用激活函數如softmax,將輸出轉換為一種概率分布,其中的每一個概率代表了該樣本屬於某類的概率。

 比如一個手寫數字識別這種簡單的10分類問題,對於數字1的識別,神經網絡模型的輸出結果應該越接近\([0, 1, 0, 0, 0, 0, 0, 0, 0, 0]\)越好,其中\([0, 1, 0, 0, 0, 0, 0, 0, 0, 0]\)是最理想的結果了

 但是如何衡量一個神經網絡輸出向量和理想的向量的接近程度呢?交叉熵(cross entropy)就是這個評價方法之一,他刻畫了兩個概率分布之間的距離,是多分類問題中常用的一種損失函數

 

二、交叉熵

 給定兩個概率分布:p(理想結果即正確標簽向量)和q(神經網絡輸出結果即經過softmax轉換后的結果向量),則通過q來表示p的交叉熵為:

\(H(p, q) = - \sum_xp(x)logq(x)\)

 注意:既然p和q都是一種概率分布,那么對於任意的x,應該屬於\([0, 1]\)並且所有概率和為1

\(\forall x p(X=x) \epsilon [0,1]\)且\(\sum_xp(X=x) =1\)

 交叉熵刻畫的是通過概率分布q來表達概率分布p的困難程度,其中p是正確答案,q是預測值,也就是交叉熵值越小,兩個概率分布越接近

 

三、三分類實例講解交叉熵

 其中某個樣本的正確答案即p是\([1,0, 0]\),某模型經過Softmax激活后的答案即預測值q是\([0.5, 0.4, 0.1]\),那么這個預測值和正確答案之間的交叉熵為:

\(H(p=[1,0,0], q=[0.5,0.4,0.1]) = -(1*log0.5 + 0*log0.4 + 0*log0.1) \approx 0.3\)

 如果另外一個模型的預測值q是\([0.8, 0.1, 0.1]\),那么這個預測值和正確答案之間的交叉熵為:

\(H(p=[1,0,0], q=[0.8,0.1,0.1]) = -(1*log0.8 + 0*log0.1 + 0*log0.1) \approx 0.1\)

 從直觀上可以很容易的知道第二個預測答案要優於第一個,通過交叉熵計算得到的結果也是一致的(第二個交叉熵值更小)

 而TF中很容易做到交叉熵的計算:

import tensorflow as tf

cross_entropy = -tf.reduce_mean( y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)) )

 

 上述代碼包含了四種不同的TF運算,解釋如下:

 1)tf.clip_by_value():將一個張量中的數值限制在一個范圍內,如限制在\([0.1, 1.0]\)范圍內,可以避免一些運算錯誤,如預測結果q中元素可能為0,這樣的話log0是無效的

v = tf.constant([[1.0, 2.0, 3.0], [4.0,5.0,6.0] ])
with tf.Session() as sess:
	sess.run(tf.global_variables_initializer())
	print(tf.clip_by_value(v, 2.5, 4.5).eval())

  

 2)tf.log():對張量中的所有元素依次求對數

v = tf.constant([[1.0, 2.0, 3.0], [4.0,5.0,6.0] ])
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(tf.log(v).eval())

  

 3)乘法運算:*操作,是元素之間直接相乘,而矩陣相乘用tf.matmul函數來完成

v1 = tf.constant([ [1.0, 2.0], [3.0, 4.0]])
v2 = tf.constant([ [5.0, 6.0], [7.0, 8.0]])
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print( (v1 * v2).eval() )
    print( tf.matmul(v1, v2).eval() )

  

 

 4)求和:上面三個運算完成了每個樣例中每個類別的交叉熵\(p(x)logq(x)\)的計算,還未進行求和運算

  即:三步計算后得到的結果是個n * m的二維矩陣,其中n為一個batch中樣本數量,m為分類的類別數量,比如十分類問題,m為10.根據交叉熵公式

  最后是要將每行中m個結果相加得到每個樣本的交叉熵,然后再對這n行取平均得到一個batch的平均交叉熵,即-tf.reduce_mean()函數來實現

 

 總結:因為交叉熵一般會與softmax一起使用,所以TF對這兩個功能進行了封裝,並提供了tf.nn.softmax_cross_entropy_with_logits函數

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(y, y_)
#y:原始神經網絡的輸出結果
#y_:標准答案
#這樣一個函數即可實現使用了Softmax后的交叉熵

 關於Softmax計算過程,可以參考:實戰Google深度學習框架-C4-深層神經網絡

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM