Softmax|8月更文挑戰

Softmax函數概述

  • soft version of max
  • 大的愈來愈大,小的愈來愈小

Softmax常與crossentropy(交叉熵)搭配連用html

上圖中假設有三個輸出,分別是2.0,1.0和0.1,若是將數值轉換成機率的話,咱們但願機率最大的值做爲預測的label。即咱們但願將最大值2.0所對應的索引做爲相應的label輸出,那麼如何做爲probilities輸出呢?python

sigmoid函數能夠將input壓縮到[0,1]的範圍,可是對於分類問題來講,咱們不只要求機率範圍是[0,1],還要求全部的機率和爲1,即 p i = 1 \sum p_i = 1 markdown

爲了解決此類問題,就有了Softmax函數,具體的函數表達式爲app

S ( y i ) = e y i j e y j S(y_i) = \frac{e^{y_i}}{\sum_j e^{y_j}}

另外有一點要注意,Softmax具備差距放大功能,例如原來2.0和1.0是兩倍關係,通過Softmax壓縮後,變爲0.7和0.2,增大到3.5倍關係函數

Softmax求導

對Softmax函數進行求導,首先寫出其函數表達式ui

p i = e a i k = 1 N e a k p_i = \frac{e^{a_i}}{\sum_{k=1}^Ne^{a_k}}

根據除法求導法則,若 f ( x ) = g ( x ) h ( x ) f(x)=\frac{g(x)}{h(x)} ,則 f ( x ) = g ( x ) h ( x ) h ( x ) g ( x ) h 2 ( x ) f'(x) = \frac{g'(x)h(x)-h'(x)g(x)}{h^2(x)} spa

i = j i=j code

e a i k = 1 N e a k a j = e a i k = 1 N a k e a j e a i ( k = 1 N e a k ) 2 = e a i ( k = 1 N a k e a j ) ( k = 1 N e a k ) 2 = e a j k = 1 N e a k ( k = 1 N e a k e a j ) k = 1 N e a k = p i ( 1 p j ) \begin{aligned} \frac{\nabla\frac{e^{a_i}}{\sum_{k=1}^Ne^{a_k}}}{\nabla{a_j}} &= \frac{e^{a_i}\sum_{k=1}^{N} a_k - e^{a_j}e^{a_i}}{(\sum_{k=1}^N e^{a_k})^2} \\ &= \frac{e^{a_i}(\sum_{k=1}^{N} a_k - e^{a_j})}{(\sum_{k=1}^N e^{a_k})^2} \\ &= \frac{e^{a_j}}{\sum_{k=1}^N e^{a_k}}*\frac{(\sum_{k=1}^N e^{a_k}-e^{a_j})}{\sum_{k=1}^N e^{a_k}} \\ &= p_i(1-p_j) \end{aligned}

i j i\neq j orm

e a i k = 1 N e a k a j = 0 e a j e a i ( k = 1 N e a k ) 2 = e a j k = 1 N e a k e a i k = 1 N e a k = p j p i \begin{aligned} \frac{\nabla\frac{e^{a_i}}{\sum_{k=1}^Ne^{a_k}}}{\nabla{a_j}} &= \frac{0 - e^{a_j}e^{a_i}}{(\sum_{k=1}^N e^{a_k})^2} \\ &= \frac{-e^{a_j}}{\sum_{k=1}^N e^{a_k}}*\frac{e^{a_i}}{\sum_{k=1}^N e^{a_k}} \\ &= -p_j * p_i \end{aligned}

對以上求導過程進行總結xml

p i a j = { p i ( 1 p j ) i = j p j p i i j \frac{\nabla p_i}{\nabla{a_j}}=\begin{cases}p_i(1-p_j) & i = j \cr -p_j*p_i &i \neq j\end{cases}

須要注意的一點是,因爲 p j p_j p j p_j 均在 [ 0 , 1 ] [0,1] 範圍內,故 p i ( 1 p j ) > 0 p_i(1-p_j)>0 p i p j < 0 -p_i*p_j<0

下面使用代碼舉例

import torch
import torch.nn.functional as F
a = torch.rand(3, requires_grad=True) # dim=1, len=3 tensor
p = F.softmax(a, dim=0)# 須要指定進行sfotmax操做的dim維度
print('softmax:', p)
torch.autograd.grad(p[0],[a], retain_graph=True)
# 注意Loss必須是長度爲1的值,因爲p是dim=1,len=3的值,所以取必須取p中的一個
複製代碼

輸出

softmax: tensor([0.2732, 0.3780, 0.3489], grad_fn=<SoftmaxBackward>)
(tensor([ 0.1985, -0.1033, -0.0953]),)
複製代碼

這裏進行了 p 0 a i \frac{\nabla p_0}{\nabla{a_i}} 的操做,因爲 a a [ 0 , 2 ] [0,2] 的tensor,因此返回了一個 1 3 1*3 的tensor。而且仔細觀察會發現,當 i = 0 i=0 時,梯度信息爲正

參數retain_graph=True須要解釋一下。因爲PyTorch在求導一次以後,就會將這個圖的梯度信息清除掉,若是第二次再求導,就會報錯。但若是寫上這個參數,就能夠保留梯度信息,就能再求一次導

相關文章
相關標籤/搜索