dropout 正則化(Dropout Regularization)
除了L2正則化,還有一個(gè)非常實(shí)用的正則化方法——“Dropout(隨機(jī)失活)”,我們來看看它的工作原理。
假設(shè)你在訓(xùn)練上圖這樣的神經(jīng)網(wǎng)絡(luò),它存在過擬合,這就是dropout所要處理的,我們復(fù)制這個(gè)神經(jīng)網(wǎng)絡(luò),dropout會(huì)遍歷網(wǎng)絡(luò)的每一層,并設(shè)置消除神經(jīng)網(wǎng)絡(luò)中節(jié)點(diǎn)的概率。假設(shè)網(wǎng)絡(luò)中的每一層,每個(gè)節(jié)點(diǎn)都以拋硬幣的方式設(shè)置概率,每個(gè)節(jié)點(diǎn)得以保留和消除的概率都是0.5,設(shè)置完節(jié)點(diǎn)概率,我們會(huì)消除一些節(jié)點(diǎn),然后刪除掉從該節(jié)點(diǎn)進(jìn)出的連線,最后得到一個(gè)節(jié)點(diǎn)更少,規(guī)模更小的網(wǎng)絡(luò),然后用backprop方法進(jìn)行訓(xùn)練。
這是網(wǎng)絡(luò)節(jié)點(diǎn)精簡(jiǎn)后的一個(gè)樣本,對(duì)于其它樣本,我們照舊以拋硬幣的方式設(shè)置概率,保留一類節(jié)點(diǎn)集合,刪除其它類型的節(jié)點(diǎn)集合。對(duì)于每個(gè)訓(xùn)練樣本,我們都將采用一個(gè)精簡(jiǎn)后神經(jīng)網(wǎng)絡(luò)來訓(xùn)練它,這種方法似乎有點(diǎn)怪,單純遍歷節(jié)點(diǎn),編碼也是隨機(jī)的,可它真的有效。不過可想而知,我們針對(duì)每個(gè)訓(xùn)練樣本訓(xùn)練規(guī)模極小的網(wǎng)絡(luò),最后你可能會(huì)認(rèn)識(shí)到為什么要正則化網(wǎng)絡(luò),因?yàn)槲覀冊(cè)谟?xùn)練極小的網(wǎng)絡(luò)。
如何實(shí)施dropout呢?
方法有幾種,接下來我要講的是最常用的方法,即inverted dropout(反向隨機(jī)失活),出于完整性考慮,我們用一個(gè)三層(l=3)網(wǎng)絡(luò)來舉例說明。編碼中會(huì)有很多涉及到3的地方。我只舉例說明如何在某一層中實(shí)施dropout。
首先要定義向量d,d^([3])表示一個(gè)三層的dropout向量:
d3 = np.random.rand(a3.shape[0],a3.shape[1])
然后看它是否小于某數(shù),我們稱之為keep-prob,keep-prob是一個(gè)具體數(shù)字,上個(gè)示例中它是0.5,而本例中它是0.8,它表示保留某個(gè)隱藏單元的概率,此處keep-prob等于0.8,它意味著消除任意一個(gè)隱藏單元的概率是0.2,它的作用就是生成隨機(jī)矩陣,如果對(duì)a^([3])進(jìn)行因子分解,效果也是一樣的。d^([3])是一個(gè)矩陣,每個(gè)樣本和每個(gè)隱藏單元,其中d^([3])中的對(duì)應(yīng)值為1的概率都是0.8,對(duì)應(yīng)為0的概率是0.2,隨機(jī)數(shù)字小于0.8。它等于1的概率是0.8,等于0的概率是0.2。
接下來要做的就是從第三層中獲取激活函數(shù),這里我們叫它a^([3]),a^([3])含有要計(jì)算的激活函數(shù),a^([3])等于上面的a^([3])乘以d^([3]),a3 =np.multiply(a3,d3),這里是元素相乘,也可寫為a3*=d3,它的作用就是讓d^([3])中所有等于0的元素(輸出),而各個(gè)元素等于0的概率只有20%,乘法運(yùn)算最終把d^[3] 中相應(yīng)元素輸出,即讓d^([3])中0元素與a^([3])中相對(duì)元素歸零。
如果用python實(shí)現(xiàn)該算法的話,d^([3])則是一個(gè)布爾型數(shù)組,值為true和false,而不是1和0,乘法運(yùn)算依然有效,python會(huì)把true和false翻譯為1和0,大家可以用python嘗試一下。
最后,我們向外擴(kuò)展a^([3]),用它除以0.8,或者除以keep-prob參數(shù)。
a3/=keep-prob
下面我解釋一下為什么要這么做,為方便起見,我們假設(shè)第三隱藏層上有50個(gè)單元或50個(gè)神經(jīng)元,在一維上a^([3])是50,我們通過因子分解將它拆分成50×m維的,保留和刪除它們的概率分別為80%和20%,這意味著最后被刪除或歸零的單元平均有10(50×20%=10)個(gè),
現(xiàn)在我們看下z^([4]),z^([4])=w^([4]) a^([3])+b^([4]),我們的預(yù)期是,a^([3])減少20%,也就是說a^([3])中有20%的元素被歸零,為了不影響z^([4])的期望值,我們需要用w^([4]) a^([3])/0.8,它將會(huì)修正或彌補(bǔ)我們所需的那20%,a^([3])的期望值不會(huì)變,劃線部分就是所謂的dropout方法。
它的功能是,不論keep-prop的值是多少0.8,0.9甚至是1,如果keep-prop設(shè)置為1,那么就不存在dropout,因?yàn)樗鼤?huì)保留所有節(jié)點(diǎn)。反向隨機(jī)失活(inverted dropout)方法通過除以keep-prob,確保a^([3])的期望值不變。
事實(shí)證明,在測(cè)試階段,當(dāng)我們?cè)u(píng)估一個(gè)神經(jīng)網(wǎng)絡(luò)時(shí),也就是用綠線框標(biāo)注的反向隨機(jī)失活方法,使測(cè)試階段變得更容易,因?yàn)樗臄?shù)據(jù)擴(kuò)展問題變少,我們將在下節(jié)課討論。
據(jù)我了解,目前實(shí)施dropout最常用的方法就是Inverted dropout,建議大家動(dòng)手實(shí)踐一下。Dropout早期的迭代版本都沒有除以keep-prob,所以在測(cè)試階段,平均值會(huì)變得越來越復(fù)雜,不過那些版本已經(jīng)不再使用了。
現(xiàn)在你使用的是d向量,你會(huì)發(fā)現(xiàn),不同的訓(xùn)練樣本,清除不同的隱藏單元也不同。實(shí)際上,如果你通過相同訓(xùn)練集多次傳遞數(shù)據(jù),每次訓(xùn)練數(shù)據(jù)的梯度不同,則隨機(jī)對(duì)不同隱藏單元?dú)w零,有時(shí)卻并非如此。比如,需要將相同隱藏單元?dú)w零,第一次迭代梯度下降時(shí),把一些隱藏單元?dú)w零,第二次迭代梯度下降時(shí),也就是第二次遍歷訓(xùn)練集時(shí),對(duì)不同類型的隱藏層單元?dú)w零。向量d或d^([3])用來決定第三層中哪些單元?dú)w零,無論用foreprop還是backprop,這里我們只介紹了foreprob。
如何在測(cè)試階段訓(xùn)練算法,在測(cè)試階段,我們已經(jīng)給出了x,或是想預(yù)測(cè)的變量,用的是標(biāo)準(zhǔn)計(jì)數(shù)法。我用a^([0]),第0層的激活函數(shù)標(biāo)注為測(cè)試樣本x,我們?cè)跍y(cè)試階段不使用dropout函數(shù),尤其是像下列情況:
z^([1])=w^([1]) a^([0])+b^([1])
a^([1])=g^([1]) (z^([1]))
z^([2])= w^([2]) a^([1])+b^([2])
a^([2])=?
以此類推直到最后一層,預(yù)測(cè)值為^y。
顯然在測(cè)試階段,我們并未使用dropout,自然也就不用拋硬幣來決定失活概率,以及要消除哪些隱藏單元了,因?yàn)樵跍y(cè)試階段進(jìn)行預(yù)測(cè)時(shí),我們不期望輸出結(jié)果是隨機(jī)的,如果測(cè)試階段應(yīng)用dropout函數(shù),預(yù)測(cè)會(huì)受到干擾。
理論上,你只需要多次運(yùn)行預(yù)測(cè)處理過程,每一次,不同的隱藏單元會(huì)被隨機(jī)歸零,預(yù)測(cè)處理遍歷它們,但計(jì)算效率低,得出的結(jié)果也幾乎相同,與這個(gè)不同程序產(chǎn)生的結(jié)果極為相似。
Inverted dropout函數(shù)在除以keep-prob時(shí)可以記住上一步的操作,目的是確保即使在測(cè)試階段不執(zhí)行dropout來調(diào)整數(shù)值范圍,激活函數(shù)的預(yù)期結(jié)果也不會(huì)發(fā)生變化,所以沒必要在測(cè)試階段額外添加尺度參數(shù),這與訓(xùn)練階段不同。
l=keep-prob
為什么dropout會(huì)起作用呢?
為什么dropout會(huì)起作用呢?下一個(gè)筆記我們將更加直觀地了解dropout的具體功能。