反向傳播之一:softmax函數
來自專欄反向傳播6 人贊了文章
不知道知乎怎麼預覽草稿,就先發布,邊寫邊改吧,反正我也沒有任何影響力
我目前的理解是:反向傳播是神經網路的精要,沒搞明白反向傳播,神經網路就還沒入門。
我的學習計劃是:
(1)推導一遍公式;
(2)寫一遍純numpy代碼;
(3)看一遍源碼。
本系列所有文章都不是原創,只是收集網上前期那些認真的牛人的文章於一處,手擼一遍推導,以求入門。於大家也是方便,於自己是一遍學習。
本文來源
帳號登錄- softmax函數
numpy代碼:
import numpy as npdef softmax(x): x = np.exp(x)/np.sum(np.exp(x)) return xprint(softmax([2,3]))
結果:[ 0.26894142 0.73105858]
2.softmax函數求導
(1)當 時
(2)當 時
綜上所述:
所以 (當Y的shape為(1,n)時)
3.softmax 函數的一個性質
這裡X是向量,c是一個常數。下面證明左右兩邊的每一個分量相等。
實際應用:為了防止溢出,事先把x減去最大值。最大值是有效數據,其他值溢不溢出可管不了,也不關心。
import numpy as npdef softmax(x): #減去最大值 x-=np.max(x) x = np.exp(x)/np.sum(np.exp(x)) return xprint(softmax([2,3]))
結果還是:[ 0.26894142 0.73105858]
4.作為中間層的激活函數
經過上面的討論,已經可以把softmax激活層的代碼寫出來:
class Softmax(object): def __init__(self): pass def forward(self, x): self.out = np.copy(x) self.out -= np.max(self.out) self.out = np.exp(self.out) s = np.sum(self.out) self.out= self.out / s return self.out def backward(self, eta): dout=np.diag(self.out)-np.dot(self.out,self.out.T) return np.dot(dout,eta)
結果怎樣呢?可以說是非常糟糕,開始表現還不錯,準確率可以衝到80%,但很快又回到原點。當然只要想想,一堆全部小於1的數不停的數乘來乘去,結果會怎樣!而且可以看出,它求導的計算量也非常大,所以softmax很特殊,沒有誰把它作為中間層的激活函數。都是放在最後一層,而且都是和交叉熵損失函數結合起來用。
5.softmax函數+交叉熵(log似然)代價函數
這裡的 是真實值,是訓練的目標,取0或1.在求導的時候是常量。 是softmax函數的輸出值,是訓練結果,是變數。
log似然代價函數C對每一個 求偏導,結果都是
當使用獨熱(onehot)編碼時, 只有一個位置為1,其他位置都是0。 也不需要用一個向量來存儲,只要 即可。
毫無疑問,這是一個無比優美的結果!!!
6.交叉熵是個什麼鬼?為什麼用交叉熵作為代價函數可以起到訓練作用?
簡單來說,訓練的目的是讓 。
但等於的可能性不大,至少 趨近即可。
而交叉熵的最小值是信息熵,當 時,C就是信息熵。怎麼證明?後面有一篇專門談這個證明。
反過來講,當我們訓練使得C達到最小值的時候, 就逐步趨近於 了。
就是說方法是求C的最小值,目的是 逐步趨近於 。這個是個間接的關係。當然,其他損失函數也是這樣。
7.源碼:fmscole/backpropagation
推薦閱讀:
TAG:機器學習 | 深度學習DeepLearning | 神經網路 |