dropout 正則化(Dropout Regularization)
除了L2正則化度秘,還有一個非常實用的正則化方法——“Dropout(隨機失活)”乖仇,我們來看看它的工作原理幻枉。
假設(shè)你在訓(xùn)練上圖這樣的神經(jīng)網(wǎng)絡(luò)扔傅,它存在過擬合耍共,這就是dropout所要處理的,我們復(fù)制這個神經(jīng)網(wǎng)絡(luò)猎塞,dropout會遍歷網(wǎng)絡(luò)的每一層试读,并設(shè)置消除神經(jīng)網(wǎng)絡(luò)中節(jié)點的概率。假設(shè)網(wǎng)絡(luò)中的每一層荠耽,每個節(jié)點都以拋硬幣的方式設(shè)置概率钩骇,每個節(jié)點得以保留和消除的概率都是0.5,設(shè)置完節(jié)點概率铝量,我們會消除一些節(jié)點倘屹,然后刪除掉從該節(jié)點進出的連線,最后得到一個節(jié)點更少慢叨,規(guī)模更小的網(wǎng)絡(luò)纽匙,然后用backprop方法進行訓(xùn)練。
這是網(wǎng)絡(luò)節(jié)點精簡后的一個樣本拍谐,對于其它樣本烛缔,我們照舊以拋硬幣的方式設(shè)置概率馏段,保留一類節(jié)點集合,刪除其它類型的節(jié)點集合践瓷。對于每個訓(xùn)練樣本院喜,我們都將采用一個精簡后神經(jīng)網(wǎng)絡(luò)來訓(xùn)練它,這種方法似乎有點怪晕翠,單純遍歷節(jié)點喷舀,編碼也是隨機的,可它真的有效崖面。不過可想而知元咙,我們針對每個訓(xùn)練樣本訓(xùn)練規(guī)模極小的網(wǎng)絡(luò),最后你可能會認識到為什么要正則化網(wǎng)絡(luò)巫员,因為我們在訓(xùn)練極小的網(wǎng)絡(luò)。
如何實施dropout呢甲棍?
方法有幾種简识,接下來我要講的是最常用的方法,即inverted dropout(反向隨機失活)感猛,出于完整性考慮七扰,我們用一個三層(l=3)網(wǎng)絡(luò)來舉例說明。編碼中會有很多涉及到3的地方陪白。我只舉例說明如何在某一層中實施dropout颈走。
首先要定義向量d,d^([3])表示一個三層的dropout向量:
d3 = np.random.rand(a3.shape[0],a3.shape[1])
然后看它是否小于某數(shù)咱士,我們稱之為keep-prob立由,keep-prob是一個具體數(shù)字,上個示例中它是0.5序厉,而本例中它是0.8锐膜,它表示保留某個隱藏單元的概率,此處keep-prob等于0.8弛房,它意味著消除任意一個隱藏單元的概率是0.2道盏,它的作用就是生成隨機矩陣,如果對a^([3])進行因子分解文捶,效果也是一樣的荷逞。d^([3])是一個矩陣,每個樣本和每個隱藏單元粹排,其中d^([3])中的對應(yīng)值為1的概率都是0.8种远,對應(yīng)為0的概率是0.2,隨機數(shù)字小于0.8恨搓。它等于1的概率是0.8院促,等于0的概率是0.2筏养。
接下來要做的就是從第三層中獲取激活函數(shù),這里我們叫它a^([3])常拓,a^([3])含有要計算的激活函數(shù)渐溶,a^([3])等于上面的a^([3])乘以d^([3]),a3 =np.multiply(a3,d3)弄抬,這里是元素相乘茎辐,也可寫為a3*=d3,它的作用就是讓d^([3])中所有等于0的元素(輸出)掂恕,而各個元素等于0的概率只有20%拖陆,乘法運算最終把d^[3] 中相應(yīng)元素輸出,即讓d^([3])中0元素與a^([3])中相對元素歸零懊亡。
如果用python實現(xiàn)該算法的話依啰,d^([3])則是一個布爾型數(shù)組,值為true和false店枣,而不是1和0速警,乘法運算依然有效,python會把true和false翻譯為1和0鸯两,大家可以用python嘗試一下闷旧。
最后,我們向外擴展a^([3])钧唐,用它除以0.8忙灼,或者除以keep-prob參數(shù)。
a3/=keep-prob
下面我解釋一下為什么要這么做钝侠,為方便起見该园,我們假設(shè)第三隱藏層上有50個單元或50個神經(jīng)元,在一維上a^([3])是50机错,我們通過因子分解將它拆分成50×m維的爬范,保留和刪除它們的概率分別為80%和20%,這意味著最后被刪除或歸零的單元平均有10(50×20%=10)個弱匪,
現(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哑诊,它將會修正或彌補我們所需的那20%,a^([3])的期望值不會變及刻,劃線部分就是所謂的dropout方法镀裤。
它的功能是竞阐,不論keep-prop的值是多少0.8,0.9甚至是1暑劝,如果keep-prop設(shè)置為1骆莹,那么就不存在dropout,因為它會保留所有節(jié)點担猛。反向隨機失活(inverted dropout)方法通過除以keep-prob幕垦,確保a^([3])的期望值不變。
事實證明傅联,在測試階段先改,當(dāng)我們評估一個神經(jīng)網(wǎng)絡(luò)時,也就是用綠線框標(biāo)注的反向隨機失活方法蒸走,使測試階段變得更容易仇奶,因為它的數(shù)據(jù)擴展問題變少,我們將在下節(jié)課討論载碌。
據(jù)我了解猜嘱,目前實施dropout最常用的方法就是Inverted dropout,建議大家動手實踐一下嫁艇。Dropout早期的迭代版本都沒有除以keep-prob,所以在測試階段弦撩,平均值會變得越來越復(fù)雜步咪,不過那些版本已經(jīng)不再使用了。
現(xiàn)在你使用的是d向量益楼,你會發(fā)現(xiàn)猾漫,不同的訓(xùn)練樣本,清除不同的隱藏單元也不同感凤。實際上悯周,如果你通過相同訓(xùn)練集多次傳遞數(shù)據(jù),每次訓(xùn)練數(shù)據(jù)的梯度不同陪竿,則隨機對不同隱藏單元歸零禽翼,有時卻并非如此。比如族跛,需要將相同隱藏單元歸零闰挡,第一次迭代梯度下降時,把一些隱藏單元歸零礁哄,第二次迭代梯度下降時长酗,也就是第二次遍歷訓(xùn)練集時,對不同類型的隱藏層單元歸零桐绒。向量d或d^([3])用來決定第三層中哪些單元歸零夺脾,無論用foreprop還是backprop之拨,這里我們只介紹了foreprob。
如何在測試階段訓(xùn)練算法咧叭,在測試階段蚀乔,我們已經(jīng)給出了x,或是想預(yù)測的變量佳簸,用的是標(biāo)準(zhǔn)計數(shù)法乙墙。我用a^([0]),第0層的激活函數(shù)標(biāo)注為測試樣本x生均,我們在測試階段不使用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ù)測值為^y马胧。
顯然在測試階段汉买,我們并未使用dropout,自然也就不用拋硬幣來決定失活概率佩脊,以及要消除哪些隱藏單元了蛙粘,因為在測試階段進行預(yù)測時,我們不期望輸出結(jié)果是隨機的威彰,如果測試階段應(yīng)用dropout函數(shù)出牧,預(yù)測會受到干擾档插。
理論上堪嫂,你只需要多次運行預(yù)測處理過程满粗,每一次栓拜,不同的隱藏單元會被隨機歸零调煎,預(yù)測處理遍歷它們污茵,但計算效率低搞莺,得出的結(jié)果也幾乎相同更哄,與這個不同程序產(chǎn)生的結(jié)果極為相似邢笙。
Inverted dropout函數(shù)在除以keep-prob時可以記住上一步的操作啸如,目的是確保即使在測試階段不執(zhí)行dropout來調(diào)整數(shù)值范圍,激活函數(shù)的預(yù)期結(jié)果也不會發(fā)生變化氮惯,所以沒必要在測試階段額外添加尺度參數(shù)叮雳,這與訓(xùn)練階段不同。
l=keep-prob
為什么dropout會起作用呢筐骇?
為什么dropout會起作用呢债鸡?下一個筆記我們將更加直觀地了解dropout的具體功能。