深度学习中softmax交叉熵损失函数的理解
1. softmax層的作用
通過神經網絡解決多分類問題時,最常用的一種方式就是在最后一層設置n個輸出節(jié)點,無論在淺層神經網絡還是在CNN中都是如此,比如,在AlexNet中最后的輸出層有1000個節(jié)點,即便是ResNet取消了全連接層,但1000個節(jié)點的輸出層還在。
一般情況下,最后一個輸出層的節(jié)點個數(shù)與分類任務的目標數(shù)相等。
假設最后的節(jié)點數(shù)為N,那么對于每一個樣例,神經網絡可以得到一個N維的數(shù)組作為輸出結果,數(shù)組中每一個維度會對應一個類別。在最理想的情況下,如果一個樣本屬于k,那么這個類別所對應的的輸出節(jié)點的輸出值應該為1,而其他節(jié)點的輸出都為0,即 [0,0,1,0,….0,0][0,0,1,0,….0,0],這個數(shù)組也就是樣本的Label,是神經網絡最期望的輸出結果,但實際是這樣的輸出[0.01,0.01,0.6,....0.02,0.01][0.01,0.01,0.6,....0.02,0.01],這其實是在原始輸出的基礎上加入了softmax的結果,原始的輸出是輸入的數(shù)值做了復雜的加權和與非線性處理之后的一個值而已,這個值可以是任意的值,但是經過softmax層后就成了一個概率值,而且概率和為1。
假設神經網絡的原始輸出為y_1,y_2,….,y_n,那么經過Softmax回歸處理之后的輸出為 :
以上可以看出: ∑y′=1∑y′=1
這也是為什么softmax層的每個節(jié)點的輸出值成為了概率和為1的概率分布。
2. 交叉熵損失函數(shù)的數(shù)學原理
上面說過實際的期望輸出,也就是標簽是[0,0,1,0,….0,0][0,0,1,0,….0,0]這種形式,而實際的輸出是[0.01,0.01,0.6,....0.02,0.01][0.01,0.01,0.6,....0.02,0.01]這種形式,這時按照常理就需要有一個損失函數(shù)來判定實際輸出和期望輸出的差距,交叉熵就是用來判定實際的輸出與期望的輸出的接近程度!下面就簡單介紹下交叉熵的原理。
交叉熵刻畫的是實際輸出(概率)與期望輸出(概率)的距離,也就是交叉熵的值越小,兩個概率分布就越接近。假設概率分布p為期望輸出(標簽),概率分布q為實際輸出,H(p,q)為交叉熵。
- 第一種交叉熵損失函數(shù)的形式:
H(p,q)=?∑xp(x)logq(x)H(p,q)=?∑xp(x)logq(x)
舉個例子:
假設N=3,期望輸出為p=(1,0,0),實際輸出q1=(0.5,0.2,0.3),q2=(0.8,0.1,0.1)q1=(0.5,0.2,0.3),q2=(0.8,0.1,0.1),這里的q1,q2兩個輸出分別代表在不同的神經網絡參數(shù)下的實際輸出,通過計算其對應的交叉熵來優(yōu)化神經網絡參數(shù),計算過程:
H(p,q1)=?1(1×log0.5+0×log0.2+0×log0.3)H(p,q1)=?1(1×log0.5+0×log0.2+0×log0.3)
假設結果:H(p,q1)=0.3H(p,q1)=0.3
H(p,q2)=?1(1×log0.8+0×log0.1+0×log0.1)H(p,q2)=?1(1×log0.8+0×log0.1+0×log0.1)
假設結果:H(p,q2)=0.1H(p,q2)=0.1
這時得到了q2q2是相對正確的分類結果。
- 第二種交叉熵損失函數(shù)形式:
H(p,q)=?∑x(p(x)logq(x)+(1?p(x))log(1?q(x)))H(p,q)=?∑x(p(x)logq(x)+(1?p(x))log(1?q(x)))
下面簡單推到其過程:
我們知道,在二分類問題模型:例如邏輯回歸「Logistic Regression」、神經網絡「Neural Network」等,真實樣本的標簽為 [0,1],分別表示負類和正類。模型的最后通常會經過一個 Sigmoid 函數(shù),輸出一個概率值,這個概率值反映了預測為正類的可能性:概率越大,可能性越大。
Sigmoid 函數(shù)的表達式和圖形如下所示:g(s)=11+e?sg(s)=11+e?s
其中 s 是模型上一層的輸出,Sigmoid 函數(shù)有這樣的特點:s = 0 時,g(s) = 0.5;s >> 0 時, g ≈ 1,s << 0 時,g ≈ 0。顯然,g(s) 將前一級的線性輸出映射到 [0,1] 之間的數(shù)值概率上。
其中預測輸出即 Sigmoid 函數(shù)的輸出g(s)表征了當前樣本標簽為 1 的概率:
P(y=1|x)=y??P(y=1|x)=y^
p(y=0|x)=1?y??p(y=0|x)=1?y^
這個時候從極大似然性的角度出發(fā),把上面兩種情況整合到一起:
p(y|x)=y??y(1?y??)(1?y)p(y|x)=y^y(1?y^)(1?y)
這個函數(shù)式表征的是:
當真實樣本標簽 y = 1 時,上面式子第二項就為 1,概率等式轉化為:
P(y=1|x)=y??P(y=1|x)=y^
當真實樣本標簽 y = 0 時,上面式子第一項就為 1,概率等式轉化為:
P(y=0|x)=1?y??P(y=0|x)=1?y^
兩種情況下概率表達式跟之前的完全一致,只不過我們把兩種情況整合在一起了。那這個時候應用極大似然估計應該得到的是所有的概率值乘積應該最大,即:
L=∑Ni=1y??yii(1?y??i)(1?yi)L=∑i=1Ny^iyi(1?y^i)(1?yi)
引入log函數(shù)后得到:
L′=log(L)=∑Ni=1yilogy??i+(1?yi)log(1?y??i)L′=log(L)=∑i=1Nyilogy^i+(1?yi)log(1?y^i)
這時令loss=-log(L)=-L',也就是損失函數(shù)越小越好,而此時也就是 L'越大越好。
而在實際的使用訓練過程中,數(shù)據(jù)往往是組合成為一個batch來使用,所以對用的神經網絡的輸出應該是一個m*n的二維矩陣,其中m為batch的個數(shù),n為分類數(shù)目,而對應的Label也是一個二維矩陣,還是拿上面的數(shù)據(jù),組合成一個batch=2的矩陣
p=[110000]p=[100100]
根據(jù)第一種交叉熵的形式得到:
H(p,q)=[0.30.1]H(p,q)=[0.30.1]
而對于一個batch,最后取平均為0.2。
3. 在TensorFlow中實現(xiàn)交叉熵
在TensorFlow可以采用這種形式:
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)))其中y_表示期望的輸出,y表示實際的輸出(概率值),*為矩陣元素間相乘,而不是矩陣乘。
并且通過tf.clip_by_value函數(shù)可以將一個張量中的數(shù)值限制在一個范圍之內,這樣可以避免一些運算錯誤(比如log0是無效的),tf.clip_by_value函數(shù)是為了限制輸出的大小,為了避免log0為負無窮的情況,將輸出的值限定在(1e-10, 1.0)之間,其實1.0的限制是沒有意義的,因為概率怎么會超過1呢。比如:
結果:
[[2.5 2.5 3. ][4. 4.5 4.5]]上述代碼實現(xiàn)了第一種形式的交叉熵計算,需要說明的是,計算的過程其實和上面提到的公式有些區(qū)別,按照上面的步驟,平均交叉熵應該是先計算batch中每一個樣本的交叉熵后取平均計算得到的,而利用tf.reduce_mean函數(shù)其實計算的是整個矩陣的平均值,這樣做的結果會有差異,但是并不改變實際意義。
import tensorflow as tfv=tf.constant([[1.0,2.0,3.0],[4.0,5.0,6.0]]) with tf.Session() as sess:# 輸出3.5print(tf.reduce_mean(v).eval())由于在神經網絡中,交叉熵常常與Sorfmax函數(shù)組合使用,所以TensorFlow對其進行了封裝,即:
cross_entropy = tf.nn.sorfmax_cross_entropy_with_logits(y_ ,y)與第一個代碼的區(qū)別在于,這里的y用神經網絡最后一層的原始輸出就好了,而不是經過softmax層的概率值。
參考:https://blog.csdn.net/red_stone1/article/details/80735068
https://blog.csdn.net/chaipp0607/article/details/73392175
總結
以上是生活随笔為你收集整理的深度学习中softmax交叉熵损失函数的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 恒生科技指数在哪里看 恒生科技指数相关问
- 下一篇: 证券开户去哪里