詳解Softmax函數
- 2020 年 11 月 3 日
- AI


前言
提到二分類首先想到的可能就是邏輯回歸算法。邏輯回歸算法是在各個領域中應用比較廣泛的機器學習算法。邏輯回歸算法本身並不難,最關鍵的步驟就是將線性模型輸出的實數域映射到[0, 1]表示概率分佈的有效實數空間,其中Sigmoid函數剛好具有這樣的功能。

▲Sigmoid函數
▲擁有單個輸出節點的二分類
對於二分類問題,除了可以使用單個輸出節點表示事件A發生的概率外,還可以分別預測
和
,並滿足約束:
。其中
表示事件A的對立事件。
▲擁有兩個輸出節點的二分類
兩個節點輸出的二分類相比於單節點輸出的二分類多了一個的約束條件,這個約束條件將輸出節點的輸出值變成一個概率分佈,簡單來說各個輸出節點的輸出值範圍映射到[0, 1],並且約束各個輸出節點的輸出值的和為1。當然可以將輸出為兩個節點的二分類推廣成擁有n個輸出節點的n分類問題。
有沒有將各個輸出節點的輸出值範圍映射到[0, 1],並且約束各個輸出節點的輸出值的和為1的函數呢?
當然,這個函數就是Softmax函數。
Softmax從字面上來說,可以分成soft和max兩個部分。max故名思議就是最大值的意思。Softmax的核心在於soft,而soft有軟的含義,與之相對的是hard硬。很多場景中需要我們找出數組所有元素中值最大的元素,實質上都是求的hardmax。下面使用Numpy模塊以及TensorFlow深度學習框架實現hardmax。
使用Numpy模塊實現hardmax:

使用TensorFlow深度學習框架實現hardmax:

通過上面的例子可以看出hardmax最大的特點就是只選出其中一個最大的值,即非黑即白。但是往往在實際中這種方式是不合情理的,比如對於文本分類來說,一篇文章或多或少包含着各種主題信息,我們更期望得到文章對於每個可能的文本類別的概率值(置信度),可以簡單理解成屬於對應類別的可信度。所以此時用到了soft的概念,Softmax的含義就在於不再唯一的確定某一個最大值,而是為每個輸出分類的結果都賦予一個概率值,表示屬於每個類別的可能性。
下面給出Softmax函數的定義(以第i個節點輸出為例):
,其中
為第i個節點的輸出值,C為輸出節點的個數,即分類的類別個數。通過Softmax函數就可以將多分類的輸出值轉換為範圍在[0, 1]和為1的概率分佈。
引入指數函數對於Softmax函數是把雙刃劍,即得到了優點也暴露出了缺點:
-
引入指數形式的優點
▲y=e^{x}函數圖像
指數函數曲線呈現遞增趨勢,最重要的是斜率逐漸增大,也就是說在x軸上一個很小的變化,可以導致y軸上很大的變化。這種函數曲線能夠將輸出的數值拉開距離。假設擁有三個輸出節點的輸出值為 為[2, 3, 5]。首先嘗試不使用指數函數
,接下來使用指數函數的Softmax函數計算。

tf.Tensor([0.2 0.3 0.5], shape=(3,), dtype=float32)tf.Tensor([0.04201007 0.11419519 0.8437947 ], shape=(3,), dtype=float32)
兩種計算方式的輸出結果分別是:
-
tf.Tensor([0.2 0.3 0.5], shape=(3,), dtype=float32) -
tf.Tensor([0.04201007 0.11419519 0.8437947],shape=(3,), dtype=float32)
-
引入指數形式的缺點

當然針對數值溢出有其對應的優化方法,將每一個輸出值減去輸出值中最大的值。

這裡需要注意一下,當使用Softmax函數作為輸出節點的激活函數的時候,一般使用交叉熵作為損失函數。由於Softmax函數的數值計算過程中,很容易因為輸出節點的輸出值比較大而發生數值溢出的現象,在計算交叉熵的時候也可能會出現數值溢出的問題。為了數值計算的穩定性,TensorFlow提供了一個統一的接口,將Softmax與交叉熵損失函數同時實現,同時也處理了數值不穩定的異常,使用TensorFlow深度學習框架的時候,一般推薦使用這個統一的接口,避免分開使用Softmax函數與交叉熵損失函數。
TensorFlow提供的統一函數式接口為:

其中y_true代表了One-hot編碼後的真實標籤,y_pred表示網絡的實際預測值:
-
當from_logits設置為True時,y_pred表示未經Softmax函數的輸出值; -
當from_logits設置為False時,y_pred表示為經過Softmax函數後的輸出值;
為了在計算Softmax函數時候數值的穩定,一般將from_logits設置為True,此時tf.keras.losses.categorical_crossentropy將在內部進行Softmax的計算,所以在不需要在輸出節點上添加Softmax激活函數。

雖然上面兩個過程結果差不多,但是當遇到一些不正常的數值時,將from_logits設置為True時TensorFlow會啟用一些優化機制。因此推薦使用將from_logits參數設置為True的統一接口。
單個輸出節點的二分類問題一般在輸出節點上使用Sigmoid函數,擁有兩個及其以上的輸出節點的二分類或者多分類問題一般在輸出節點上使用Softmax函數。其他層建議使用的激活函數可以參考深度學習中常用激活函數的詳細總結。
現在可以構建比較複雜的神經網絡模型,最重要的原因之一得益於反向傳播算法。反向傳播算法從輸出端也就是損失函數開始向輸入端基於鏈式法則計算梯度,然後通過計算得到的梯度,應用梯度下降算法迭代更新待優化參數。
由於反向傳播計算梯度基於鏈式法則,因此下面為了更加清晰,首先推導一下Softmax函數的導數。作為最後一層的激活函數,求導本身並不複雜,但是需要注意需要分成兩種情況來考慮。

▲來源李宏毅老師PPT
為了方便說明,先來簡單看一個小例子。
▲簡單計算圖
可以將梯度看成是高維的導數,而導數簡單來說就是切線的斜率,也就是y軸的改變量與x軸的改變量的比值。通過上面的計算圖可以得知,和
的改變量都會影響
的值,因此需要讓
與
和
分別求導,很明顯此時計算出來的兩個偏導數結果不同,
,
。
繪製擁有三個輸出節點的Softmax函數的計算圖:
▲擁有三個輸出節點的Softmax函數的計算圖
-
對 時,類似前面介紹的
。Softmax函數的偏導數
可以展開為:
-
對 時,類似前面介紹的
或
。Softmax函數的偏導數
可以展開為:
首發:
1. 觸摸壹縷陽光~知乎 參考:
1. 三分鐘帶你對 Softmax 劃重點
2. 《TensorFlow深度學習》
3. 觸摸壹縷陽光:[L4]使用LSTM實現語言模型-softmax與交叉熵