神經網絡識別手寫優化(二)

前言

本文接着一寫的,還是對之前實現的神經網絡進行一個優化。

DropOut

這個東西也是防止過擬合的。意思就是每一輪訓練完了之後,丟棄掉一些神經元。從而防止過擬合。

這是什麼原理?

因爲我們網絡的神經元過多,有些神經元把沒有泛化能力的特徵記錄了下來,通俗來說就是把無關緊要的東西記錄了下來。及時在訓練集上表現的特別好,cost會降到很低,但是在驗證集上反而會升高,因爲驗證集上的數據可能不包括那些無關緊要的東西。
這個好比如,讓計算機識別人類,給他很多張照片,照片上有很多朋友臉上有痣。神經元結構過於龐大,它們會把有痣這個特徵記憶下來,認爲有痣的
是人類的可能性很大。但是驗證集或者測試集上面很多沒有痣的朋友,計算機就認爲他不是個人。

解決方法
就是在網絡訓練過程中,丟棄掉一些神經元,從而改變網絡的結構。防止過擬合的發生。而丟棄哪些節點呢?一般都是隨機的….

交叉墒代價函數

在之前使用的代價函數是
損失函數
上一篇說了在後面可以加上一個正則項。但是這一項還是沒有發生改變。那麼這一項有什麼問題呢?
image.png

image.png

問題就出在sigmod’(z)的導數上面。看函數圖像
image.png

可以看出當w小於-4或者大於4的時候導數幾乎爲0。那麼w收斂會賊慢。那麼怎麼才能避免求sigmod的導數呢?只有引進一個損失函數,那就是交叉墒代價函數。
image.png
這個並不複雜。其中激勵函數等於。
image.png
下面我們一步一步的進行推導:
image.png

其實不難的,大家一步一步來,就是高數的鏈式法則。
同理看看權重的導數。
image.png
這裏就沒有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
發佈了47 篇原創文章 · 獲贊 80 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章