你是如何提升深度學(xué)習(xí)模型的效果? 這是我經(jīng)常被問(wèn)到的一個(gè)問(wèn)題。 有時(shí)候也會(huì)換一種問(wèn)法: 我該如何提高模型的準(zhǔn)確率呢? ……或者反過(guò)來(lái)問(wèn): 如果我的網(wǎng)絡(luò)模型效果不好,我該怎么辦? 通常我的回答是: “具體原因我不清楚,但我有一些想法可以試試?!?/span> 然后我會(huì)列舉一些我認(rèn)為能夠提升性能的方法。 為了避免重復(fù)羅列這些內(nèi)容,我打算在本文中把它們都寫(xiě)出來(lái)。 這些想法不僅可以用于深度學(xué)習(xí), 事實(shí)上可以用在任何機(jī)器學(xué)習(xí)的算法上。 提升算法性能的想法 這個(gè)列表并不完整,卻是很好的出發(fā)點(diǎn)。 我的目的是給大家拋出一些想法供大家嘗試,或許有那么一兩個(gè)有效的方法。 往往只需要嘗試一個(gè)想法就能得到提升。 如果你用下面某一種想法取得了好效果,可以分享給更多的人,當(dāng)然你也可能有其它更好的想法。 我把這個(gè)列表劃分為四塊:
性能提升的力度按上表的順序從上到下依次遞減。舉個(gè)例子,新的建模方法或者更多的數(shù)據(jù)帶來(lái)的效果提升往往好于調(diào)出最優(yōu)的參數(shù)。但這并不是絕對(duì)的,只是大多數(shù)情況下如此。 我在文章中添加了不少經(jīng)典神經(jīng)網(wǎng)絡(luò)問(wèn)題。 其中有一些想法只是針對(duì)人工神經(jīng)網(wǎng)絡(luò),但大多數(shù)想法都是通用性的。你可以將它們與其它技術(shù)結(jié)合起來(lái)使用。 1.從數(shù)據(jù)上提升性能 調(diào)整訓(xùn)練數(shù)據(jù)或是問(wèn)題的抽象定義方法可能會(huì)帶來(lái)巨大的效果改善。甚至是最顯著的改善。 下面是概覽:
1)收集更多的數(shù)據(jù) 你還能收集到更多的訓(xùn)練數(shù)據(jù)嗎? 你的模型的質(zhì)量往往取決于你的訓(xùn)練數(shù)據(jù)的質(zhì)量。你需要確保使用的數(shù)據(jù)是針對(duì)問(wèn)題最有效的數(shù)據(jù),你還希望數(shù)據(jù)盡可能多。 深度學(xué)習(xí)和其它現(xiàn)代的非線性機(jī)器學(xué)習(xí)模型在大數(shù)據(jù)集上的效果更好,尤其是深度學(xué)習(xí)。這也是深度學(xué)習(xí)方法令人興奮的主要原因之一。 請(qǐng)看下面的圖片:
不總是數(shù)據(jù)閱讀效果越好,多數(shù)情況下如此。如果讓我選擇,我會(huì)選擇要更多的數(shù)據(jù)。 2) 產(chǎn)生更多的數(shù)據(jù) 深度學(xué)習(xí)算法往往在數(shù)據(jù)量大的時(shí)候效果好,我們?cè)谏弦还?jié)已經(jīng)提到過(guò)這一點(diǎn)。 如果由于某些原因你得不到更多的數(shù)據(jù),也可以制造一些數(shù)據(jù)。
這類做法通常被稱為數(shù)據(jù)擴(kuò)展或是數(shù)據(jù)生成,你可以使用生成模型,也可以用一些簡(jiǎn)單的小技巧。 舉個(gè)例子,若是用圖像數(shù)據(jù),簡(jiǎn)單地隨機(jī)選擇和平移已有的圖像就能取得很大的提升。它能提升模型的泛化能力,如果新的數(shù)據(jù)中包含這類變換就能得到很好的處理。 有時(shí)候是往數(shù)據(jù)中增加噪聲,這相當(dāng)于是一種規(guī)則方法,避免過(guò)擬合訓(xùn)練數(shù)據(jù)。 3) 對(duì)數(shù)據(jù)做縮放 此方法簡(jiǎn)單有效。 使用神經(jīng)網(wǎng)絡(luò)模型的一條經(jīng)驗(yàn)法寶就是: 將數(shù)據(jù)縮放到激活函數(shù)的閾值范圍。 如果你使用sigmoid激活函數(shù),將數(shù)據(jù)縮放到0~1之間。如果選用tanh激活函數(shù),將值域控制在-1~1之間。 輸入、輸出數(shù)據(jù)都經(jīng)過(guò)同樣的變換。比如,如果在輸出層有一個(gè)sigmoid函數(shù)將輸出值轉(zhuǎn)換為二值數(shù)據(jù),則將輸出的y歸一化為二進(jìn)制。如果選用的是softmax函數(shù),對(duì)y進(jìn)行歸一化還是有效的。 我還建議你將訓(xùn)練數(shù)據(jù)擴(kuò)展生成多個(gè)不同的版本:
然后在每個(gè)數(shù)據(jù)集上測(cè)試模型的性能,選用最好的一組生成數(shù)據(jù)。 如果更換了激活函數(shù),最好重復(fù)做一次這個(gè)小實(shí)驗(yàn)。 在模型中不適合計(jì)算大的數(shù)值。此外,還有許多其它方法來(lái)壓縮模型中的數(shù)據(jù),比如對(duì)權(quán)重和激活值做歸一化,我會(huì)在后面介紹這些技巧。 4) 對(duì)數(shù)據(jù)做變換 與上一節(jié)的方法相關(guān),但是需要更多的工作量。 你必須真正了解所用到的數(shù)據(jù)。數(shù)據(jù)可視化,然后挑出異常值。 先猜測(cè)每一列數(shù)據(jù)的分布:
憑你的直覺(jué),嘗試幾種方法:
神經(jīng)網(wǎng)絡(luò)有特征學(xué)習(xí)的功能,它們能夠完成這些事情。 不過(guò)你若是可以將問(wèn)題的結(jié)構(gòu)更好地呈現(xiàn)出來(lái),網(wǎng)絡(luò)模型學(xué)習(xí)的速度就會(huì)更快。 在訓(xùn)練集上快速嘗試各種變換方法,看看哪些方法有些,而哪些不起作用。 5) 特征選擇 神經(jīng)網(wǎng)絡(luò)受不相關(guān)數(shù)據(jù)的影響很小,它們會(huì)對(duì)此賦予一個(gè)趨近于0的權(quán)重,幾乎忽略此特征對(duì)預(yù)測(cè)值的貢獻(xiàn)。 你是否可以移除訓(xùn)練數(shù)據(jù)的某些屬性呢? 我們有許多的特征選擇方法和特征重要性方法來(lái)鑒別哪些特征可以保留,哪些特征需要移除。 如果你的時(shí)間充裕,我還是建議在相同的神經(jīng)網(wǎng)絡(luò)模型上選擇嘗試多個(gè)方法,看看它們的效果分別如何。
6) 問(wèn)題重構(gòu) 在回到你問(wèn)題的定義上來(lái)。 你所收集到的這些觀測(cè)數(shù)據(jù)是描述問(wèn)題的唯一途徑嗎? 也許還有其它的途徑。也許其它途徑能更清晰地將問(wèn)題的結(jié)構(gòu)暴露出來(lái)。 我自己非常喜歡這種練習(xí),因?yàn)樗鼜?qiáng)迫我們拓寬思路。很難做好。尤其是當(dāng)你已經(jīng)投入大量的時(shí)間、精力、金錢在現(xiàn)有的方法上。 即使你列舉了3 ~ 5種不同的方式,至少你對(duì)最后所選用的方式有充足的信心。
深入思考問(wèn)題是一個(gè)好習(xí)慣,最好在選擇工具下手之前先完成上述步驟,以減少無(wú)效的精力投入。 無(wú)論如何,如果你正束手無(wú)策,這個(gè)簡(jiǎn)單的連續(xù)能讓你思如泉涌。 另外,你也不必拋棄前期的大量工作,詳情可以參見(jiàn)后面的章節(jié)。 2. 從算法上提升性能 機(jī)器學(xué)習(xí)總是與算法相關(guān),所有的理論和數(shù)學(xué)知識(shí)都在描述從數(shù)據(jù)中學(xué)習(xí)決策過(guò)程的不同方法(如果我們這里僅討論預(yù)測(cè)模型)。 你選用深度學(xué)習(xí)來(lái)求解,它是不是最合適的技術(shù)呢? 在這一節(jié)中,我們會(huì)簡(jiǎn)單地聊一下算法的選擇,后續(xù)內(nèi)容會(huì)具體介紹如何提升深度學(xué)習(xí)的效果。 下面是概覽:
1) 算法的篩選 你事先不可能知道哪種算法對(duì)你的問(wèn)題效果最好,如果你已經(jīng)知道,你可能也就不需要機(jī)器學(xué)習(xí)了。 你有哪些證據(jù)可以證明現(xiàn)在已經(jīng)采用的方法是最佳選擇呢? 當(dāng)在所有可能出現(xiàn)的問(wèn)題上進(jìn)行效果評(píng)測(cè)時(shí),沒(méi)有哪一項(xiàng)單獨(dú)的算法效果會(huì)好于其它算法。所有的算法都是平等的。這就是天下沒(méi)有免費(fèi)的午餐理論的要點(diǎn)。 也許你選擇的算法并不是最適合你的問(wèn)題。 現(xiàn)在,我們不指望解決所有的問(wèn)題,但當(dāng)前的熱門算法也許并不適合你的數(shù)據(jù)集。 我的建議是先收集證據(jù),先假設(shè)有其它的合適算法適用于你的問(wèn)題。 篩選一些常用的算法,挑出其中適用的幾個(gè)。
采納效果較好的幾種方法,然后精細(xì)調(diào)解參數(shù)和數(shù)據(jù)來(lái)進(jìn)一步提升效果。 將你所選用的深度學(xué)習(xí)方法與上述這些方法比較,看看是否能擊敗他們? 也許你可以放棄深度學(xué)習(xí)模型轉(zhuǎn)而選擇更簡(jiǎn)單模型,訓(xùn)練的速度也會(huì)更快,而且模型易于理解。 2) 從文獻(xiàn)中學(xué)習(xí) 從文獻(xiàn)中“竊取”思路是一條捷徑。 其它人是否已經(jīng)做過(guò)和你類似的問(wèn)題,他們使用的是什么方法。 閱讀論文、書(shū)籍、問(wèn)答網(wǎng)站、教程以及Google給你提供的一切信息。 記下所有的思路,然后沿著這些方向繼續(xù)探索,這并不是重復(fù)研究,這是幫助你發(fā)現(xiàn)新的思路。 優(yōu)先選擇已經(jīng)發(fā)表的論文 ,已經(jīng)有許許多多的聰明人寫(xiě)下了很多有意思的事情。利用好這寶貴的資源吧。 3) 重采樣的方法 你必須明白自己模型的效果如何,你估計(jì)的模型效果是否可靠呢? 深度學(xué)習(xí)模型的訓(xùn)練速度很慢,這就意味著我們不能用標(biāo)準(zhǔn)的黃金法則來(lái)評(píng)判模型的效果,比如k折交叉驗(yàn)證。
另一方面,也可以讓數(shù)據(jù)集變得更小,采用更強(qiáng)的重采樣方法。 也許你會(huì)看到在采樣后的數(shù)據(jù)集上訓(xùn)練得到的模型效果與在全體數(shù)據(jù)集上訓(xùn)練得到的效果有很強(qiáng)的相關(guān)性。那么,你就可以用小數(shù)據(jù)集進(jìn)行模型的選擇,然后把最終選定的方法應(yīng)用于全體數(shù)據(jù)集上。 也許你可以任意限制數(shù)據(jù)集的規(guī)模,采樣一部分?jǐn)?shù)據(jù),用它們完成所有的訓(xùn)練任務(wù),你必須對(duì)模型效果的預(yù)測(cè)有十足的把握。 3. 從算法調(diào)優(yōu)上提升性能 你通過(guò)算法篩選往往總能找出一到兩個(gè)效果不錯(cuò)的算法。但想要達(dá)到這些算法的最佳狀態(tài)需要耗費(fèi)數(shù)日、數(shù)周甚至數(shù)月。 下面是一些想法,在調(diào)參時(shí)能有助于提升算法的性能。
你可能需要指定參數(shù)來(lái)多次(3-10次甚至更多)訓(xùn)練模型,以得到預(yù)計(jì)效果最好的一組參數(shù)。對(duì)每個(gè)參數(shù)都要不斷的嘗試。 1) 可診斷性 只有知道為何模型的性能不再有提升了,才能達(dá)到最好的效果。 是因?yàn)槟P瓦^(guò)擬合呢,還是欠擬合呢? 千萬(wàn)牢記這個(gè)問(wèn)題,千萬(wàn)。 模型總是處于這兩種狀態(tài)之間,只是程度不同罷了。 一種快速查看模型性能的方法就是每一步計(jì)算模型在訓(xùn)練集和驗(yàn)證集上的表現(xiàn),將結(jié)果繪制成圖表。 在訓(xùn)練集和驗(yàn)證集上測(cè)試模型的準(zhǔn)確率
經(jīng)常繪制類似的圖表,深入研究并比較不同的方法,以提高模型的性能。這些圖表也許是你最有價(jià)值的診斷工具,另一種有效的診斷方法是研究模型正確預(yù)測(cè)或是錯(cuò)誤預(yù)測(cè)的樣本。 在某些場(chǎng)景下,這種方法能給你提供一些思路。
2) 權(quán)重的初始化 有一條經(jīng)驗(yàn)規(guī)則:用小的隨機(jī)數(shù)初始化權(quán)重。 事實(shí)上,這可能已經(jīng)足夠了。但是這是你網(wǎng)絡(luò)模型的最佳選擇嗎? 不同的激活函數(shù)也可以有不同的應(yīng)對(duì)策略,但我不記得在實(shí)踐中存在什么顯著的差異。 保持你的模型結(jié)構(gòu)不變,試一試不同的初始化策略。 記住,權(quán)重值就是你模型需要訓(xùn)練的參數(shù)。幾組不同的權(quán)重值都能取得不錯(cuò)的效果,但你想得到更好的效果。
記住,修改權(quán)重初始化值的方法與修改激活函數(shù)或者目標(biāo)函數(shù)的效果相當(dāng)。 3) 學(xué)習(xí)率 調(diào)節(jié)學(xué)習(xí)率也能帶來(lái)效果提升。 這里也有一些探索的思路:
大的網(wǎng)絡(luò)模型需要更多的訓(xùn)練步驟,反之亦然。如果你添加了更多的神經(jīng)節(jié)點(diǎn)和網(wǎng)絡(luò)層,請(qǐng)加大學(xué)習(xí)率。 學(xué)習(xí)率與訓(xùn)練步驟、batch大小和優(yōu)化方法都有耦合關(guān)系。 4) 激活函數(shù) 也許你應(yīng)該選用ReLU激活函數(shù),僅僅因?yàn)樗鼈兊男Ч谩?nbsp;在ReLU之前流行sigmoid和tanh,然后是輸出層的softmax、線性和sigmoid函數(shù)。除此之外,我不建議嘗試其它的選擇。 這三種函數(shù)都試一試,記得把輸入數(shù)據(jù)歸一化到它們的值域范圍。 顯然,你需要根據(jù)輸出內(nèi)容的形式選擇轉(zhuǎn)移函數(shù)。 比方說(shuō),將二值分類的sigmoid函數(shù)改為回歸問(wèn)題的線性函數(shù),然后對(duì)輸出值進(jìn)行再處理。同時(shí),可能需要調(diào)整合適的損失函數(shù)。在數(shù)據(jù)轉(zhuǎn)換章節(jié)去尋找更多的思路吧。 5) 網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu) 調(diào)整網(wǎng)絡(luò)的拓?fù)浣Y(jié)構(gòu)也會(huì)有一些幫助。 你需要設(shè)計(jì)多少個(gè)節(jié)點(diǎn),需要幾層網(wǎng)絡(luò)呢? 別打聽(tīng)了,鬼知道是多少。 你必須自己找到一組合理的參數(shù)配置。
這是一個(gè)難題。越大的網(wǎng)絡(luò)模型有越強(qiáng)的表達(dá)能力,也許你就需要這樣一個(gè)。 更多晨的結(jié)構(gòu)提供了抽象特征的更多結(jié)構(gòu)化組合的可能,也許你也需要這樣一個(gè)網(wǎng)絡(luò)。 后期的網(wǎng)絡(luò)模型需要更多的訓(xùn)練過(guò)程,需要不斷地調(diào)節(jié)訓(xùn)練步長(zhǎng)和學(xué)習(xí)率。 6) batch和epoch batch的大小決定了梯度值,以及權(quán)重更新的頻率。一個(gè)epoch指的是訓(xùn)練集的所有樣本都參與了一輪訓(xùn)練,以batch為序。 你嘗試過(guò)不同的batch大小和epoch的次數(shù)嗎? 在前文中,我們已經(jīng)討論了學(xué)習(xí)率、網(wǎng)絡(luò)大小和epoch次數(shù)的關(guān)系。 深度學(xué)習(xí)模型常用小的batch和大的epoch以及反復(fù)多次的訓(xùn)練,這或許對(duì)你的問(wèn)題會(huì)有幫助。
嘗試設(shè)置一個(gè)近似于無(wú)限大的epoch次數(shù),然后快照一些中間結(jié)果,尋找效果最好的模型。 有些模型結(jié)構(gòu)對(duì)batch的大小很敏感。我覺(jué)得多層感知器對(duì)batch的大小很不敏感,而LSTM和CNN則非常敏感,但這都是仁者見(jiàn)仁。 7) 正則項(xiàng) 正則化是克服訓(xùn)練數(shù)據(jù)過(guò)擬合的好方法。 最近熱門的正則化方法是dropout,你試過(guò)嗎? Dropout方法在訓(xùn)練過(guò)程中隨機(jī)地略過(guò)一些神經(jīng)節(jié)點(diǎn),強(qiáng)制讓同一層的其它節(jié)點(diǎn)接管。簡(jiǎn)單卻有效的方法。
嘗試用各種懲罰措施和懲罰項(xiàng)進(jìn)行實(shí)驗(yàn),比如L1、L2和兩者之和。 8) 優(yōu)化方法和損失函數(shù) 以往主要的求解方法是隨機(jī)梯度下降,然而現(xiàn)在有許許多多的優(yōu)化器。 你嘗試過(guò)不同的優(yōu)化策略嗎? 隨機(jī)梯度下降是默認(rèn)的方法。先用它得到一個(gè)結(jié)果,然后調(diào)節(jié)不同的學(xué)習(xí)率、動(dòng)量值進(jìn)行優(yōu)化。 許多更高級(jí)的優(yōu)化方法都用到更多的參數(shù),結(jié)構(gòu)更復(fù)雜,收斂速度更快。這取決于你的問(wèn)題,各有利弊吧。 為了壓榨現(xiàn)有方法的更多潛力,你真的需要深入鉆研每個(gè)參數(shù),然后用網(wǎng)格搜索法測(cè)試不同的取值。過(guò)程很艱辛,很花時(shí)間,但值得去嘗試。 我發(fā)現(xiàn)更新/更流行的方法收斂速度更快,能夠快速了解某個(gè)網(wǎng)絡(luò)拓?fù)涞臐摿?,例如?/span>
你也可以探索其它的優(yōu)化算法,例如更傳統(tǒng)的算法(Levenberg-Marquardt)和比較新的算法(基因算法)。其它方法能給SGD創(chuàng)造好的開(kāi)端,便于后續(xù)調(diào)優(yōu)。 待優(yōu)化的損失函數(shù)則與你需要解決的問(wèn)題更相關(guān)。 不過(guò),也有一些常用的伎倆(比如回歸問(wèn)題常用MSE和MAE),換個(gè)損失函數(shù)有時(shí)也會(huì)帶來(lái)意外收獲。同樣,這可能也與你輸入數(shù)據(jù)的尺度以及所使用的激活函數(shù)相關(guān)。 9) Early Stopping 你可以在模型性能開(kāi)始下降的時(shí)候停止訓(xùn)練。 這幫我們節(jié)省了大量時(shí)間,也許因此就能使用更精細(xì)的重采樣方法來(lái)評(píng)價(jià)模型了。 early stopping也是防止數(shù)據(jù)過(guò)擬合的一種正則化方法,需要你在每輪訓(xùn)練結(jié)束后觀察模型在訓(xùn)練集和驗(yàn)證集上的效果。一旦模型在驗(yàn)證集上的效果下降了,則可以停止訓(xùn)練。你也可以設(shè)置檢查點(diǎn),保存當(dāng)時(shí)的狀態(tài),然后模型可以繼續(xù)學(xué)習(xí)。 4. 用融合方法提升效果 你可以將多個(gè)模型的預(yù)測(cè)結(jié)果融合,繼模型調(diào)優(yōu)之后,這是另一個(gè)大的提升領(lǐng)域。事實(shí)上,往往將幾個(gè)效果還可以的模型的預(yù)測(cè)結(jié)果融合,取得的效果要比多個(gè)精細(xì)調(diào)優(yōu)的模型分別預(yù)測(cè)的效果好。 我們來(lái)看一下模型融合的三個(gè)主要方向:
1) 模型融合 不必挑選出一個(gè)模型,而是將它們集成。 如果你訓(xùn)練了多個(gè)深度學(xué)習(xí)模型,每一個(gè)的效果都不錯(cuò),則將它們的預(yù)測(cè)結(jié)果取均值。 模型的差異越大,效果越好。舉個(gè)例子,你可以使用差異很大的網(wǎng)絡(luò)拓?fù)浜图记伞?nbsp; 如果每個(gè)模型都獨(dú)立且有效,那么集成后的結(jié)果效果更穩(wěn)定。 相反的,你也可以反過(guò)來(lái)做實(shí)驗(yàn)。 每次訓(xùn)練網(wǎng)絡(luò)模型時(shí),都以不同的方式初始化,最后的權(quán)重也收斂到不同的值。多次重復(fù)這個(gè)過(guò)程生成多個(gè)網(wǎng)絡(luò)模型,然后集成這些模型的預(yù)測(cè)結(jié)果。它們的預(yù)測(cè)結(jié)果會(huì)高度相關(guān),但對(duì)于比較難預(yù)測(cè)的樣本也許會(huì)有一點(diǎn)提升。 2) 視角融合 如上一節(jié)提到的,以不同的角度來(lái)訓(xùn)練模型,或是重新刻畫(huà)問(wèn)題。 我們的目的還是得到有用的模型,但是方式不同(如不相關(guān)的預(yù)測(cè)結(jié)果)。 你可以根據(jù)上文中提到的方法,對(duì)訓(xùn)練數(shù)據(jù)采取完全不同的縮放和變換技巧。 所選用的變化方式和問(wèn)題的刻畫(huà)角度差異越大,效果提升的可能性也越大,簡(jiǎn)單地對(duì)預(yù)測(cè)結(jié)果取均值是一個(gè)不錯(cuò)的方式。 3)stacking 你還可以學(xué)習(xí)如何將各個(gè)模型的預(yù)測(cè)結(jié)果相融合。 這被稱作是stacked泛化,或者簡(jiǎn)稱為stacking。 通常,可以用簡(jiǎn)單的線性回歸的方式學(xué)習(xí)各個(gè)模型預(yù)測(cè)值的權(quán)重。 把各個(gè)模型預(yù)測(cè)結(jié)果取均值的方法作為baseline,用帶權(quán)重的融合作為實(shí)驗(yàn)組。 - DataCastle -
|
|