log_softmax

參考:https://blog.csdn.net/qq_28418387/article/details/95918829

python版softmax:

def softmax(x, axis=1):
    # 計算每行的最大值
    row_max = x.max(axis=axis)

    # 每行元素都需要減去對應的最大值,否則求exp(x)會溢出,導致inf情況
    row_max = row_max.reshape(-1, 1)
    x = x - row_max

    # 計算e的指數次冪
    x_exp = np.exp(x)
    x_sum = np.sum(x_exp, axis=axis, keepdims=True)
    s = x_exp / x_sum
    return s

 

LogSoftmax
顧名思義,logsoftmax其實就是對softmax求出來的值再求一次log值,其計算公式如下:
LogSoftmax(xi)=log(exp(xi)∑jexp(xj)) LogSoftmax(x_i)=log(\frac{exp(x_i)}{\sum_{j}exp(x_j)})

 

Pytorch中Softmax、Log_Softmax、NLLLoss以及CrossEntropyLoss的關係與區別詳解


最近看了一些Pytorch的代碼,代碼中使用了Log_Softmax方法,Loss函數使用了NLLLoss,作爲深度學習新手,便上網查了一些資料,將相關知識總結記錄以下。

本文主要參考了這篇文章,在此基礎上加入了一些自己的理解。

Softmax
我們知道softmax激活函數的計算方式是對輸入的每個元素值x求以自然常數e爲底的指數,然後再分別除以他們的和,其計算公式如下:

​    


 

舉個例子,假如是圖片分類任務,輸入m張圖片,輸出爲一個m * N的Tensor,其中N爲類別數。加入輸入的是四張圖片,類別數爲3,那麼輸出的就是一個4 * 3的Tensor:

每一行代表一張圖片,假如每一列分別代表類別爲貓、狗、豬的得分,可以看出模型認爲第二,第四張更有可能是狗,第一張更有可能是貓,第三張更有可能是豬。然後對每個值求softmax,得到每張圖片的概率分佈。求得softmax值爲:

參數dim=1表示對每一行求softmax,那麼每一行的值加起來都等於1。
那麼我們再看看對softmax值再求log:

由於經過softmax求出來的值都在[0,1]區間,所以,再log求值之後的值域爲負無窮到1。記住上面的值,我們再直接對輸入值計算LogSoftmax,與上面的值對比:

看!計算出來的完全相等,這就驗證了LogSoftmax等於對Softmax求log值。

NLLLoss
NLLLoss的計算方式就是將上面輸出的值與對應的Label中的類別拿出來去掉負號,求均值。比如,我們現在的Target標籤爲[0, 2, 1, 2],分別表示第一張圖片的label爲貓,第二張圖片的label爲豬,第三章圖片的label爲狗,第四張圖片的label爲豬。那麼NLLLoss的計算就是取出上面輸出的第一行-0.5315,第二行-2.3351,第三行-2.6132,第四行-1.4174,取他們的絕對值求和取平均

那麼我們再通過pytorch中的NLLLoss函數來計算一下:

看!計算出來的值相等。
這裏說一下我自己對NLLLoss的理解,爲什麼NLLLoss的計算方式可以用來求損失值。經過上面的計算我們知道,Softmax計算出來的值範圍在[0, 1],值的含義表示對應類別的概率,也就是說,每行(代表每張圖)中最接近於1的值對應的類別,就是該圖片概率最大的類別,那麼經過log求值取絕對值之後,就是最接近於0的值,如果此時每行中的最小值對應的類別值與Target中的類別值相同,那麼每行中的最小值求和取平均就是最小,極端的情況就是0。總結一下就是,input的預測值與Target的值越接近,NLLLoss求出來的值就越接近於0,這不正是損失值的本意所在嗎,所以NLLLoss可以用來求損失值。

CrossEntropyLoss
CrossEntropyLoss很容易理解,它就是softmax+log+NLLLoss,一步到位,不需要那麼多步驟去自己寫,它的輸入就是模型的直接輸出,測試一下:

果然沒錯,與之前NLLLoss求出來的一樣!

發佈了2649 篇原創文章 · 獲贊 964 · 訪問量 524萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章