導(dǎo)讀:在學(xué)習(xí)了有關(guān)深度學(xué)習(xí)的理論之后,很多人都會(huì)有興趣嘗試構(gòu)建一個(gè)屬于自己的項(xiàng)目。本文將會(huì)從第一步開(kāi)始,告訴你如何解決項(xiàng)目開(kāi)發(fā)中會(huì)遇到的各類(lèi)問(wèn)題。
本文由六大部分組成,涵蓋深度學(xué)習(xí) ( DL ) 項(xiàng)目的整個(gè)過(guò)程。我們將使用一個(gè)自動(dòng)漫畫(huà)著色項(xiàng)目來(lái)說(shuō)明深度學(xué)習(xí)的設(shè)計(jì)、程序調(diào)試和參數(shù)調(diào)整過(guò)程。
本文主題為「如何啟動(dòng)一個(gè)深度學(xué)習(xí)項(xiàng)目?」,分為以下六個(gè)部分:
第一部分:?jiǎn)?dòng)一個(gè)深度學(xué)習(xí)項(xiàng)目
第二部分:創(chuàng)建一個(gè)深度學(xué)習(xí)數(shù)據(jù)集
第三部分:設(shè)計(jì)深度模型
第四部分:可視化深度網(wǎng)絡(luò)模型及度量指標(biāo)
第五部分:深度學(xué)習(xí)網(wǎng)絡(luò)中的調(diào)試
第六部分:改善深度學(xué)習(xí)模型性能及網(wǎng)絡(luò)調(diào)參
01 啟動(dòng)一個(gè)深度學(xué)習(xí)項(xiàng)目
1. 應(yīng)該選擇什么樣的項(xiàng)目?
很多人工智能項(xiàng)目其實(shí)并沒(méi)有那么嚴(yán)肅,做起來(lái)還很有趣。2017 年初,我著手啟動(dòng)了一個(gè)為日本漫畫(huà)上色的項(xiàng)目,并作為我對(duì)生成對(duì)抗網(wǎng)絡(luò) ( GAN ) 研究的一部分。這個(gè)問(wèn)題很難解決,但卻很吸引人,尤其是對(duì)于我這種不會(huì)畫(huà)畫(huà)的人來(lái)說(shuō)!在尋找項(xiàng)目時(shí),不要局限于增量性改進(jìn),去做一款適銷(xiāo)對(duì)路的產(chǎn)品,或者創(chuàng)建一種學(xué)習(xí)速度更快、質(zhì)量更高的新模型。
2. 調(diào)試深度網(wǎng)絡(luò)(DN)非常棘手
訓(xùn)練深度學(xué)習(xí)模型需要數(shù)百萬(wàn)次的迭代,因此查找 bug 的過(guò)程非常艱難,而且容易崩壞。因此我們要從簡(jiǎn)單的地方著手,循序漸進(jìn),例如模型的優(yōu)化(如正則化)始終可以在代碼調(diào)試完成后進(jìn)行。此外,我們還需要經(jīng)??梢暬A(yù)測(cè)結(jié)果和模型度量標(biāo)準(zhǔn),并且我們首先需要令模型跑起來(lái),這樣就有一個(gè)可以后退的基線。我們最好不要陷在一個(gè)很大的模型,并嘗試將所有的模塊都弄好。
3. 度量和學(xué)習(xí)
宏偉的項(xiàng)目計(jì)劃可能帶慘烈的失敗。多數(shù)個(gè)人項(xiàng)目的第一個(gè)版本會(huì)持續(xù)兩到四個(gè)月,這個(gè)時(shí)間非常短暫,因?yàn)檠芯?、調(diào)試和實(shí)驗(yàn)都需要花費(fèi)大量的時(shí)間。一般我們安排這些復(fù)雜的實(shí)驗(yàn),使其通宵運(yùn)行,到第二天清晨時(shí),我們希望得到足夠的信息來(lái)采取下一步行動(dòng)。在早期階段,這些實(shí)驗(yàn)不應(yīng)超過(guò) 12 小時(shí),這是一條良好的經(jīng)驗(yàn)法則。為了做到這一點(diǎn),我們將漫畫(huà)上色項(xiàng)目范圍縮小到單個(gè)動(dòng)畫(huà)人物的上色。此外,我們需要設(shè)計(jì)很多測(cè)試,因此借助它們分析模型在實(shí)驗(yàn)中的不足之處。一般這些測(cè)試不要計(jì)劃得太遠(yuǎn),我們需要快速度量、學(xué)習(xí),并為下一步設(shè)計(jì)提供足夠的反饋。
4. 研究與產(chǎn)品
當(dāng)我們?cè)?2017 年春季開(kāi)始討論漫畫(huà)上色項(xiàng)目時(shí),Kevin Frans 有一個(gè) Deepcolor 項(xiàng)目,用 GAN 為漫畫(huà)添加色彩提示。
在確定目標(biāo)時(shí),你會(huì)花很大力氣來(lái)確保項(xiàng)目完成后仍然具有意義。GAN 模型相當(dāng)復(fù)雜,2017 年初還沒(méi)達(dá)到嵌入產(chǎn)品所需的質(zhì)量水準(zhǔn)。然而,如果你把應(yīng)用范圍縮小到產(chǎn)品可以巧妙處理的程度,你就可以把質(zhì)量提高到商用水準(zhǔn)。為此,無(wú)論著手啟動(dòng)何種 DL 項(xiàng)目,都要把握好模型泛化、容量和準(zhǔn)確性之間的平衡。
5. 成本
必須使用 GPU 來(lái)訓(xùn)練實(shí)際模型。它比 CPU 快 20 到 100 倍。價(jià)格最低的亞馬遜 GPU p2.xlarge 站點(diǎn)實(shí)例要價(jià) 7.5 美元/天,而 8 核 GPU 的價(jià)格則高達(dá) 75 美元/天。在我們的漫畫(huà)上色項(xiàng)目中,一些實(shí)驗(yàn)花費(fèi)的時(shí)間就超過(guò)兩天,因此平均每周花費(fèi)至少需要 150 美元。至于更快的 AWS 實(shí)例,花費(fèi)可能高達(dá) 1500 美元/周。我們可以購(gòu)買(mǎi)獨(dú)立計(jì)算機(jī),而不是使用云計(jì)算。2018 年 2 月,搭載 Nvidia GeForce GTX 1080 Ti 的臺(tái)式機(jī)售價(jià)約為 2200 美元。在訓(xùn)練精調(diào)的 VGG 模型時(shí),它比 P2 實(shí)例大約要快 5 倍。
6. 時(shí)間線
我們將開(kāi)發(fā)分為四個(gè)階段,最后三個(gè)階段在多次迭代中進(jìn)行。
項(xiàng)目研究
模型設(shè)計(jì)
實(shí)現(xiàn)及調(diào)試
實(shí)驗(yàn)及調(diào)參
項(xiàng)目研究
我們會(huì)先對(duì)現(xiàn)有產(chǎn)品進(jìn)行研究,以探索它們的弱點(diǎn)。許多 GAN 類(lèi)型的解決方案使用空間顏色提示,圖案有點(diǎn)不清晰,有時(shí)還會(huì)出現(xiàn)顏色混雜。我們?yōu)樽约旱捻?xiàng)目設(shè)定了兩個(gè)月的時(shí)間框架,其中有兩個(gè)優(yōu)先事項(xiàng):生成不帶提示的顏色及提高顏色保真度。我們的目標(biāo)是:
在單個(gè)動(dòng)畫(huà)角色上為灰度漫畫(huà)著色,且不使用空間顏色提示。
站在巨人的肩膀上
接下來(lái),我們需要了解相關(guān)的研究和開(kāi)源項(xiàng)目,許多人在開(kāi)始實(shí)踐之前至少要看幾十篇論文和項(xiàng)目。例如,當(dāng)我們深入研究 GAN 時(shí),發(fā)現(xiàn)有十幾個(gè)新的 GAN 模型: DRAGAN、cGAN、LSGAN 等,閱讀研究論文可能會(huì)很痛苦,但非常有意義。
深度學(xué)習(xí) ( DL ) 代碼簡(jiǎn)練,但很難排查缺陷,且很多研究論文常常遺漏了實(shí)現(xiàn)細(xì)節(jié)。許多項(xiàng)目始于開(kāi)源實(shí)現(xiàn),解決的問(wèn)題也很相似,因此我們可以多多搜索開(kāi)源項(xiàng)目。因此我們?cè)?GitHub 上查看了不同 GAN 變體的代碼實(shí)現(xiàn),并對(duì)它們進(jìn)行若干次測(cè)試。
02 創(chuàng)建一個(gè)深度學(xué)習(xí)數(shù)據(jù)集
深度學(xué)習(xí)項(xiàng)目的成功取決于數(shù)據(jù)集的質(zhì)量。在本文的第 2 部分中,我們將探討創(chuàng)建優(yōu)質(zhì)訓(xùn)練數(shù)據(jù)集的核心問(wèn)題。
1. 公開(kāi)及學(xué)術(shù)數(shù)據(jù)集
對(duì)于研究項(xiàng)目,可以搜索已建立的公開(kāi)數(shù)據(jù)集。這些數(shù)據(jù)集可以提供更整齊的樣本和基線模型性能。如果你有多個(gè)可用的公開(kāi)數(shù)據(jù)集,請(qǐng)選擇與你的問(wèn)題最相關(guān)且質(zhì)量最好的樣本。
2. 自定義數(shù)據(jù)集
對(duì)于實(shí)際問(wèn)題,我們需要來(lái)自問(wèn)題領(lǐng)域的樣本。首先嘗試查找公共數(shù)據(jù)集。關(guān)于創(chuàng)建高質(zhì)量自定義數(shù)據(jù)集的研究還有所欠缺。如果沒(méi)有可用的資料,請(qǐng)搜尋你可以抓取數(shù)據(jù)的位置。該位置通常有很多參考,但數(shù)據(jù)質(zhì)量通常較低,還需要投入大量精力進(jìn)行整理。在抓取樣本之前,要專(zhuān)門(mén)抽出時(shí)間評(píng)估所有選項(xiàng)并選擇最相關(guān)的選項(xiàng)。
高質(zhì)量數(shù)據(jù)集應(yīng)該包括以下特征:
類(lèi)別均衡
數(shù)據(jù)充足
數(shù)據(jù)和標(biāo)記中有高質(zhì)量信息
數(shù)據(jù)和標(biāo)記錯(cuò)誤非常小
與你的問(wèn)題相關(guān)
不要一次爬取所有數(shù)據(jù)。我們經(jīng)常借助標(biāo)簽和分類(lèi)來(lái)抓取網(wǎng)站樣本,從而獲取與我們的問(wèn)題相關(guān)的數(shù)據(jù)。最好的爬取方法是在你的模型中訓(xùn)練、測(cè)試少量樣本,并根據(jù)得到的經(jīng)驗(yàn)教訓(xùn)改善抓取方法。
清理你抓取的數(shù)據(jù)非常重要,否則,即使最好的模型設(shè)計(jì)也達(dá)不到與人類(lèi)水平相當(dāng)?shù)谋憩F(xiàn)。Danbooru 和 Safebooru 是兩個(gè)非常受歡迎的動(dòng)漫人物來(lái)源,但是一些深入學(xué)習(xí)的應(yīng)用程序偏愛(ài) Getchu,以獲得更高質(zhì)量的繪圖。我們可以使用一組標(biāo)簽從 Safebooru 下載圖像,并直觀地檢查樣本并運(yùn)行測(cè)試來(lái)分析錯(cuò)誤(表現(xiàn)不佳的樣本)。
模型訓(xùn)練和視覺(jué)評(píng)估都提供了進(jìn)一步的信息來(lái)細(xì)化我們的標(biāo)簽選擇。隨著迭代的繼續(xù),我們將學(xué)到更多,并逐漸進(jìn)行樣本積累。我們還需要使用分類(lèi)器進(jìn)一步過(guò)濾與問(wèn)題無(wú)關(guān)的樣本,如清除所有人物過(guò)小的圖像等。與學(xué)術(shù)數(shù)據(jù)集相比,小型項(xiàng)目收集的樣本很少,在適當(dāng)情況下可以應(yīng)用遷移學(xué)習(xí)。
下面的左圖由 PaintsChainer 提供,右圖由最終的模型上色:
我們決定用一些訓(xùn)練樣本來(lái)對(duì)算法進(jìn)行測(cè)試。結(jié)果并沒(méi)有給人驚喜,應(yīng)用的顏色較少,樣式也不正確。
由于對(duì)模型進(jìn)行了一段時(shí)間的訓(xùn)練,我們知道什么樣的繪圖表現(xiàn)欠佳。正如預(yù)期的那樣,結(jié)構(gòu)錯(cuò)綜復(fù)雜的繪圖更難上色。
這說(shuō)明好好選擇樣本非常重要。作為一款產(chǎn)品,PaintsChainer 專(zhuān)注于它們擅長(zhǎng)的線條類(lèi)型,這點(diǎn)非常明智。這次我使用了從互聯(lián)網(wǎng)上挑選的干凈線條藝術(shù),結(jié)果再次給人驚喜。
這里有一些經(jīng)驗(yàn)教訓(xùn):數(shù)據(jù)沒(méi)有好壞之分,只是有些數(shù)據(jù)不能滿足你的需求。此外,隨著樣本類(lèi)別的增加,訓(xùn)練和保持輸出質(zhì)量會(huì)變得更加困難,刪除不相關(guān)的數(shù)據(jù)可以得到一個(gè)更好的模型。
在開(kāi)發(fā)早期,我們認(rèn)識(shí)到一些繪圖有太多錯(cuò)綜復(fù)雜的結(jié)構(gòu)。在不顯著增加模型容量的情況下,這些繪圖在訓(xùn)練中產(chǎn)生的價(jià)值很小,因此最好不要使用,否則只會(huì)影響訓(xùn)練效率。
3. 重點(diǎn)回顧
盡可能使用公共數(shù)據(jù)集;
尋找可以獲取高質(zhì)量、多樣化樣本的最佳網(wǎng)站;
分析錯(cuò)誤并過(guò)濾掉與實(shí)際問(wèn)題無(wú)關(guān)的樣本;
迭代地創(chuàng)建你的樣本;
平衡每個(gè)類(lèi)別的樣本數(shù);
訓(xùn)練之前先整理樣本;
收集足夠的樣本。如果樣本不夠,應(yīng)用遷移學(xué)習(xí)。
03 深度學(xué)習(xí)設(shè)計(jì)
第三部分介紹了一些高層次的深度學(xué)習(xí)策略,接下來(lái)我們將詳細(xì)介紹最常見(jiàn)的設(shè)計(jì)選擇,這可能需要一些基本的 DL 背景。
1. 簡(jiǎn)單靈活
設(shè)計(jì)初始要簡(jiǎn)單、小巧。在學(xué)習(xí)階段,人們腦海中會(huì)充斥大量很酷的觀念。我們傾向于一次性把所有細(xì)節(jié)都編碼進(jìn)來(lái)。但這是不現(xiàn)實(shí)的,最開(kāi)始就想要超越頂尖的結(jié)果并不實(shí)際。從較少網(wǎng)絡(luò)層和自定義開(kāi)始設(shè)計(jì),后面再做一些必要的超參數(shù)精調(diào)方案。這些都需要查證損失函數(shù)一直在降低,不要一開(kāi)始就在較大的模型上浪費(fèi)時(shí)間。
在簡(jiǎn)短的 Debug 之后,我們的模型經(jīng)過(guò) 5000 次迭代產(chǎn)生了簡(jiǎn)單的結(jié)果。但至少該模型所上的顏色開(kāi)始限制在固定區(qū)域內(nèi),且膚色也有些顯露出來(lái)。
在模型是否開(kāi)始上色上,以上結(jié)果給了我們有價(jià)值的反饋。所以不要從大模型開(kāi)始,不然你會(huì)花費(fèi)大量時(shí)間 Debug 和訓(xùn)練模型。
2. 優(yōu)先性以及增量設(shè)計(jì)
首先為了創(chuàng)造簡(jiǎn)單的設(shè)計(jì),我們需要選出優(yōu)先項(xiàng)。把復(fù)雜問(wèn)題分解成小問(wèn)題,一步一步解決。做深度學(xué)習(xí)的正確策略是快速的執(zhí)行學(xué)到的東西。在跳到使用無(wú)暗示(no hints)模型之前,我們先使用帶有空間顏色暗示的模型。不要一步跳到「無(wú)暗示」模型設(shè)計(jì),例如我們首先去掉暗示中的空間信息,顏色質(zhì)量會(huì)急劇下降,所以我們轉(zhuǎn)變優(yōu)先性,在做下一步前先精煉我們的模型。在設(shè)計(jì)模型的過(guò)程中,我們會(huì)遇到許多驚喜。相比于做個(gè)要不斷改變的長(zhǎng)期計(jì)劃,還不如以?xún)?yōu)先性驅(qū)動(dòng)的計(jì)劃。使用更短、更小的設(shè)計(jì)迭代,從而保證項(xiàng)目可管理性。
3. 避免隨機(jī)改進(jìn)
首先分析自己模型的弱點(diǎn),而不是隨意地改進(jìn),例如用雙向 LSTM 或者 PReLU。我們需要根據(jù)可視化模型誤差(表現(xiàn)極差的場(chǎng)景)以及性能參數(shù)來(lái)確定模型問(wèn)題。隨意做改進(jìn)反而適得其反,會(huì)成比例的增加訓(xùn)練成本,而回報(bào)極小。
4. 限制
我們把限制應(yīng)用到網(wǎng)絡(luò)設(shè)計(jì),從而保證訓(xùn)練更高效。建立深度學(xué)習(xí)并不是簡(jiǎn)單的把網(wǎng)絡(luò)層堆在一起。增加好的限制(constraints)能使得學(xué)習(xí)更為有效,或者更智能。例如,應(yīng)用注意機(jī)制,能讓網(wǎng)絡(luò)知道注意哪里,在變分自編碼器中,我們訓(xùn)練隱藏因子使其服從正態(tài)分布。在設(shè)計(jì)中,我們應(yīng)用去噪方法通過(guò)歸零除去空間顏色暗示的大量分?jǐn)?shù)。啼笑皆非的是,這使得模型能更好地學(xué)習(xí)、泛化。
5. 設(shè)計(jì)細(xì)節(jié)
文章接下來(lái)的部分,將討論深度學(xué)習(xí)項(xiàng)目中會(huì)遇到的一些常見(jiàn)的設(shè)計(jì)選擇。
深度學(xué)習(xí)軟件框架
自谷歌 2015 年 11 月發(fā)布 TensorFlow 以來(lái),短短 6 個(gè)月就成為了最流行的深度學(xué)習(xí)框架。雖然短期看起來(lái)難有競(jìng)爭(zhēng)對(duì)手,但一年后 Facebook 就發(fā)布了 PyTorch,且極大的受研究社區(qū)的關(guān)注。到 2018 年,已經(jīng)有大量的深度學(xué)習(xí)平臺(tái)可供選擇,包括 TensorFlow、PyTorch、Caffe、Caffe2、MXNet、CNTK 等。
一些研究員之所以轉(zhuǎn)向 PyTorch 有一主要因素:PyTorch 設(shè)計(jì)上注重端用戶(hù)(end-user),API 簡(jiǎn)單且直觀。錯(cuò)誤信息可以直觀地理解,API 文檔也非常完整。PyTorch 中的特征,例如預(yù)訓(xùn)練模型、數(shù)據(jù)預(yù)處理、載入常用數(shù)據(jù)集都非常受歡迎。
TensorFlow 也非常棒,但目前為止它還是采用自下而上的方式,使其變得極為復(fù)雜。TensorFlow 的 API 很冗長(zhǎng),Debug 也不一樣,它大概有十幾種建立深度網(wǎng)絡(luò)的 API 模型。
截止到 2018 年 2 月,TensorFlow 依然獨(dú)占鰲頭。開(kāi)發(fā)者社區(qū)依然是是最大的。這是非常重要的因素。如果你想要用多個(gè)機(jī)器訓(xùn)練模型,或者把推理引擎部署到移動(dòng)手機(jī)上,TensorFlow 是唯一的選擇。然而,如果其他平臺(tái)變得更加專(zhuān)注端用戶(hù),我們可以預(yù)見(jiàn)將會(huì)有更多從小項(xiàng)目轉(zhuǎn)向中級(jí)項(xiàng)目。
隨著 TensorFlow 的發(fā)展,有很多 API 可供選擇來(lái)建立深度網(wǎng)絡(luò)。最高層的 API 是提供隱式積分的評(píng)估器,而 TensorBoard 提供了性能評(píng)估。最低層的 API 非常冗長(zhǎng),在許多模塊中都有。現(xiàn)在,它用封裝器 API 合并到了 tf.layers、tf.metrics 和 tf.losses 模塊,從而更容易地建立深度網(wǎng)絡(luò)層。
對(duì)想要更直觀 API 的研究者來(lái)說(shuō),還有 Keras、TFLearn、TF-Slim 等可以選擇,這些都可直接在 TensorFlow 上使用。我建議是選擇帶有所需要的預(yù)訓(xùn)練模型與工具(來(lái)下載數(shù)據(jù)集)的框架,此外在學(xué)術(shù)界,用 Keras API 做原型設(shè)計(jì)相當(dāng)流行。
遷移學(xué)習(xí)
不要做重復(fù)的工作。許多深度學(xué)習(xí)軟件平臺(tái)都有 VGG19、ResNet、Inception v3 這樣的預(yù)訓(xùn)練模型。從頭開(kāi)始訓(xùn)練非常耗費(fèi)時(shí)間。就像 2014 年 VGG 論文中所說(shuō)的,「VGG 模型是用 4 塊英偉達(dá) Titan Black GPU 訓(xùn)練的,根據(jù)架構(gòu)訓(xùn)練單個(gè)網(wǎng)絡(luò)需要 2-3 周的時(shí)間?!?/span>
許多預(yù)訓(xùn)練模型可用于解決深度學(xué)習(xí)難題。例如,我們使用預(yù)訓(xùn)練 VGG 模型提取圖像特征,并將這些特征反饋到 LSTM 模型來(lái)生成描述。許多預(yù)訓(xùn)練模型都用 ImageNet 數(shù)據(jù)集訓(xùn)練,如果你的目標(biāo)數(shù)據(jù)和 ImageNet 差別不大,我們將固定大部分模型參數(shù),只重新訓(xùn)練最后幾個(gè)完全連接的層。否則,我們就要使用訓(xùn)練數(shù)據(jù)集對(duì)整個(gè)網(wǎng)絡(luò)進(jìn)行端到端的重訓(xùn)練。但是在這兩種情況下,由于模型已經(jīng)過(guò)預(yù)訓(xùn)練,再訓(xùn)練所需的迭代將大大減少。由于訓(xùn)練時(shí)間較短,即使訓(xùn)練數(shù)據(jù)集不夠大,也可以避免過(guò)擬合。這種遷移學(xué)習(xí)在各個(gè)學(xué)科都很有效,例如用預(yù)先訓(xùn)練好的英語(yǔ)模型訓(xùn)練漢語(yǔ)模型。
然而,這種遷移學(xué)習(xí)僅適用于需要復(fù)雜模型來(lái)提取特征的問(wèn)題。在我們的項(xiàng)目中,我們的示例與 ImageNet 不同,我們需要對(duì)模型進(jìn)行端到端的重新訓(xùn)練。然而,當(dāng)我們只需要相對(duì)簡(jiǎn)單的潛在因素(顏色)時(shí),來(lái)自 VGG19 的訓(xùn)練復(fù)雜度太高。因此,我們決定建立一個(gè)新的更簡(jiǎn)單的 CNN 特征提取模型。
成本函數(shù)
并非所有的成本函數(shù)都是等價(jià)的,它會(huì)影響模型的訓(xùn)練難度。有些成本函數(shù)是相當(dāng)標(biāo)準(zhǔn)的,但有些問(wèn)題域需要仔細(xì)考慮。
分類(lèi)問(wèn)題:交叉熵,折頁(yè)損失函數(shù)(SVM)
回歸: 均方誤差(MSE)
對(duì)象檢測(cè)或分割:交并比(IoU)
策略?xún)?yōu)化:KL 散度
詞嵌入:噪音對(duì)比估計(jì)(NCE)
詞向量:余弦相似度
在理論分析中看起來(lái)不錯(cuò)的成本函數(shù)在實(shí)踐中可能不太好用。例如,GAN 中鑒別器網(wǎng)絡(luò)的成本函數(shù)采用了更為實(shí)用也更經(jīng)得起實(shí)驗(yàn)考驗(yàn)的方法,而不是理論分析中看起來(lái)不錯(cuò)的方法。在一些問(wèn)題域中,成本函數(shù)可以是部分猜測(cè)加部分實(shí)驗(yàn),也可以是幾個(gè)成本函數(shù)的組合。我們的項(xiàng)目始于標(biāo)準(zhǔn) GAN 成本函數(shù)。此外,我們還添加了使用 MSE 和其他正則化成本的重建成本。然而,如何找到更好的成本函數(shù)是我們項(xiàng)目中尚未解決的問(wèn)題之一,我們相信它將對(duì)色彩保真度產(chǎn)生重大影響。
度量標(biāo)準(zhǔn)
良好的度量標(biāo)準(zhǔn)有助于更好地比較和調(diào)整模型。對(duì)于特殊問(wèn)題,請(qǐng)查看 Kaggle 平臺(tái),該平臺(tái)組織了許多 DL 競(jìng)賽,并提供了詳細(xì)的度量標(biāo)準(zhǔn)。不幸的是,在我們的項(xiàng)目中,你很難定義一個(gè)精確的公式來(lái)衡量藝術(shù)渲染的準(zhǔn)確性。
正則化
L1 正則化和 L2 正則化都很常見(jiàn),但 L2 正則化在深度學(xué)習(xí)中更受歡迎。
L1 正則化有何優(yōu)點(diǎn)?L1 正則化可以產(chǎn)生更加稀疏的參數(shù),這有助于解開(kāi)底層表示。由于每個(gè)非零參數(shù)會(huì)往成本上添加懲罰,與 L2 正則化相比,L1 更加青睞零參數(shù),即與 L2 正則化中的許多微小參數(shù)相比,它更喜歡零參數(shù)。L1 正則化使過(guò)濾器更干凈、更易于解釋?zhuān)虼耸翘卣鬟x擇的良好選擇。L1 對(duì)異常值的脆弱性也較低,如果數(shù)據(jù)不太干凈,運(yùn)行效果會(huì)更好。然而,L2 正則化仍然更受歡迎,因?yàn)榻饪赡芨€(wěn)定。
梯度下降
始終密切監(jiān)視梯度是否消失或爆炸,梯度下降問(wèn)題有許多可能的原因,這些原因難以證實(shí)。不要跳至學(xué)習(xí)速率調(diào)整或使模型設(shè)計(jì)改變太快,小梯度可能僅僅由編程 Bug 引起,如輸入數(shù)據(jù)未正確縮放或權(quán)重全部初始化為零。
如果消除了其他可能的原因,則在梯度爆炸時(shí)應(yīng)用梯度截?cái)啵ㄌ貏e是對(duì)于 NLP)。跳過(guò)連接是緩解梯度下降問(wèn)題的常用技術(shù)。在 ResNet 中,殘差模塊允許輸入繞過(guò)當(dāng)前層到達(dá)下一層,這有效地增加了網(wǎng)絡(luò)的深度。
縮放
縮放輸入特征。我們通常將特征縮放為以零為均值在特定范圍內(nèi),如 [-1, 1]。特征的不適當(dāng)縮放是梯度爆炸或降低的一個(gè)最常見(jiàn)的原因。有時(shí)我們從訓(xùn)練數(shù)據(jù)中計(jì)算均值和方差,以使數(shù)據(jù)更接近正態(tài)分布。如果縮放驗(yàn)證或測(cè)試數(shù)據(jù),要再次利用訓(xùn)練數(shù)據(jù)的均值和方差。
批歸一化和層歸一化
每層激活函數(shù)之前節(jié)點(diǎn)輸出的不平衡性是梯度問(wèn)題的另一個(gè)主要來(lái)源,必要時(shí)需要對(duì) CNN 應(yīng)用批量歸一化(BN)。如果適當(dāng)?shù)貥?biāo)準(zhǔn)化(縮放)輸入數(shù)據(jù),DN 將學(xué)習(xí)得更快更好。在 BN 中,我們從每批訓(xùn)練數(shù)據(jù)中計(jì)算每個(gè)空間位置的均值和方差。例如,批大小為 16,特征圖具有 10 X10 的空間維度,我們計(jì)算 100 個(gè)平均值和 100 個(gè)方差(每個(gè)位置一個(gè))。每個(gè)位置處的均值是來(lái)自 16 個(gè)樣本的對(duì)應(yīng)位置平均值,我們使用均值和方差來(lái)重新歸一化每個(gè)位置的節(jié)點(diǎn)輸出。BN 提高了準(zhǔn)確度,同時(shí)縮短了訓(xùn)練時(shí)間。
然而,BN 對(duì) RNN 無(wú)效,我們需要使用層歸一化。在 RNN 中,來(lái)自 BN 的均值和方差不適合用來(lái)重新歸一化 RNN 單元的輸出,這可能是因?yàn)?RNN 和共享參數(shù)的循環(huán)屬性。在層歸一化中,輸出由當(dāng)前樣本的層輸出計(jì)算的平均值和方差重新歸一化。一個(gè)含有 100 個(gè)元素的層僅使用來(lái)自當(dāng)前輸入的一個(gè)平均值方差來(lái)重新歸一化該層。
Dropout
可以將 Dropout 應(yīng)用于層以歸一化模型。2015 年批量歸一化興起之后,dropout 熱度降低。批量歸一化使用均值和標(biāo)準(zhǔn)差重新縮放節(jié)點(diǎn)輸出。這就像噪聲一樣,迫使層對(duì)輸入中的變量進(jìn)行更魯棒的學(xué)習(xí)。由于批量歸一化也有助于解決梯度下降問(wèn)題,因此它逐漸取代了 Dropout。
結(jié)合 Dropout 和 L2 正則化的好處是領(lǐng)域特定的。通常,我們可以在調(diào)優(yōu)過(guò)程中測(cè)試 dropout,并收集經(jīng)驗(yàn)數(shù)據(jù)來(lái)證明其益處。
激活函數(shù)
在 DL 中,ReLU 是最常用的非線性激活函數(shù)。如果學(xué)習(xí)速率太高,則許多節(jié)點(diǎn)的激活值可能會(huì)處于零值。如果改變學(xué)習(xí)速率沒(méi)有幫助,我們可以嘗試 leaky ReLU 或 PReLU。在 leaky ReLU 中,當(dāng) x < 0 時(shí),它不輸出 0,而是具有小的預(yù)定義向下斜率(如 0.01 或由超參數(shù)設(shè)置)。參數(shù) ReLU(PReLU)往前推動(dòng)一步。每個(gè)節(jié)點(diǎn)將具有可訓(xùn)練斜率。
拆分?jǐn)?shù)據(jù)集
為了測(cè)試實(shí)際性能,我們將數(shù)據(jù)分為三部分: 70 % 用于訓(xùn)練,20 % 用于驗(yàn)證,10 % 用于測(cè)試。確保樣本在每個(gè)數(shù)據(jù)集和每批訓(xùn)練樣本中被充分打亂。在訓(xùn)練過(guò)程中,我們使用訓(xùn)練數(shù)據(jù)集來(lái)構(gòu)建具有不同超參數(shù)的模型。我們使用驗(yàn)證數(shù)據(jù)集來(lái)運(yùn)行這些模型,并選擇精確度最高的模型。但是保險(xiǎn)起見(jiàn),我們使用 10 % 的測(cè)試數(shù)據(jù)進(jìn)行最后的錯(cuò)亂檢查。如果你的測(cè)試結(jié)果與驗(yàn)證結(jié)果有很大差異,則應(yīng)將數(shù)據(jù)打亂地更加充分或收集更多的數(shù)據(jù)。
基線
設(shè)置基線有助于我們比較模型和 Debug,例如我們可使用 VGG19 模型作為分類(lèi)問(wèn)題的基線?;蛘?,我們可以先擴(kuò)展一些已建立的簡(jiǎn)單模型來(lái)解決我們的問(wèn)題。這有助于我們更好地了解問(wèn)題,并建立性能基線進(jìn)行比較。在我們的項(xiàng)目中,我們修改了已建立的 GAN 實(shí)現(xiàn)并重新設(shè)計(jì)了作為基線的生成網(wǎng)絡(luò)。
檢查點(diǎn)
我們定期保存模型的輸出和度量以供比較。有時(shí),我們希望重現(xiàn)模型的結(jié)果或重新加載模型以進(jìn)一步訓(xùn)練它。檢查點(diǎn)允許我們保存模型以便以后重新加載。但是,如果模型設(shè)計(jì)已更改,則無(wú)法加載所有舊檢查點(diǎn)。我們也使用 Git 標(biāo)記來(lái)跟蹤多個(gè)模型,并為特定檢查點(diǎn)重新加載正確的模型。我們的設(shè)計(jì)每個(gè)檢查點(diǎn)占用 4gb 空間。在云環(huán)境中工作時(shí),應(yīng)相應(yīng)配置足夠的存儲(chǔ)。我們經(jīng)常啟動(dòng)和終止 Amazon 云實(shí)例,因此我們將所有文件存儲(chǔ)在 Amazon EBS 中,以便于重新連接。
自定義層
深度學(xué)習(xí)軟件包中的內(nèi)建層已經(jīng)得到了更好的測(cè)試和優(yōu)化。盡管如此,如果想自定義層,你需要:
用非隨機(jī)數(shù)據(jù)對(duì)前向傳播和反向傳播代碼進(jìn)行模塊測(cè)試;
將反向傳播結(jié)果和樸素梯度檢查進(jìn)行對(duì)比;
在分母中添加小量的?或用對(duì)數(shù)計(jì)算來(lái)避免 NaN 值。
歸一化
深度學(xué)習(xí)的一大挑戰(zhàn)是可復(fù)現(xiàn)性。在調(diào)試過(guò)程中,如果初始模型參數(shù)在 session 間保持變化,就很難進(jìn)行調(diào)試。因此,我們明確地對(duì)所有隨機(jī)發(fā)生器初始化了種子。我們?cè)陧?xiàng)目中對(duì) python、NumPy 和 TensorFlow 都初始化了種子。在精調(diào)過(guò)程中,我們我們關(guān)閉了種子初始化,從而為每次運(yùn)行生成不同的模型。為了復(fù)現(xiàn)模型的結(jié)果,我們將對(duì)其進(jìn)行 checkpoint,并在稍后重新加載它。
6. 優(yōu)化器
Adam 優(yōu)化器是深度學(xué)習(xí)中最流行的優(yōu)化器之一。它適用于很多種問(wèn)題,包括帶稀疏或帶噪聲梯度的模型。其易于精調(diào)的特性使得它能快速獲得很好的結(jié)果。實(shí)際上,默認(rèn)的參數(shù)配置通常就能工作得很好。Adam 優(yōu)化器結(jié)合了 AdaGrad 和 RMSProp 的優(yōu)點(diǎn)。Adam 對(duì)每個(gè)參數(shù)使用相同的學(xué)習(xí)率,并隨著學(xué)習(xí)的進(jìn)行而獨(dú)立地適應(yīng)。Adam 是基于動(dòng)量的算法,利用了梯度的歷史信息。因此,梯度下降可以運(yùn)行得更加平滑,并抑制了由于大梯度和大學(xué)習(xí)率導(dǎo)致的參數(shù)振蕩問(wèn)題。
Adam 優(yōu)化器調(diào)整
Adam 有 4 個(gè)可配置參數(shù):
學(xué)習(xí)率(默認(rèn) 0.001);
β1:第一個(gè)矩估計(jì)的指數(shù)衰減率(默認(rèn) 0.9);
β2:第二個(gè)矩估計(jì)的指數(shù)衰減率(默認(rèn) 0.999),這個(gè)值在稀疏梯度問(wèn)題中應(yīng)該被設(shè)置成接近 1;
?(默認(rèn)值 1e^-8)是一個(gè)用于避免除以零運(yùn)算的小值。
β(動(dòng)量)通過(guò)累積梯度的歷史信息來(lái)平滑化梯度下降。通常對(duì)于早期階段,默認(rèn)設(shè)置已經(jīng)能工作得很好。否則,最可能需要改變的參數(shù)應(yīng)該是學(xué)習(xí)率。
7. 總結(jié)
以下是對(duì)深度學(xué)習(xí)項(xiàng)目的主要步驟的簡(jiǎn)單總結(jié):
? Define task (Object detection, Colorization of line arts)
? Collect dataset (MS Coco, Public web sites)
? ?? Search for academic datasets and baselines
? ?? Build your own (From Twitter, News, Website,…)
? Define the metrics
? ?? Search for established metrics
? Clean and preprocess the data
? ?? Select features and transform data
? ?? One-hot vector, bag of words, spectrogram etc...
? ?? Bucketize, logarithm scale, spectrogram
? ?? Remove noise or outliers
? ?? Remove invalid and duplicate data
? ?? Scale or whiten data
? Split datasets for training, validation and testing
? ?? Visualize data
? ?? Validate dataset
? Establish a baseline
? ?? Compute metrics for the baseline
? ?? Analyze errors for area of improvements
? Select network structure
? ?? CNN, LSTM…
? Implement a deep network
? ?? Code debugging and validation
? ?? Parameter initialization
? ?? Compute loss and metrics
? ?? Choose hyper-parameters
? ?? Visualize, validate and summarize result
? ?? Analyze errors
? ?? Add layers and nodes
? ?? Optimization
? Hyper-parameters fine tunings
? Try our model variants
04 可視化深度神經(jīng)網(wǎng)絡(luò)模型和指標(biāo)
在為深度神經(jīng)網(wǎng)絡(luò)排除故障方面,人們總是太快、太早地下結(jié)論了。在了解如何排除故障前,我們要先考慮要尋找什么,再花費(fèi)數(shù)小時(shí)時(shí)間追蹤故障。這部分我們將討論如何可視化深度學(xué)習(xí)模型和性能指標(biāo)。
1. TensorBoard
在每一步追蹤每個(gè)動(dòng)作、檢查結(jié)果非常重要。在預(yù)置包如 TensorBoard 的幫助下,可視化模型和性能指標(biāo)變得簡(jiǎn)單,且獎(jiǎng)勵(lì)幾乎是同時(shí)的。
2. 數(shù)據(jù)可視化(輸入、輸出)
驗(yàn)證模型的輸入和輸出。在向模型饋送數(shù)據(jù)之前,先保存一些訓(xùn)練和驗(yàn)證樣本用于視覺(jué)驗(yàn)證。取消數(shù)據(jù)預(yù)處理。將像素值重新調(diào)整回 [0, 255]。檢查多個(gè)批次,以確定我們沒(méi)有重復(fù)相同批次的數(shù)據(jù)。左下圖像是一些訓(xùn)練樣本,右下方驗(yàn)證樣本。
有時(shí),驗(yàn)證輸入數(shù)據(jù)的直方圖很棒。完美情況下,它應(yīng)該是以 0 為中心的,區(qū)間在 -1 和 1 之間。如果特征在不同的尺度中,那么梯度要么下降要么爆炸(根據(jù)學(xué)習(xí)率而定)。
定期保存對(duì)應(yīng)模型的輸出,用于驗(yàn)證和誤差分析。例如,驗(yàn)證輸出中的顏色稍淺。
3. 指標(biāo)(損失 & 準(zhǔn)確率)
除了定期記錄損失和準(zhǔn)確率之外,我們還可以記錄和繪制它們,以分析其長(zhǎng)期趨勢(shì)。下圖是 TensorBoard 上展示的準(zhǔn)確率和交叉熵?fù)p失。
繪制損失圖能夠幫助我們調(diào)整學(xué)習(xí)率。損失的任意長(zhǎng)期上升表明學(xué)習(xí)率太高了。如果學(xué)習(xí)率較低,則學(xué)習(xí)的速度變慢。
這里是另一個(gè)學(xué)習(xí)率太高的真實(shí)樣本。我們能看到損失函數(shù)突然上升(可能由梯度突然上升引起)。
我們使用準(zhǔn)確率圖調(diào)整正則化因子。如果驗(yàn)證和訓(xùn)練準(zhǔn)確率之間存在很大差距,則該模型出現(xiàn)過(guò)擬合。為了緩解過(guò)擬合,我們需要提高正則化因子。
4. 小結(jié)
權(quán)重 & 偏置:我們緊密監(jiān)控權(quán)重和偏置。下圖是層 1 在不同訓(xùn)練迭代中的權(quán)重和偏置。出現(xiàn)大型(正/負(fù))權(quán)重是不正常的。正態(tài)分布的權(quán)重表明訓(xùn)練過(guò)程很順利(但是也不一定)。
激活:為了梯度下降以實(shí)現(xiàn)最佳性能,激活函數(shù)之前的節(jié)點(diǎn)輸出應(yīng)該呈正態(tài)分布。如果不是,那么我們可能向卷積層應(yīng)用批歸一化,或者向 RNN 層應(yīng)用層歸一化。我們還監(jiān)控激活函數(shù)之后無(wú)效節(jié)點(diǎn)(0 激活)的數(shù)量。
梯度:我們監(jiān)控每一層的梯度,以確定一個(gè)最嚴(yán)肅的深度學(xué)習(xí)問(wèn)題:梯度消失或爆炸。如果梯度從最右層向最左層快速下降,那么就出現(xiàn)了梯度消失問(wèn)題。
這或許不是很常見(jiàn):我們可視化了 CNN 濾波器。它識(shí)別出模型提取的特征的類(lèi)型。如下圖所示,前兩個(gè)卷積層在檢測(cè)邊界和顏色。
對(duì)于 CNN,我們可以看到特征圖在學(xué)習(xí)什么。下圖捕捉了特定圖中具備最高激活函數(shù)的 9 張圖(右側(cè))。它還使用解卷積網(wǎng)絡(luò)從特征圖中重建空間圖像(左圖)。
▲Visualizing and Understanding Convolutional Networks, Matthew D Zeiler et al.
這種圖像重建很少進(jìn)行。但是在生成模型中,我們經(jīng)常改變一個(gè)潛在因子、保持其他不變。它驗(yàn)證該模型是否在智能地學(xué)習(xí)。
▲Dynamic Routing Between Capsules, Sara Sabour, Nicholas Frosst, Geoffrey E Hinton
05 調(diào)試深度學(xué)習(xí)網(wǎng)絡(luò)
1. 深度學(xué)習(xí)的問(wèn)題解決步驟
在前期開(kāi)發(fā)中,我們會(huì)同時(shí)遇到多個(gè)問(wèn)題。就像前面提到的,深度學(xué)習(xí)訓(xùn)練由數(shù)百萬(wàn)次迭代組成。找到 bug 非常難,且容易崩潰。從簡(jiǎn)單開(kāi)始,漸漸做一些改變。正則化這樣的模型優(yōu)化可以在代碼 degug 后做。以功能優(yōu)先的方式檢查模型:
把正則化因子設(shè)置為 0;
不要其他正則化(包括 dropouts);
使用默認(rèn)設(shè)置的 Adam 優(yōu)化器;
使用 ReLU;
不要數(shù)據(jù)增強(qiáng);
更少的深度網(wǎng)絡(luò)層;
擴(kuò)大輸入數(shù)據(jù),但不要非必要預(yù)處理;
不要在長(zhǎng)時(shí)間訓(xùn)練迭代或者大 batch size 上浪費(fèi)時(shí)間。
用小量的訓(xùn)練數(shù)據(jù)使模型過(guò)擬合是 debug 深度學(xué)習(xí)的最好方式。如果在數(shù)千次迭代內(nèi),損失值不下降,進(jìn)一步 debgug 代碼。準(zhǔn)確率超越瞎猜的概念,你就獲得了第一個(gè)里程碑。然后對(duì)模型做后續(xù)的修改:增加網(wǎng)絡(luò)層和自定義;開(kāi)始用完整訓(xùn)練數(shù)據(jù)做訓(xùn)練;通過(guò)監(jiān)控訓(xùn)練和驗(yàn)證數(shù)據(jù)集之間的準(zhǔn)確率差別,來(lái)增加正則化控制過(guò)擬合。
如果卡住了,去掉所有東西,從更小的問(wèn)題開(kāi)始上手。
2. 初始化超參數(shù)
許多超參數(shù)與模型優(yōu)化更為相關(guān)。關(guān)掉超參數(shù)或者使用缺省值。使用 Adam 優(yōu)化器,它速度快、高效且缺省學(xué)習(xí)率也很好。前期的問(wèn)題主要來(lái)自于 bug,而不是模型設(shè)計(jì)和精調(diào)問(wèn)題。在做微調(diào)之前,先過(guò)一遍下面的檢查列表。這些問(wèn)題更常見(jiàn),也容易檢查。如果損失值還沒(méi)下降,就調(diào)整學(xué)習(xí)率。如果損失值降的太慢,學(xué)習(xí)率增加 10。如果損失值上升或者梯度爆炸,學(xué)習(xí)率降低 10。重復(fù)這個(gè)過(guò)程,直到損失值逐漸下降。典型的學(xué)習(xí)率在 1 到 1e-7 之間。
3. 檢查列表
數(shù)據(jù):
可視化并檢查輸入數(shù)據(jù)(在數(shù)據(jù)預(yù)處理之后,饋送到模型之前);
檢查輸入標(biāo)簽的準(zhǔn)確率(在數(shù)據(jù)擾動(dòng)之后);
不要一遍又一遍的饋送同一 batch 的數(shù)據(jù);
適當(dāng)?shù)目s放輸入數(shù)據(jù)(一般可縮放到區(qū)間 (-1, 1) 之間,且具有零均值);
檢查輸出的范圍(如,在區(qū)間 (-1, 1) 之間);
總是使用訓(xùn)練集的平均值/方差來(lái)重新調(diào)節(jié)驗(yàn)證/測(cè)試集;
模型所有的輸入數(shù)據(jù)有同樣的維度;
獲取數(shù)據(jù)集的整體質(zhì)量(是否有太多異常值或者壞樣本)。
模型:
模型參數(shù)準(zhǔn)確的初始化,權(quán)重不要全部設(shè)定為 0;
對(duì)激活或者梯度消失/爆炸的網(wǎng)絡(luò)層做 debug(從最右邊到最左邊);
對(duì)權(quán)重大部分是 0 或者權(quán)重太大的網(wǎng)絡(luò)層做 debug;
檢查并測(cè)試損失函數(shù);
對(duì)預(yù)訓(xùn)練模型,輸入數(shù)據(jù)范圍要匹配模型中使用的范圍;
推理和測(cè)試中的 Dropout 應(yīng)該總是關(guān)掉。
4. 權(quán)重初始化
把權(quán)重全部初始化到 0 是最常見(jiàn)的錯(cuò)誤,深度網(wǎng)絡(luò)也學(xué)不到任何東西。權(quán)重要按照高斯分布做初始化:
5. 縮放與歸一化
人們對(duì)縮放與歸一化都有很好地理解,但這仍舊是最被輕視的問(wèn)題之一。如果輸入特征和節(jié)點(diǎn)輸出都被歸一化,就能更容易地訓(xùn)練模型。如果做的不準(zhǔn)確,損失值就不會(huì)隨著學(xué)習(xí)率降低。我們應(yīng)該監(jiān)控輸入特征和每層節(jié)點(diǎn)輸出的的直方圖。要適當(dāng)?shù)目s放輸入。而對(duì)節(jié)點(diǎn)的輸出,完美的形狀是零均值,且值不太大(正或負(fù))。如果不是且遇到該層有梯度問(wèn)題,則在卷積層做批歸一化,在 RNN 單元上做層歸一化。
6. 損失函數(shù)
檢查和測(cè)試損失函數(shù)的準(zhǔn)確性。模型的損失值一定要比隨機(jī)猜測(cè)的值低。例如,在 10 類(lèi)別分類(lèi)問(wèn)題中,隨機(jī)猜測(cè)的的交叉熵?fù)p失是-ln(1/10)。
7. 分析誤差
檢查表現(xiàn)不好(誤差)的地方并加以改進(jìn),且對(duì)誤差進(jìn)行可視化。在我們的項(xiàng)目中,模型表現(xiàn)對(duì)結(jié)構(gòu)高度糾纏的圖像表現(xiàn)不好。例如,增加更多帶有更小濾波器的卷積層來(lái)解開(kāi)小特征。如果有必要就增強(qiáng)數(shù)據(jù)或者收集更多類(lèi)似的樣本來(lái)更好的訓(xùn)練模型。在一些情景下,你可能想要移除這些樣本,限制在更聚焦的模型。
8. 正則化精調(diào)
關(guān)掉正則化(使得模型過(guò)擬合)直到做出合理的預(yù)測(cè)。
一旦模型代碼可以工作了,接下來(lái)調(diào)整的參數(shù)是正則化因子。我們需要增加訓(xùn)練數(shù)據(jù)的體量,然后增加正則化來(lái)縮小訓(xùn)練和驗(yàn)證準(zhǔn)確率之間的差別。不要做的太過(guò)分,因?yàn)槲覀兿胍晕⒆屇P瓦^(guò)擬合。密切監(jiān)測(cè)數(shù)據(jù)和正則化成本。長(zhǎng)時(shí)間尺度下,正則化損失不應(yīng)該控制數(shù)據(jù)損失。如果用大型正則化還不能縮小兩個(gè)準(zhǔn)確率間的差距,那先 degug 正則化代碼或者方法。
類(lèi)似于學(xué)習(xí)率,我們以對(duì)數(shù)比例改變測(cè)試值,例如開(kāi)始時(shí)改變 1/10。注意,每個(gè)正則化因子都可能是完全不同的數(shù)量級(jí),我們可以反復(fù)調(diào)整這些參數(shù)。
9. 多個(gè)損失函數(shù)
在第一次實(shí)現(xiàn)中,避免使用多個(gè)數(shù)據(jù)損失函數(shù)。每個(gè)損失函數(shù)的權(quán)重可能有不同的數(shù)量級(jí),也需要一些精力去調(diào)整。如果我們只有一個(gè)損失函數(shù),就可以只在意學(xué)習(xí)率了。
10. 固定變量
當(dāng)我們使用預(yù)訓(xùn)練模型,我們可以固定特定層的模型參數(shù),從而加速計(jì)算。一定要再次檢查是否有變量固定的錯(cuò)誤。
11. 單元測(cè)試
正如極少會(huì)被談到的,我們應(yīng)該對(duì)核心模塊進(jìn)行單元測(cè)試,以便于代碼改變時(shí)實(shí)現(xiàn)依舊穩(wěn)健。如果其參數(shù)用隨機(jī)發(fā)生器(randomizer)做初始化,檢查一個(gè)網(wǎng)絡(luò)層的輸出不太簡(jiǎn)單。另外,我們可以模仿輸入數(shù)據(jù)、檢查輸出。對(duì)每個(gè)模塊(層),我們可以檢查:
訓(xùn)練和推理輸出的形狀;
可訓(xùn)練變量的數(shù)量(不是參數(shù)的數(shù)量)。
12. 維度誤匹配
要一直跟蹤 Tensor(矩陣)的形狀,并將其歸檔到代碼中。對(duì)形狀是 [N, channel, W, H ] 的 Tensor,如果 W(寬)和 H(高)有同樣的維度,二者交換代碼不會(huì)出錯(cuò)。因此,我們應(yīng)該用非對(duì)稱(chēng)形狀做代碼單元測(cè)試。例如,我們用 [4, 3]Tensor,而非 [4, 4] 做測(cè)試。
06 提升深度學(xué)習(xí)模型性能及網(wǎng)絡(luò)調(diào)參
1. 提升模型容量
要想提升模型容量,我們可以向深度網(wǎng)絡(luò)(DN)逐漸添加層和節(jié)點(diǎn)。更深的層會(huì)輸出更復(fù)雜的模型。我們還可以降低濾波器大小。較小的濾波器(3×3 或 5×5)性能通常優(yōu)于較大的濾波器。
調(diào)參過(guò)程更重實(shí)踐而非理論。我們逐漸添加層和節(jié)點(diǎn),可以與模型過(guò)擬合,因?yàn)槲覀兛梢杂谜齽t化方式再將其調(diào)低。重復(fù)該迭代過(guò)程直到準(zhǔn)確率不再提升,不再值得訓(xùn)練、計(jì)算性能的降低。
但是,GPU 的內(nèi)存是有限的。截止 2018 年初,高端顯卡 NVIDIA GeForce GTX 1080 TI 的內(nèi)存為 11GB。兩個(gè)仿射層之間隱藏節(jié)點(diǎn)的最大數(shù)量受內(nèi)存大小的限制。
對(duì)于非常深層的網(wǎng)絡(luò),梯度消失問(wèn)題很?chē)?yán)重。我們可以添加跳躍連接(類(lèi)似 ResNet 中的殘差連接)來(lái)緩解該問(wèn)題。
2. 模型 & 數(shù)據(jù)集設(shè)計(jì)變化
以下是提升性能的檢查列表:
在驗(yàn)證數(shù)據(jù)集中分析誤差(糟糕的預(yù)測(cè)結(jié)果);
監(jiān)控激活函數(shù)。在激活函數(shù)不以零為中心或非正態(tài)分布時(shí),考慮批歸一化或?qū)託w一化;
監(jiān)控?zé)o效節(jié)點(diǎn)的比例;
使用梯度截?cái)啵ㄓ绕涫?NLP 任務(wù)中)來(lái)控制梯度爆炸問(wèn)題;
Shuffle 數(shù)據(jù)集(手動(dòng)或通過(guò)程序);
平衡數(shù)據(jù)集(每個(gè)類(lèi)別具備相似數(shù)量的樣本)。
我們應(yīng)該在激活函數(shù)之前密切監(jiān)控激活直方圖。如果它們的規(guī)模差別很大,那么梯度下降將會(huì)無(wú)效。使用歸一化。如果深度網(wǎng)絡(luò)有大量無(wú)效節(jié)點(diǎn),那么我們應(yīng)該進(jìn)一步追蹤該問(wèn)題。它可能是由 bug、權(quán)重初始化或梯度消失導(dǎo)致的。如果都不是,則試驗(yàn)一些高級(jí) ReLU 函數(shù),如 leaky ReLU。
3. 數(shù)據(jù)集收集 & 清洗
如果你想構(gòu)建自己的數(shù)據(jù)集,那么最好的建議就是仔細(xì)研究如何收集樣本。找最優(yōu)質(zhì)的資源,過(guò)濾掉與你問(wèn)題無(wú)關(guān)的所有數(shù)據(jù),分析誤差。在我們的項(xiàng)目中,具備高度糾纏結(jié)構(gòu)的圖像性能非常糟糕。我們可以添加卷積層和小型濾波器來(lái)改變模型。但是模型已經(jīng)很難訓(xùn)練了。我們可以添加更多糾纏樣本做進(jìn)一步訓(xùn)練,但是已經(jīng)有了很多了……另一種方式:我們可以精細(xì)化項(xiàng)目范圍,縮小樣本范圍。
4. 數(shù)據(jù)增強(qiáng)
收集有標(biāo)簽的數(shù)據(jù)是一件昂貴的工作。對(duì)于圖片來(lái)說(shuō),我們可以使用數(shù)據(jù)增強(qiáng)方法如旋轉(zhuǎn)、隨機(jī)剪裁、移位等方式來(lái)對(duì)已有數(shù)據(jù)進(jìn)行修改,生成更多的數(shù)據(jù)。顏色失真則包括色調(diào)、飽和度和曝光偏移。
5. 半監(jiān)督學(xué)習(xí)
我們還可以使用無(wú)標(biāo)注數(shù)據(jù)補(bǔ)充訓(xùn)練數(shù)據(jù)。使用模型分類(lèi)數(shù)據(jù)。把具備高置信預(yù)測(cè)的樣本添加到具備對(duì)應(yīng)標(biāo)簽預(yù)測(cè)的訓(xùn)練數(shù)據(jù)集中。
6. 調(diào)整
學(xué)習(xí)率調(diào)整
我們先簡(jiǎn)單回顧一下如何調(diào)整學(xué)習(xí)率。在早期開(kāi)發(fā)階段,我們關(guān)閉任意非關(guān)鍵超參數(shù)或設(shè)置為 0,包括正則化。在具備 Adam 優(yōu)化器的情況下,默認(rèn)學(xué)習(xí)率通常性能就很好了。如果我們對(duì)自己的代碼很有信心,但是損失并沒(méi)有下降,則需要調(diào)整學(xué)習(xí)率。典型的學(xué)習(xí)率在 1 和 1e-7 之間。每次把學(xué)習(xí)率降低 10%,并在簡(jiǎn)短迭代中進(jìn)行測(cè)試,密切監(jiān)控?fù)p失。如果它持續(xù)上升,那么學(xué)習(xí)率太高了。如果它沒(méi)有下降,則學(xué)習(xí)率太低。提高學(xué)習(xí)率,直到損失提前變得平緩。
下面是一個(gè)真實(shí)樣本,展示了學(xué)習(xí)率太高的情況,這導(dǎo)致成本突然上漲:
在不經(jīng)常用的實(shí)踐中,人們監(jiān)控 W ratio 的更新情況:
如果 ratio > 1e-3,則考慮調(diào)低學(xué)習(xí)率;
如果 ratio < 1e-3,則考慮提高學(xué)習(xí)率。
超參數(shù)調(diào)整
在模型設(shè)計(jì)穩(wěn)定后,我們也可以進(jìn)一步調(diào)整模型。最經(jīng)常調(diào)整的超參數(shù)是:
mini-batch 尺寸;
學(xué)習(xí)率;
正則化因子;
特定層的超參數(shù)(如 dropout)。
Mini-batch 尺寸
通常的批尺寸是 8、16、32 或 64。如果批尺寸太小,則梯度下降不會(huì)很順暢,模型學(xué)習(xí)的速度慢,損失可能會(huì)振蕩。如果批尺寸太大,則完成一次訓(xùn)練迭代(一輪更新)的時(shí)間太長(zhǎng),得到的返回結(jié)果較小。在我們的項(xiàng)目中,我們降低批尺寸,因?yàn)槊看斡?xùn)練迭代時(shí)間太長(zhǎng)。我們密切監(jiān)控整個(gè)學(xué)習(xí)速度和損失。如果損失振蕩劇烈,則我們會(huì)知道批尺寸降低的幅度太大了。批尺寸影響正則化因子等超參數(shù)。一旦我們確定好批尺寸,我們通常就鎖定了值。
學(xué)習(xí)率 & 正則化因子
我們可以使用上述方法進(jìn)一步調(diào)整學(xué)習(xí)率和正則化因子。我們監(jiān)控?fù)p失,來(lái)控制學(xué)習(xí)率和驗(yàn)證與訓(xùn)練準(zhǔn)確率之間的差距,從而調(diào)整正則化因子。我們沒(méi)有把學(xué)習(xí)率降低 10%,而是降低 3%(精細(xì)調(diào)整中或許更?。?。
調(diào)參不是線性過(guò)程。超參數(shù)是有關(guān)聯(lián)的,我們將反復(fù)調(diào)整超參數(shù)。學(xué)習(xí)率和正則化因子高度相關(guān),有時(shí)需要一起調(diào)。不要太早進(jìn)行精細(xì)調(diào)整,有可能浪費(fèi)時(shí)間。設(shè)計(jì)改變的話這些努力就白費(fèi)了。
Dropout
Dropout 率通常在 20% 到 50% 之間。我們先從 20% 開(kāi)始。如果模型出現(xiàn)過(guò)擬合,則提高值。
其他調(diào)整
稀疏度
激活函數(shù)
模型參數(shù)的稀疏度能使計(jì)算優(yōu)化變得簡(jiǎn)單,并減少能耗(這對(duì)于移動(dòng)設(shè)備來(lái)說(shuō)至關(guān)重要)。如果需要,我們可以用 L1 正則化替代 L2 正則化。ReLU 是最流行的激活函數(shù)。對(duì)于一些深度學(xué)習(xí)競(jìng)賽,人們使用更高級(jí)的 ReLU 變體以提高準(zhǔn)確率。在一些場(chǎng)景中它還可以減少無(wú)效節(jié)點(diǎn)。
高級(jí)調(diào)參
一些高級(jí)精細(xì)調(diào)參方法:
學(xué)習(xí)率衰減調(diào)度
動(dòng)量(Momentum)
早停
我們沒(méi)有使用固定的學(xué)習(xí)率,而是定期降低學(xué)習(xí)率。超參數(shù)包括學(xué)習(xí)率下降的頻率和幅度。例如,你可以在每十萬(wàn)次迭代時(shí)減少 0.95 的學(xué)習(xí)率。要調(diào)整這些參數(shù),我們需要監(jiān)控成本,以確定參數(shù)下降地更快但又不至于過(guò)早平緩。
高級(jí)優(yōu)化器使用動(dòng)量使梯度下降過(guò)程流暢進(jìn)行。Adam 優(yōu)化器中存在兩種動(dòng)量設(shè)置,分別控制一階(默認(rèn) 0.9)和二階(默認(rèn) 0.999)動(dòng)量。對(duì)于具備梯度陡降的問(wèn)題領(lǐng)域如 NLP,我們可以稍稍提高動(dòng)量值。
當(dāng)驗(yàn)證誤差持續(xù)上升時(shí),過(guò)擬合可通過(guò)停止訓(xùn)練來(lái)緩解。
但是,這只是概念的可視化。實(shí)時(shí)誤差可能暫時(shí)上升,然后再次下降。我們可以定期檢查模型,記錄對(duì)應(yīng)的驗(yàn)證誤差。稍后我們來(lái)選擇模型。
7. 網(wǎng)格搜索
一些超參數(shù)是高度相關(guān)的。我們應(yīng)該使用對(duì)數(shù)尺度上的可能性網(wǎng)格一起調(diào)整它們。例如:對(duì)于兩個(gè)超參數(shù)λ和γ,我們從相應(yīng)的初始值開(kāi)始,并在每個(gè)步驟中將其降低 10 倍:
(e-1, e-2, … and e-8);
(e-3, e-4, … and e-6)。
相應(yīng)的網(wǎng)格會(huì)是 [(e-1, e-3), (e-1, e-4), … , (e-8, e-5) 和 (e-8, e-6)]。
我們沒(méi)有使用明確的交叉點(diǎn),而是稍微隨機(jī)移動(dòng)了這些點(diǎn)。這種隨機(jī)性可能會(huì)幫助我們發(fā)現(xiàn)一些隱藏的性質(zhì)。如果最佳點(diǎn)位于網(wǎng)格的邊界(藍(lán)色點(diǎn)),我們則會(huì)在邊界區(qū)域進(jìn)行重新測(cè)試。
網(wǎng)格搜索的計(jì)算量很大。對(duì)于較小的項(xiàng)目,它們會(huì)被零星使用。我們開(kāi)始用較少的迭代來(lái)調(diào)整粗粒度參數(shù)。在后期的細(xì)調(diào)階段,我們會(huì)使用更長(zhǎng)的迭代,并將數(shù)值調(diào)至 3(或更低)。
8. 模型集合
在機(jī)器學(xué)習(xí)中,我們可以從決策樹(shù)中投票進(jìn)行預(yù)測(cè)。這種方法非常有效,因?yàn)榕袛嗍д`通常是有局部性質(zhì)的:兩個(gè)模型發(fā)生同一個(gè)錯(cuò)誤的幾率很小。在深度學(xué)習(xí)中,我們可以從隨機(jī)猜測(cè)開(kāi)始訓(xùn)練(提交一個(gè)沒(méi)有明確設(shè)置的隨機(jī)種子),優(yōu)化模型也不是唯一的。我們可以使用驗(yàn)證數(shù)據(jù)集測(cè)試多次選出表現(xiàn)最佳的模型,也可以讓多個(gè)模型進(jìn)行內(nèi)部投票,最終輸出預(yù)測(cè)結(jié)果。這種方式需要進(jìn)行多個(gè)會(huì)話,肯定非常耗費(fèi)系統(tǒng)資源。我們也可以訓(xùn)練一次,檢查多個(gè)模型,隨后在這個(gè)過(guò)程中選出表現(xiàn)最佳的模型。通過(guò)集合模型,我們可以基于這些進(jìn)行準(zhǔn)確的預(yù)測(cè):
每個(gè)模型預(yù)測(cè)的「投票」;
基于預(yù)測(cè)置信度進(jìn)行加權(quán)投票。
模型集合在提高一些問(wèn)題的預(yù)測(cè)準(zhǔn)確率上非常有效,經(jīng)常會(huì)被深度學(xué)習(xí)數(shù)據(jù)競(jìng)賽的隊(duì)伍所采用。
9. 模型提升
在微調(diào)模型以外,我們也可以嘗試使用模型的不同變體來(lái)提升性能。例如,我們可以考慮使用色彩生成器部分或全部替代標(biāo)準(zhǔn) LSTM。這種概念并不陌生:我們可以分步繪制圖片。
直觀地說(shuō),在圖像生成任務(wù)中引入時(shí)間序列方法是有優(yōu)勢(shì)的,這種方法已經(jīng)在 DRAW: A Recurrent Neural Network For Image Generation 中被證明過(guò)了。
微調(diào)與模型提升
性能重大提升的背后往往是模型設(shè)計(jì)的改變。不過(guò)有些時(shí)候?qū)δP瓦M(jìn)行微調(diào)也可以提升機(jī)器學(xué)習(xí)的性能。最終的判斷可能會(huì)取決于你對(duì)相應(yīng)任務(wù)的基準(zhǔn)測(cè)試結(jié)果。
10. Kaggle
在開(kāi)發(fā)過(guò)程中,你或許會(huì)有一些簡(jiǎn)單的問(wèn)題,如:我需要使用 Leak ReLU 嗎?。有時(shí)候問(wèn)題很簡(jiǎn)單,但你永遠(yuǎn)無(wú)法在任何地方找到答案。在一些論文中,你會(huì)看到 Leak ReLU 的優(yōu)越性,但另一些項(xiàng)目的經(jīng)驗(yàn)顯示并沒(méi)有性能提升。太多的項(xiàng)目,太多的變量都缺乏衡量多種可能性的驗(yàn)證結(jié)果。Kaggle 是一個(gè)數(shù)據(jù)科學(xué)競(jìng)賽的開(kāi)放平臺(tái),其中深度學(xué)習(xí)是很重要的一部分。深入觀察一些優(yōu)秀選手的方法,你或許就可以找到最為普遍的性能指標(biāo)了。而且,一些數(shù)據(jù)競(jìng)賽團(tuán)隊(duì)還會(huì)把自己的代碼(被稱(chēng)為 kernel)上傳開(kāi)源。只要留心探索,Kaggle 會(huì)是一個(gè)很棒的信息源。
11. 實(shí)驗(yàn)框架
深度學(xué)習(xí)開(kāi)發(fā)需要依賴(lài)大量經(jīng)驗(yàn),調(diào)節(jié)超參數(shù)是一件非常乏味的工作。創(chuàng)建一個(gè)實(shí)驗(yàn)框架可以加速這一過(guò)程。例如:一些人會(huì)開(kāi)發(fā)代碼將模型定義外化為字符串以便調(diào)節(jié)。然而這些努力通常不能為小團(tuán)隊(duì)帶來(lái)收益。以我的經(jīng)驗(yàn),這樣做的話代碼的簡(jiǎn)潔性和可追溯性損失會(huì)遠(yuǎn)比受益要大,這意味著難以對(duì)代碼進(jìn)行簡(jiǎn)單的修改。易于閱讀的代碼必然有著簡(jiǎn)潔和靈活的特性。與此相反,很多 AI 云產(chǎn)品已經(jīng)開(kāi)始提供自動(dòng)調(diào)節(jié)超參數(shù)的特性。雖然目前這種技術(shù)仍處于初始階段,但無(wú)需人類(lèi)自己編寫(xiě)框架的流程應(yīng)該是大勢(shì)所趨,請(qǐng)時(shí)刻注意這一趨勢(shì)。
12. 結(jié)論
現(xiàn)在,你已擁有了調(diào)整完畢的模型,可以正式部署了。希望這個(gè)系列教程對(duì)你有所幫助。深度學(xué)習(xí)可以幫助我們解決很多問(wèn)題——其適用范圍超出你的想象。想使用深度學(xué)習(xí)代替前端設(shè)計(jì)?你可以嘗試一下 pix2code!
作者:Jonathan Hui
來(lái)源:機(jī)器之心(ID:almosthuman2014)編譯
原文鏈接(需翻墻):
https://medium.com/@jonathan_hui/how-to-start-a-deep-learning-project-d9e1db90fa72
https://medium.com/@jonathan_hui/build-a-deep-learning-dataset-part-2-a6837ffa2d9e
https://medium.com/@jonathan_hui/deep-learning-designs-part-3-e0b15ef09ccc
https://medium.com/@jonathan_hui/visualize-deep-network-models-and-metrics-part-4-9500fe06e3d0
https://medium.com/@jonathan_hui/debug-a-deep-learning-network-part-5-1123c20f960d
https://medium.com/@jonathan_hui/improve-deep-learning-models-performance-network-tuning-part-6-29bf90df6d2d
回復(fù)“深度學(xué)習(xí)21天實(shí)戰(zhàn)caffe”可獲得電子書(shū)
掃一掃下邊二維碼,
更多精彩文章等著你。
精彩文章推薦:
神經(jīng)網(wǎng)絡(luò)和深度學(xué)習(xí)簡(jiǎn)史