如果你稍微了解一點深度學(xué)習(xí)的知識或者看過深度學(xué)習(xí)的在線課程,你就一定知道最基礎(chǔ)的多分類問題。當(dāng)中,老師一定會告訴你在全連接層后面應(yīng)該加上 Softmax 函數(shù),如果正常情況下(不正常情況指的是類別超級多的時候)用交叉熵函數(shù)作為損失函數(shù),你就一定可以得到一個讓你基本滿意的結(jié)果。而且,現(xiàn)在很多開源的深度學(xué)習(xí)框架,直接就把各種損失函數(shù)寫好了(甚至在 Pytorch中 CrossEntropyLoss 已經(jīng)把 Softmax函數(shù)集合進(jìn)去了),你根本不用操心怎么去實現(xiàn)他們,但是你真的理解為什么要這么做嗎?這篇小文就將告訴你:Softmax 是如何把 CNN 的輸出轉(zhuǎn)變成概率,以及交叉熵是如何為優(yōu)化過程提供度量。為了讓讀者能夠深入理解,我們將會用 Python 一一實現(xiàn)他們。
▌Softmax函數(shù)
Softmax 函數(shù)接收一個 這N維向量作為輸入,然后把每一維的值轉(zhuǎn)換成(0,1)之間的一個實數(shù),它的公式如下面所示:
正如它的名字一樣,Softmax 函數(shù)是一個“軟”的最大值函數(shù),它不是直接取輸出的最大值那一類作為分類結(jié)果,同時也會考慮到其它相對來說較小的一類的輸出。
說白了,Softmax 可以將全連接層的輸出映射成一個概率的分布,我們訓(xùn)練的目標(biāo)就是讓屬于第k類的樣本經(jīng)過 Softmax 以后,第 k 類的概率越大越好。這就使得分類問題能更好的用統(tǒng)計學(xué)方法去解釋了。
使用 Python,我們可以這么去實現(xiàn) Softmax 函數(shù):
我們需要注意的是,在 numpy 中浮點類型是有數(shù)值上的限制的,對于float64,它的上限是。對于指數(shù)函數(shù)來說,這個限制很容易就會被打破,如果這種情況發(fā)生了 python 便會返回?nan。
為了讓 Softmax 函數(shù)在數(shù)值計算層面更加穩(wěn)定,避免它的輸出出現(xiàn)nan這種情況,一個很簡單的方法就是對輸入向量做一步歸一化操作,僅僅需要在分子和分母上同乘一個常數(shù)C,如下面的式子所示
理論上來說,我們可以選擇任意一個值作為,但是一般我們會選擇
通過這種方法就使得原本非常大的指數(shù)結(jié)果變成0,避免出現(xiàn)?nan的情況。
同樣使用 Python,改進(jìn)以后的 Softmax 函數(shù)可以這樣寫:
▌Softmax 函數(shù)的導(dǎo)數(shù)推倒過程
通過上文我們了解到,Softmax 函數(shù)可以將樣本的輸出轉(zhuǎn)變成概率密度函數(shù),由于這一很好的特性,我們就可以把它加裝在神經(jīng)網(wǎng)絡(luò)的最后一層,隨著迭代過程的不斷深入,它最理想的輸出就是樣本類別的 One-hot 表示形式。進(jìn)一步我們來了解一下如何去計算 Softmax 函數(shù)的梯度(雖然有了深度學(xué)習(xí)框架這些都不需要你去一步步推導(dǎo),但為了將來能設(shè)計出新的層,理解反向傳播的原理還是很重要的),對 Softmax 的參數(shù)求導(dǎo):
根據(jù)商的求導(dǎo)法則,對于其導(dǎo)數(shù)為?
。在中,一直都是?但是在?中,當(dāng)且僅當(dāng)?的時候,才為。具體的過程,我們看一下下面的步驟:
如果
如果
所以 Softmax 函數(shù)的導(dǎo)數(shù)如下面所示:
▌交叉熵?fù)p失函數(shù)
下面我們來看一下對模型優(yōu)化真正起到作用的損失函數(shù)——交叉熵?fù)p失函數(shù)。交叉熵函數(shù)體現(xiàn)了模型輸出的概率分布和真實樣本的概率分布的相似程度。它的定義式就是這樣:
在分類問題中,交叉熵函數(shù)已經(jīng)大范圍的代替了均方誤差函數(shù)。也就是說,在輸出為概率分布的情況下,就可以使用交叉熵函數(shù)作為理想與現(xiàn)實的度量。這也就是為什么它可以作為有 Softmax 函數(shù)激活的神經(jīng)網(wǎng)絡(luò)的損失函數(shù)。
我們來看一下,在 Python 中是如何實現(xiàn)交叉熵函數(shù)的:
▌交叉熵?fù)p失函數(shù)的求導(dǎo)過程
就像我們之前所說的,Softmax 函數(shù)和交叉熵?fù)p失函數(shù)是一對好兄弟,我們用上之前推導(dǎo) Softmax 函數(shù)導(dǎo)數(shù)的結(jié)論,配合求導(dǎo)交叉熵函數(shù)的導(dǎo)數(shù):
加上 Softmax 函數(shù)的導(dǎo)數(shù):
y 代表標(biāo)簽的 One-hot 編碼,因此因此我們就可以得到:
可以看到,這個結(jié)果真的太簡單了,不得不佩服發(fā)明它的大神們!最后,我們把它轉(zhuǎn)換成代碼:
▌小結(jié)
需要注意的是,正如我之前提到過的,在許多開源的深度學(xué)習(xí)框架中,Softmax 函數(shù)被集成到所謂的 CrossEntropyLoss 函數(shù)中。比如 Pytorch 的說明文檔,就明確地告訴讀者 CrossEntropyLoss 這個損失函數(shù)是 Log-Softmax 函數(shù)和負(fù)對數(shù)似然函數(shù)(NLLoss)的組合,也就是說當(dāng)你使用它的時候,沒有必要再在全連接層后面加入 Softmax 函數(shù)。還有許多文章中會提到 SoftmaxLoss,其實它就是 Softmax 函數(shù)和交叉熵函數(shù)的組合,跟我們說的 CrossEntropyLoss 函數(shù)是一個意思,這點需要讀者自行分辨即可。
-
python
+關(guān)注
關(guān)注
55文章
4767瀏覽量
84376 -
深度學(xué)習(xí)
+關(guān)注
關(guān)注
73文章
5463瀏覽量
120891 -
cnn
+關(guān)注
關(guān)注
3文章
350瀏覽量
22132
原文標(biāo)題:Softmax和交叉熵的深度解析和Python實現(xiàn)
文章出處:【微信號:AI_Thinker,微信公眾號:人工智能頭條】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論