接前一篇的內容:自己動手寫深度神經網路框架(一);然後先附上完整實現
leeroee/CNN?github.com之前介紹到了Softmax函數:
可以看到,它接受一個向量(或者一組變數)作為輸入,每個變數指數化後除以所有指數化變數之和,(順便說一下,sigmoid函數就是其輸入數為2時的特例),有點類似於對輸入進行歸一化,事實上它就叫做歸一化指數函數
為了更直觀的理解先來看一個栗子,現有一個向量如下
將其作為softamax的輸入,先對其進行指數化:
最後就是:
得到的結果之和為1,每一個分量表示其概率,例如,如果是手寫數字識別的話,輸入數據經過若干個層的計算後投入到softmax中,得到一個長度為10(從0到9)的向量,每個分量的值表示個所要識別的數字為該數字的概率,取概率最高的作為結果
基本上的原理和功能都說明白了,不過在實際計算過程中有事會遇到一些問題,如溢出
從上面的式子中可以看出,如果輸入的x有某個值非常的的話,再對其進行指數化的話,就可能因為數字過大而導致溢出,所以在進行計算之前需要讀輸入x進行一些處理,將其每個分量都減去最大的那個值,用在上面的情況就是:
可以看到,這樣並不會改變最終的結果
線性層和激活層的forward都說完了,接下來就是損失函數了
首先,為什麼要有損失函數?
在有監督的訓練中,將訓練樣本的數據投入到網路中,得到一個輸出結果,同時你有該樣本的真值;例如數字識別,將一個數字的圖片輸入到網路中,得到網路的輸出結果(即網路判斷這是數字幾),然後將這個判斷的數字和真實值進行比較,根據結果進而調整網路的權重,以期提升網路針對這一任務的表現
如何進行比較呢?這就需要用到損失函數了,例如均方誤差損失(MSELoss):
這只是多種誤差函數的一種,不同的任務會有不同的損失函數,例如上述的softmax,它用作多分類任務的輸出,而該類任務的損失函數叫做交叉熵損失(CrossEntropyLoss):
關於交叉熵更多詳細的內容可以去百度查一下,這裡只要知道它合適作為分類任務的損失函數即可
有了損失函數,就可以衡量網路對給定樣本的輸出值與樣本的真值之間的差距,所以只要朝著減小這個差距的方向去改變網路的權重,就能夠使網路的輸出越來越接近真值,而這個改變權重的方法即梯度下降
什麼是梯度?
在此之前,我想應該都了解導數是什麼吧,進一步的,先說一下偏導數是什麼
簡單的栗子,一個二元(或多元)函數 ,如果要求y關於變數x1(或者x2)的偏導數 (或 ):則把另一個變數當做常數處理,然後求y關於該變數的導數即可
理解偏導數之後,梯度簡單的來說就是,有一個函數:
其中x是一個向量:
那麼該函數關於x的梯度 (或 )就是由n個偏導數組成的向量
而梯度下降說白了就是讓梯度減小,即讓各個分量的偏導減小