夏乙 栗子 編譯自 Khanna.cc 量子位 報(bào)道 | 公眾號(hào) QbitAI
想要訓(xùn)練個(gè)深度神經(jīng)網(wǎng)絡(luò),也準(zhǔn)備好了可以直接用的數(shù)據(jù),要從哪里開始上手? 來自美國(guó)的Harry Khanna,精心編織了一套六步法。大家可以瞻仰一下,然后決定要不要行動(dòng)。 整個(gè)過程中,過擬合的問題時(shí)時(shí)刻刻都要注意。 1. 選個(gè)損失函數(shù)選擇怎樣的損失函數(shù),取決于需要解決怎樣的問題。 如果是回歸問題,就可以用均方誤差 (MSE) 損失函數(shù)。 
如果是分類問題,就用交叉熵 (Cross-Entropy) 損失函數(shù)。 只有兩類的話,要用二值交叉熵 (Binary Cross-Entropy) 。 如果遇到了不常見的問題,比如一次性學(xué)習(xí) (One-Shot Learning) ,可能就要自行定制一個(gè)損失方程了。 2. 選個(gè)初始架構(gòu)說到結(jié)構(gòu)化學(xué)習(xí),比如預(yù)測(cè)銷售情況,從全連接的隱藏層開始,是個(gè)不錯(cuò)的選擇。 這一層的激活數(shù) (Number of Activations) ,要在輸入神經(jīng)元與輸出神經(jīng)元的數(shù)量之間。 兩者取個(gè)平均數(shù),就可以。 像下面這樣的取法,也可以。 ? ? Ni,是輸入神經(jīng)元數(shù)。 No,是輸出神經(jīng)元數(shù)。 Ns,訓(xùn)練集里的樣本數(shù)。 a,尺度因子,在2到10之間選。 對(duì)計(jì)算機(jī)視覺領(lǐng)域的小伙伴來說,像ResNet這樣的架構(gòu),就很友好。 3. 擬合訓(xùn)練集這一步,最重要的超參數(shù),是學(xué)習(xí)率 (Learning Rate) (α) 。 不需要試錯(cuò),fast.ai的庫(kù)里面,有一個(gè)rate finder。 ? ? 只要寫兩行代碼,就可以得到一個(gè)學(xué)習(xí)率的曲線。 ? ? 在損失還在明顯下降的區(qū)域,選取學(xué)習(xí)率—— 比如,最陡部分的旁邊一點(diǎn)點(diǎn),損失仍在劇烈下降,沒有到平坦的地方。 上圖的話,10-4就可以。 如果,模型訓(xùn)練還是很慢,或者效果不好的話,可以用Adam優(yōu)化,代替初始架構(gòu)里的隨機(jī)梯度下降 (SGD) 優(yōu)化。 這時(shí)候,如果模型還是不能和訓(xùn)練集愉快玩耍,考慮一下學(xué)習(xí)率衰減 (Learning Rate Decay) —— 有指數(shù)衰減,離散階梯衰減 (Discrete Staircase Decay) ,甚至還有一些手動(dòng)方法,人類可以在損失不再下降的時(shí)候,自己把學(xué)習(xí)率 (α) 往下調(diào)。 其中,余弦型 (Cosine) 衰減,在一個(gè)回合 (Epoch) 開始的時(shí)候,衰減最慢,中間最快,結(jié)束時(shí)又最慢。 ? ? 然后,可以加上一個(gè)“重啟 (Restart) ”功能。這樣,每 (幾) 個(gè)回合開始時(shí),學(xué)習(xí)率都會(huì)回到沒有衰減的狀態(tài)。 遷移學(xué)習(xí)的話,要把開始幾層解凍 (Unfreeze) ,然后用差分學(xué)習(xí)率來訓(xùn)練神經(jīng)網(wǎng)絡(luò)。 如果,訓(xùn)練集還是不開心,還有另外幾個(gè)超參數(shù)可以調(diào)整—— · 隱藏層的unit數(shù) · 小批量 (Minibatch) 的大?。?4,128,256,512…… · 隱藏層數(shù) 還不行的話,就要看目標(biāo)能不能再細(xì)化一下。 
輸入的訓(xùn)練數(shù)據(jù),可能并沒有預(yù)測(cè)輸出值所需的有效信息。 舉個(gè)栗子,僅僅基于股票的歷史價(jià)格,來預(yù)測(cè)未來走勢(shì),就很難。 4. 擬合驗(yàn)證集這一步,是最難的,也最花時(shí)間。 怎樣才能解決訓(xùn)練集上的過擬合問題? 丟棄 (Dropout)把訓(xùn)練集中的一些神經(jīng)元,隨機(jī)清零。 
那么,概率 (p) 要怎么設(shè)置? 雖然,沒有萬能之法,但還是有一些可以嘗試的方法—— 找到p=0.25的最后一個(gè)線性層,對(duì)這之前 (包含本層) 的那些層,執(zhí)行隨機(jī)拋棄。 然后,在把p往上調(diào)到0.5的過程中,實(shí)驗(yàn)幾次。 如果還是不行,就給再往前的線性層,也執(zhí)行隨機(jī)丟棄操作,還是用p=0.25到0.5之間的范圍。 
并沒有通天大法,所以有時(shí)候還是要試錯(cuò),才能知道在哪些層里,取多大的p,更有效。 權(quán)重衰減/L2正則化 (Weight Decay/ L2 Regularization)第二小步,加上權(quán)重衰減。就是在損失函數(shù)里面添加一項(xiàng)—— ? ? λ,是正則化超參數(shù)。 wj,是權(quán)重矩陣w里面的特征j。 n,是權(quán)重矩陣w里的特征數(shù)。 過擬合的其中一個(gè)原因,就是權(quán)重大。而權(quán)重衰減,可以有效打擊大權(quán)重。 輸入歸一化 (Normalize Inputs)減少過擬合的第三小步,就是把輸入特征的均值和方差,各自除以訓(xùn)練集,歸一化。 特征x1除以訓(xùn)練樣本總數(shù)m,要等于0,方差要等于1。x2,x3…也一樣。 ? ?μ向量,維數(shù)等于單個(gè)訓(xùn)練樣本的輸入特征數(shù)。
x是一個(gè)n x m矩陣,n是輸入特征數(shù),m是訓(xùn)練樣本數(shù)。 x-μ,就是x的每一列都要減掉μ。 標(biāo)準(zhǔn)差歸一化的公式,看上去就比較熟悉了—— ? ?
注意,要?dú)w一化的是,除以訓(xùn)練樣本總數(shù)m,之后的均值和方差,不是除以每個(gè)樣本的特征數(shù)n。
再注意,是用訓(xùn)練集的均值和方差,不是驗(yàn)證集。 批量歸一化 (Batch Normalization)上一小步,歸一的是輸入特征,而這里,要把隱藏層神經(jīng)元的均值和方差歸一化。 和之前一樣的是,用了訓(xùn)練集的均值和方差,來調(diào)教驗(yàn)證集。 
△ 不支持一次吃太多不同的是,要一小批一小批地進(jìn)行,并非整個(gè)訓(xùn)練集一步到位。 這種情況下,可以使用均值和方差的指數(shù)加權(quán)平均 (exponentially weighted average) ,因?yàn)橛泻芏嗟木担秃芏嗟姆讲睢?/p> 多點(diǎn)訓(xùn)練數(shù)據(jù)、數(shù)據(jù)擴(kuò)增根據(jù)經(jīng)驗(yàn),過擬合最好的解決辦法,就是增加訓(xùn)練數(shù)據(jù),繼續(xù)訓(xùn)練。 如果沒有太多數(shù)據(jù),就只好做數(shù)據(jù)擴(kuò)增。計(jì)算機(jī)視覺最愛這種方法,調(diào)光,旋轉(zhuǎn),翻轉(zhuǎn)等等簡(jiǎn)單操作,都可以把一張圖變成好幾張。 
不過,在結(jié)構(gòu)化數(shù)據(jù)和自然語(yǔ)言處理中,數(shù)據(jù)擴(kuò)增就沒有什么栗子了。 梯度消失,梯度爆炸梯度消失 (Vanishing Gradients) ,是指梯度變得很小很小,以至于梯度下降的學(xué)習(xí)效果不怎么好。 梯度爆炸 (Exploding Gradients) ,是指梯度變得很大很大,超出了設(shè)備的計(jì)算能力。 解決這兩個(gè)問題,第一條路,就是用一種特殊的方式把權(quán)重矩陣初始化——名曰“He Initialization”。 不是第三人稱,是出自何愷明等2015年的論文: Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification。 把權(quán)重矩陣W[l],變成一個(gè)均值為零的高斯分布。標(biāo)準(zhǔn)差長(zhǎng)這樣: ? ? 效果意想不到的好,梯度消失和爆炸,都少有發(fā)生了。 如果是訓(xùn)練自然語(yǔ)言處理RNN,LSTM是首選,也是一種減少梯度消失或爆炸的方式。 出現(xiàn)NaN,很可能就是梯度爆炸了。 
一個(gè)簡(jiǎn)單粗暴的處理方式是,梯度裁剪 (Gradient Clipping) ,給梯度設(shè)一個(gè)上限。超出了限制,梯度就會(huì)被切。 神經(jīng)網(wǎng)絡(luò)架構(gòu)搜索有時(shí)候調(diào)整超參數(shù)沒什么用,不管怎么調(diào),驗(yàn)證集的loss還是比訓(xùn)練集高好多。 這時(shí)候就該好好看看神經(jīng)網(wǎng)絡(luò)的架構(gòu)了。 輸入里有太多特征、隱藏層太多激活數(shù),都可能會(huì)導(dǎo)致神經(jīng)網(wǎng)絡(luò)擬合了訓(xùn)練集里的噪音。 
這時(shí)候就要調(diào)整隱藏層的神經(jīng)元數(shù)量,或者增減隱藏層的數(shù)量。 這個(gè)過程需要試錯(cuò),可能要試過很多架構(gòu)才能找到一個(gè)好用的。 5. 在測(cè)試集上檢驗(yàn)性能當(dāng)神經(jīng)網(wǎng)絡(luò)在訓(xùn)練集和驗(yàn)證集上都表現(xiàn)良好,要保持警惕:優(yōu)化過程中,有可能一不小心在驗(yàn)證集上過擬合了。 上一步擬合驗(yàn)證集時(shí),超參數(shù)都向著在驗(yàn)證集上優(yōu)化的方向調(diào)整。于是,這些超參數(shù)有可能將驗(yàn)證集中的噪音考慮了進(jìn)去,模型對(duì)新數(shù)據(jù)的泛化能力可能很差。 所以,到了這一步,就要在一個(gè)沒見過的測(cè)試集上來運(yùn)行神經(jīng)網(wǎng)絡(luò),確認(rèn)還能取得和驗(yàn)證集上一樣的成績(jī)。 
如果在測(cè)試集上表現(xiàn)不好,就要通過增加新數(shù)據(jù)或者數(shù)據(jù)增強(qiáng)(data augmentation)的方式,擴(kuò)大驗(yàn)證集規(guī)模。 然后重復(fù)第4、5步。 注意:不要根據(jù)測(cè)試集損失來調(diào)整超參數(shù)!這樣只能得到一個(gè)對(duì)訓(xùn)練集、驗(yàn)證集和測(cè)試集都過擬合了的模型。 6. 在真實(shí)世界中檢驗(yàn)性能如果你訓(xùn)練了一個(gè)貓片識(shí)別器,就喂它一些你的貓片; 
如果你訓(xùn)練了一個(gè)新聞稿情緒識(shí)別器,就喂它一些微軟最近的新聞。 如果這個(gè)神經(jīng)網(wǎng)絡(luò)在訓(xùn)練、驗(yàn)證、測(cè)試集上表現(xiàn)都不錯(cuò),到了現(xiàn)實(shí)世界卻是個(gè)渣渣,那一定出了什么問題。比如說,有可能過擬合了測(cè)試集。 這時(shí)候就需要換個(gè)驗(yàn)證集、測(cè)試集,看看模型表現(xiàn)怎么樣。如果這個(gè)現(xiàn)實(shí)世界的渣渣依然表現(xiàn)良好,那么問題可能出在損失函數(shù)身上。 這種情況,還是挺少見的。 一般只要成功熬到第6步,模型在現(xiàn)實(shí)世界里都挺厲害的。 來,我們回顧一下剛才講的這么多,最后可以匯集成下面這個(gè)checklist: 量子位AI社群18群開始招募啦,歡迎對(duì)AI感興趣的同學(xué),加小助手微信qbitbot8入群;
此外,量子位專業(yè)細(xì)分群(自動(dòng)駕駛、CV、NLP、機(jī)器學(xué)習(xí)等)正在招募,面向正在從事相關(guān)領(lǐng)域的工程師及研究人員。
進(jìn)群請(qǐng)加小助手微信號(hào)qbitbot8,并務(wù)必備注相應(yīng)群的關(guān)鍵詞~通過審核后我們將邀請(qǐng)進(jìn)群。(專業(yè)群審核較嚴(yán),敬請(qǐng)諒解)
|