除了L2正則化,還有一個非常實用的正則化方法----dropout(隨機失活),下面介紹其工作原理。
假設你在訓練下圖左邊的這樣的神經網絡,它存在過擬合情況,這就是dropout所要處理的。我們復制這個神經網絡,dropout會遍歷網絡每一層,並設置一個消除神經網絡中節點的概率。

假設網絡中的每一層,每個節點都以拋硬幣的方式設置概率,每個節點得以保留和消除的概率都是0.5,設置完節點之后,我們會消除一些節點,然后刪掉從該節點進出的連線,如下圖,最后得到一個節點更少,規模更小的網絡,然后用backprop方法進行訓練。對於每個訓練樣本(每一個mini-batch),我們都將重復上述操作,以一定的概率消除網絡節點,得到一個精簡后的神經網絡,然后訓練這個神經網絡。

如何實施dropout呢?方法有幾種,下面介紹最常見的,即inverted dropout(反向隨機失活)。
下面我們用一個三層(L=3)的網絡來舉例說明。下面只舉例說明如何在某一層中實施dropout。
首先要定義向量d,對d3表示第三層的dropout向量。
d3 = np.random.rand(a3.shape[0], a3.shape[1]) < keep_prob
看d3是否小於某個數keep_prob,keep_prob是一個具體數字,上面的示例中它是0.5,本例中設置keep_prob=0.8,它表示保留某個隱藏單元的概率,即此處意味着消除任意一個隱藏單元的概率是0.2。 它的作用是生成隨機矩陣,如果對a3進行因子分解,效果也是一樣的。d3是一個矩陣,其中d3中值為1的概率都是0.8,值為0的概率是20%。接下來要做的就是從第三層中獲取激活函數,這里我們叫它a3,a3含有要計算的激活函數
a3=np.multiply(a3, d3) #a3*=d3
注:上面是對應元素相乘
它的作用就是過濾d3中所有等於0的元素。而各個元素等於0的概率只有20%,乘法運算最終把a3中相應的元素歸零。
如果用python實現的話,d3就是一個布爾型數組,值為true或者false,而不是1或0。乘法運算依舊有效,python會把true和false翻譯為1和0
最后我們向外擴展a3,即除以keep_prob參數
a3 /= keep_prob #所謂的dropout方法,功能是不論keep_prob的值時多少,反向隨機失活(inverted dropout)方法通過除以keep_prob,以確保a3的期望值不變。
下面解釋為什么要這么做
方便起見,假設第三層隱藏層有50個神經元,在一維上a3是50,我們通過因子分解將它拆分成50xm維的,保留和刪除它們的概率分別是80%和20%,這意味着最后被刪除或者歸零的神經元平均有10個。
我們現在看看z4

我們的預期是a3減少20%,也就是說a3中有20%的元素被歸零,為了不影響z4的期望值,我們需要用w4*a3除以0.8,它將會修正或者說彌補我們所需的那20%,因此a3的期望值不會變。
事實證明,在測試階段,當我們評估一個神經網絡時,inverted dropout使得測試階段變得更容易,因為它的數據擴展變得更容易。
目前實施dropout最常用的方法就是Inverted dropout
現在你使用的是d向量,你會發現不同的訓練樣本,清除不同的隱藏單元也不同,事實上,如果你通過相同訓練集多次傳遞數據,每次訓練數據的梯度不同,則隨機對不同隱藏單元歸零。
向量d或者d3用來決定第三層中哪些單元歸零,無論在前向傳播還是在反向傳播的時候
如何在測試階段訓練算法?
在測試階段,我們已經給出了x或者想預測變量,用的是標准計數法,a0表示第0層的激活函數標注為測試樣本x,我們在測試階段不使用dropout函數,尤其是像下面這種情況:

以此類推,直到最后一層預測值為y’
顯然,在測試階段,我們並沒有使用dropout,自然也不需要隨機將神經元失活,因為在測試階段進行預測時,我們不期望輸出的結果是隨機的,如果在測試階段應用dropout函數,預測會受到干擾,理論上,你只需要多次運行預測處理過程,每一次不同的隱藏單元會被隨機歸零,遍歷它們並進行預測處理,這樣得出的結果也幾乎相同,但是計算效率低。
Inverted dropout函數除以keep_prob( /=keep_prob )這一操作,目的是確保即使是在測試階段不執行dropout來調整數值范圍,激活函數的預期結果也不會發生變化,所以沒有必要在測試階段額外添加尺度參數,這與訓練階段不同
內容主要來自與:
Andrew Ng的改善深層神經網絡:超參數調試、正則化以及優化課程
