前言
本文接着一寫的,還是對之前實現的神經網絡進行一個優化。
DropOut
這個東西也是防止過擬合的。意思就是每一輪訓練完了之後,丟棄掉一些神經元。從而防止過擬合。
這是什麼原理?
因爲我們網絡的神經元過多,有些神經元把沒有泛化能力的特徵記錄了下來,通俗來說就是把無關緊要的東西記錄了下來。及時在訓練集上表現的特別好,cost會降到很低,但是在驗證集上反而會升高,因爲驗證集上的數據可能不包括那些無關緊要的東西。
這個好比如,讓計算機識別人類,給他很多張照片,照片上有很多朋友臉上有痣。神經元結構過於龐大,它們會把有痣這個特徵記憶下來,認爲有痣的
是人類的可能性很大。但是驗證集或者測試集上面很多沒有痣的朋友,計算機就認爲他不是個人。
解決方法
就是在網絡訓練過程中,丟棄掉一些神經元,從而改變網絡的結構。防止過擬合的發生。而丟棄哪些節點呢?一般都是隨機的….
交叉墒代價函數
在之前使用的代價函數是
上一篇說了在後面可以加上一個正則項。但是這一項還是沒有發生改變。那麼這一項有什麼問題呢?
問題就出在sigmod’(z)的導數上面。看函數圖像
可以看出當w小於-4或者大於4的時候導數幾乎爲0。那麼w收斂會賊慢。那麼怎麼才能避免求sigmod的導數呢?只有引進一個損失函數,那就是交叉墒代價函數。
這個並不複雜。其中激勵函數等於。
下面我們一步一步的進行推導:
其實不難的,大家一步一步來,就是高數的鏈式法則。
同理看看權重的導數。
這裏就沒有sigmod的導數,導數直接抵消了。這樣學習就會很快了。
代碼部分
class CrossEntropyCost(object):
"""
交叉墒代價函數
"""
@staticmethod
def fn(a,y):
"""
避免出現nan,inf
nan_to_num 把這玩意改成數字
:param a:
:param y:
:return:
"""
return np.sum(np.nan_to_num(-y * np.log(a) - (1-y) * no.log(1-a)))
@staticmethod
def delta(z,a,y):
"""
:param z:無用
:param a:
:param y:
:return:
"""
return a-y