parallels網絡初始化失敗_33 個神經網絡「煉丹」技巧

9f24283761a41ed6bce0f9dc9ed1bba0.png

自然語言處理

Andrej Karpathy 是深度學習計算機視覺領域、與領域的研究員。博士期間師從李飛飛。在讀博期間,兩次在谷歌實習,研究在 Youtube 視頻上的大規模特征學習,2015 年在 DeepMind 實習,研究深度強化學習。畢業后,Karpathy 成為 OpenAI 的研究科學家,后于 2017 年 6 月加入特斯拉擔任人工智能與視覺總監。

今日他發布的這篇博客能為深度學習研究者們提供極為明晰的洞見,在 Twitter 上也引發了極大的關注。

3146bcd8ce34398a9f7bb2e6f4575b81.png

1. 誰說神經網絡訓練簡單了?

很多人認為開始訓練神經網絡是很容易的,大量庫和框架號稱可以用 30 行代碼段解決你的數據問題,這就給大家留下了(錯誤的)印象:訓練神經網絡這件事是非常簡單的,不同模塊即插即用就能搭個深度模型。

簡單的建模過程通常如下所示:

>>> your_data = # plug your awesome dataset here>>> model = SuperCrossValidator(SuperDuper.fit, your_data, ResNet50, SGDOptimizer)# conquer world here

這些庫和示例令我們想起了熟悉標準軟件及模塊,標準軟件中通常可以獲取簡潔的 API 和抽象。

例如 Request 庫的使用展示如下:

>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))>>> r.status_code200

酷!這些庫和框架的開發者背負起理解用戶 Query 字符串、url、GET/POST 請求、HTTP 連接等的大量需求,將復雜度隱藏在幾行代碼后面。這就是我們熟悉與期待的。

然而,神經網絡不一樣,它們并不是現成的技術。我在 2016 年撰寫的一篇博客中試圖說明這一點,在那篇文章中我認為反向傳播是「leaky abstraction」,然而現在的情況似乎更加糟糕了。

Backprop + SGD 不是魔法,無法讓你的網絡運行;批歸一化也無法奇跡般地使網絡更快收斂;RNN 也不能神奇地讓你直接處理文本。不要因為你可以將自己的問題表示為強化學習,就認為你應該這么做。如果你堅持在不理解技術原理的情況下去使用它,那么你很可能失敗。

241179263d0ff42fe29e16d899b5c5d0.png

2. 背著我不 work 的神經網絡

當你破壞代碼或者錯誤配置代碼時,你通常會得到某種異常。你在原本應該插入字符串的地方插入了整數;導入出錯;該關鍵字不存在……此外,為了方便 debug,你還很可能為某個功能創建單元測試。

這還只是開始。訓練神經網絡時,有可能所有代碼的句法都正確,但整個訓練就是不對。可能問題出現在邏輯性(而不是句法),且很難通過單元測試找出來。

例如,你嘗試截損失度而不是梯度,這會導致訓練期間的異常值被忽視,但語法或維度等檢測都不會出現錯誤。又或者,你弄錯了正則化強度、學習率、衰減率、模型大小等的設置,那么幸運的話網絡會報錯,然而大部分時候它會繼續訓練,并默默地變糟……

因此,「快速激烈」的神經網絡訓練方式沒有用,只會導致困難。現在,這些經驗性困難是使神經網絡正常運行的攔路虎,你需要更加周密詳盡地調試網絡才能減少困難,需要大量可視化來了解每一件事。

在我的經驗中,深度學習成功的重要因素是耐心和注重細節。

如何解決

基于以上兩點事實,我開發了一套將神經網絡應用于新問題的特定流程。該流程嚴肅地執行了上述兩項原則:耐心注重細節

具體來說,它按照從簡單到復雜的方式來構建,我們在每一步都對即將發生的事作出準確的假設,然后用實驗來驗證假設或者調查直到發現問題。我們試圖盡力阻止大量「未經驗證的」復雜性一次來襲,這有可能導致永遠也找不到的 bug/錯誤配置。如果讓你像訓練神經網絡那樣寫它的代碼,你會想使用非常小的學習率,然后猜測,再在每次迭代后評估整個測試集。

1. 梳理數據

訓練神經網絡的第一步是不要碰代碼,先徹底檢查自己的數據。這一步非常關鍵。我喜歡用大量時間瀏覽數千個樣本,理解它們的分布,尋找其中的模式。幸運的是,人類大腦很擅長做這件事。有一次,我發現數據中包含重復的樣本,還有一次我發現了損壞的圖像/標簽。我會查找數據不均衡和偏差。我通常還會注意自己的數據分類過程,它會揭示我們最終探索的架構。比如,只需要局部特征就夠了還是需要全局語境?標簽噪聲多大?

此外,由于神經網絡是數據集的壓縮/編譯版本,你能夠查看網絡(錯誤)預測,理解預測從哪里來。如果網絡預測與你在數據中發現的不一致,那么一定是什么地方出問題了。

在你對數據有了一些感知之后,你可以寫一些簡單的代碼來搜索/過濾/排序標簽類型、標注規模、標注數量等,并沿任意軸可視化其分布和異常值。異常值通常能夠揭示數據質量或預處理中的 bug。

29117f3f7260f8525bd87e24823e69a4.png

2. 配置端到端訓練/評估架構、獲取基線結果

現在我們已經理解了數據,那我們就可以開始構建高大上的多尺度 ASPP FPN ResNet 并訓練強大的模型了嗎?當然還不到時候,這是一個充滿荊棘的道路。我們下一步需要構建一個完整的訓練、評估架構,并通過一系列實驗確定我們對準確率的置信度。

在這個階段,你們最好選擇一些不會出錯的簡單模型,例如線性分類器或非常精簡的 ConvNet 等。我們希望訓練這些模型,并可視化訓練損失、模型預測和其它度量指標(例如準確率)。當然在這個過程中,我們還需要基于一些明確假設,從而執行一系列對照實驗(ablation experiments)。

該階段的一些技巧與注意事項:

固定隨機 seed:始終使用固定的隨機 seed 能保證很多屬性,例如在我們兩次運行相同代碼時能得到相同的輸出。這能消除變化因子,從進行合理的判斷。

簡化:確保禁用不必要的技巧。例如,在這個階段肯定需要關閉數據增強。數據增強可以在后期引入,并作為一種強大的正則化策略。不過在這個階段引入的話,它就有機會帶來一些愚蠢的 bug。

使用多數據、少次數的驗證評估:當我們在繪制測試損失時,我們需要在整個比較大的測試集中執行評估。不要過幾個批量就繪制一次測試損失,然后再依賴 TensorBoard 的平滑處理。我們雖然追求的是準確率,但也要防止犯這些低級錯誤。

在初始化中驗證損失:驗證你的損失函數在初始化中有比較合理的損失值。例如,如果你正確地初始化最終層,那么你應該通過-log(1/n_classes) 度量初始化的 Softmax 值。L2 回歸和 Huber 損失函數等都有相同的默認值。

優秀的初始化:正確的初始化最終層。例如,如果你正在對均值為 50 的一些數據做回歸處理,那么初始化的最終偏置項就應該為 50。如果你有一個非平衡數據集(兩類樣本數 1:10),那么就需要在 logits 上設置偏置項,令模型在初始化時預測概率為 0.1。正確配置這些偏置項將加快收斂速度,因為網絡在前面幾次迭代中基本上只在學習偏置。

人類基線結果:監控損失值等其他度量指標(例如準確度),這些指標應該是人類能解釋并檢查的。盡可能評估你自己(人類)獲得的準確率,并與構建的模型做對比。或者對測試數據進行兩次標注,其中一次為預測值,另一次為標注值。

獨立于輸入的基線結果:訓練一個獨立于輸入的基線模型,例如最簡單的方法就是將所有輸入都設置為 0。這樣的模型應該比實際輸入數據表現更差,你的模型是否準備好從任何輸入中抽取任何信息?

在批數據上過擬合:在單個批數據上使得過擬合(兩個或多個少樣本)。為此,我們需要增加模型擬合能力,并驗證我們能達到的最低損失值(即 0)。我還想在同一張圖中顯示標簽和預測值,并確保損失值一旦達到最小,它們就能完美地對齊了。

驗證訓練損失的下降:在這一階段,你可能希望在數據集上實現欠擬合,該階段的模型應該是極簡的。然后我們嘗試增加一點模型的擬合能力,再看看訓練損失是否稍微下降了一些。

在輸入網絡前可視化:在運行模型之前,我們需要可視化數據。也就是說,我們需要可視化輸入到網絡的具體數據,即可視化原始張量的數據和標簽。這是唯一的「真實來源」,我有很多次都是因為這個過程而節省了大量時間,并揭示了數據預處理和數據增強過程中的問題。

可視化預測過程:我喜歡在訓練過程中對一個固定的測試批數據進行模型預測的可視化。這展示了預測值如何變化的過程,能為我們提供關于訓練過程的優秀直覺。很多時候,如果網絡以某種方式小幅度波動,那么模型最可能在嘗試擬合數據,這也展示了一些不穩定性。太低或太高的學習率也很容易注意到,因為抖動量比較大。

使用反向傳播繪制依賴性:你的深度學習代碼通常包括復雜的、矢量化的、Boardcast 操作。一個常見的 bug 是,人們會無意間使用 view 而不是 transpose/permute,從而混合了批量數據中的維度信息。然而,你的網絡仍然可以正常訓練,只不過它們學會忽略了其它樣本中的數據。一種 debug 的方法是將某些樣本 i 的損失設置為 1.0,然后運行反向傳播一直到輸入,并確保第 i 個樣本的梯度不為零。更一般的,梯度為我們提供了網絡中的依賴性關系,它們在 debug 中非常有用。

一般化特殊案例:這是一種更為通用的代碼技巧,但是我經常看到人們在使用這些技巧時會新產生 Bug,尤其是在從頭構建一般函數時。相反,我喜歡直接寫非常具體的函數,它只包含我現在需要做的事情。我會先讓這個函數能 work,然后再一般化好函數,并確保能取得相同的結果。通常這個過程會體現在向量化代碼中,我會先用循環編寫某個過程,然后再一次一個循環地將它們轉化為向量化化代碼。

1a4d4e7b40c857043da72a3d4218a91e.png

3. 過擬合

到了這個階段,我們應該對數據集有所了解了,而且有了完整的訓練+評估流程。對于任何給定的模型,我們可以計算出我們信任的度量。而且還為獨立于輸入的基線準備了性能,一些 dumb 基線的性能(最好超過這些),我們人類的表現有大致的了解(并希望達到這一點)。現在,我們已經為迭代一個好的模型做好了準備。

我準備用來尋找好模型的方法有兩個階段:首先獲得足夠大的模型,這樣它能夠過擬合(即關注訓練損失),然后對其進行適當的正則化(棄掉一些訓練損失以改進驗證損失)。我喜歡這兩個階段的原因是,如果我們不能用任何模型實現較低的誤差率,則可能再次表明一些問題、bug 和配置錯誤。

該階段的一些技巧與注意事項:

選擇模型:為了達到理想的訓練損失,我們可能希望為數據選擇一個合適的架構。當我們在挑選模型時,我的第一個建議即別好高騖遠。我看到很多人都非常渴望一開始就堆疊一些新的模塊,或創造性地用于各種異質架構,從而想一步到位做好。我建議可以找最相關的論文,并直接利用它們的簡單架構,從而獲得良好性能。后面再基于這個架構做修改和改進,并將我們的想法加進去就行了。

Adam 是一般選擇:在配置基線模型的早期階段,我喜歡使用 Adam 算法(學習率為 3e-4)。在我的經驗中,Adam 對超參數的容忍度更高,不太好的學習率也能獲得一般的效果。對于卷積網絡來說,一般經過仔細調整的 SGD 幾乎總會略優于 Adam,但最佳學習率的可能區域要窄得多。

一次復雜化一個:如果你有多個特性插入分類器,我建議你一個個插入,從而確保能獲得期待的性能提升。不要在最開始時就一次性全加上,這樣你會弄不清楚性能提升到底是哪個特性帶來的。還有其它增加復雜性的方法,例如你可以先嘗試插入較小的圖像,然后再慢慢地加大。

別相信默認的學習率衰減:如果你修改來自其它領域的代碼,你應該小心使用學習率衰減方法。對于不同問題,你不僅希望使用不同的衰減策略,同時因為 Epoch 的數量不同,衰減過程也會不一樣。例如數據集的大小,會影響 Epoch 的數量,而很多學習率衰減策略是直接與 Epoch 相關的。在我自己的工作中,我經常整個地關閉學習率衰減,即使用常數學習率。

4. 正則化

理想情況下,我們現在至少有了一個擬合訓練集的大模型。現在是時候對它進行正則化,并通過放棄一些訓練準確率來提升驗證準確率了。技巧包括:

更多數據:首先,在當前任何實際環境中正則化模型的最好方式是增加更多真實的訓練數據。在你能收集更多數據時,花費大量工程時間試圖從小數據集上取得更好結果是很常見的一個錯誤。我認為增加更多數據是單調提升一個較好配置神經網絡性能的唯一可靠方式。

數據增強:比真實數據較次的方法是半假數據,試驗下更激進的數據增強。

創造性增強:如果半假數據也沒有,假數據也還可以。人們在尋求擴展數據集的創造性方法。例如,域隨機化、使用模擬數據、把數據插入場景這樣機智的混合方法,甚至可以用 GAN。

預訓練:即使你有足夠的數據,你也可以使用預訓練網絡,基本沒什么損失。

堅持監督式學習:不要對無監督學習過于激動。據我所知,沒有什么無監督學習方法在當前計算機視覺任務上有很強的結果(盡管 NLP 領域現在有了 BERT 和其他類似模型,但這更多歸功于文本更成熟的本質以及對噪聲比更好的信號)。

更小的輸入維度:移除可能包含假信號的特征。如果你的數據集很小,任何加入的假輸入只會增加過擬合的可能。類似地,如果低級細節作用不大,試試輸入更小的圖像。

更小的模型:在許多情況下,你可以在網絡上使用域知識約束來降低模型大小。例如,在 ImageNet 主干網絡頂部使用全連接層一度很流行,但它們后來被簡單的平均池化取代,消除了這一過程中大量的參數。

減小批大小:由于 BN 基于批量大小來做歸一化,較小的批量大小具有更強的正則化效果。這主要因為一個批量的統計均值與標準差是實際均值和標準差的近似,所以縮放量和偏移量在小批量內波動地更大。

drop:增加 dropout。在卷積網絡上使用 dropout2d(空間 dropout)。保守謹慎的使用 dropout,因為它對 batch 歸一化好像不太友好。

權重衰減:增加權重衰減懲罰。

早停(early stopping):基于你得到的驗證損失停止訓練,從而在即將過擬合之前獲取模型。

嘗試更大的模型:我過去多次發現更大模型最終都會很大程度的過擬合,但它們「早停」后的性能要比小模型好得多。

最后,為了更加確保網絡是個合理的分類器,我喜歡可視化網絡第一層的權重,確保自己獲得了有意義的邊緣。如果第一層的濾波器看起來像噪聲,那需要去掉些東西。類似地,網絡內的激活函數有時候也會揭示出一些問題。

00d22b27499c975e96bc95a3f5e27460.png

5. 精調

現在你應該位于數據集一環,探索取得較低驗證損失的架構模型空間。這一步的一些技巧包括:

隨機網格搜索:在同時精調多個超參數時,使用網格搜索聽起來更誘惑,能夠確保覆蓋到所有環境。但記住,使用隨機搜索反而是最佳方式。直觀上,因為神經網絡對一些參數更為敏感。在極限情況下,如果參數 a 很重要,改變 b 卻沒有影響,然后相比于多次在固定點采樣,你寧可徹底采樣 a。

超參數優化:如今社區內有大量好的貝葉斯超參數優化工具箱,我的一些朋友用過后覺得很成功。但我的個人經驗是,探索好的、寬的模型空間和超參數的最佳方法是找個實習生。開玩笑而已,哈哈哈。

6. 最后的壓榨

一旦你找到最好的架構類型和超參數,依然可以使用更多的技巧讓系統變得更好:

集成:模型集成是能將準確率穩定提升 2% 的一種好方式。如果你承擔不起測試階段的計算成本,試著使用《Distilling the Knowledge in a Neural Network》中的方法把你的模型蒸餾到一個網絡。

一直訓練:我經常看到一些人在驗證損失趨平時會中斷模型訓練,以我的經驗來看,網絡會長時間保持非直觀的訓練。寒假時有一次我忘了關掉模型訓練,一月回來后發現它取得了 SOTA 結果。

結論

一旦你做到了這些,你就具備了成功的所有要素:對神經網絡、數據集和問題有了足夠深的了解,配置好了完整的訓練/評估體系,取得高置信度的準確率,逐漸探索更復雜的模型,提升每一步的表現。現在萬事俱備,就可以去讀大量論文,嘗試大量實驗并取得 SOTA 結果了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/454175.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/454175.shtml
英文地址,請注明出處:http://en.pswp.cn/news/454175.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《操作系統》OS學習(三):系統調用

例子 首先看一個標準C庫的例子:當我們程序中使用了C庫中的printf()函數,實際在底層是在內核態中調用了write()函數。圖中右側則是將程序代碼與C庫都算到應用程序中,內核提供了一個系統調用接口。 從這個例子我們可以得到以下幾點&#xff1a…

cygwin/gcc與MinGW

cygwin/gcc和MinGW都是gcc在windows下的編譯環境,但是它們有什么區別?在實際工作中如何選擇這兩種編譯器呢?cygwin/gcc完全可以和在linux下的gcc劃等號,這個從boost庫的劃分中就可以看出來端倪,cygwin下的gcc和linux下的gcc使用的是相同的T…

JavaScript服務器端開發技術(對象屬性的枚舉與查詢)

既然對象是屬性的集合,那么檢測與枚舉集合中的屬性就是一項重要任務。對此,我們來分別看一下ES3和ES5提供的解決方案。 1) ES3枚舉方案 示例代碼: var contacts{ ID:[0,1,2,3,4,5], names:["Zero","One","Two&q…

treelistview 所有節點失去焦點_垃圾詢盤過濾,焦點科技的 Milvus 實踐

文章作者:黎陽,焦點科技軟件開發工程師李成龍,Zilliz 數據工程師Milvus (https://milvus.io/) 向量搜索引擎開源半年以來,全球已經有數百家企業或組織用戶。焦點科技是一家以 B2B 外貿交易為主營業務的科技公司,也是 M…

《操作系統》OS學習(四):計算機體系結構、內存層次和地址生成

計算機除了計算能力之外還有存儲能力,存儲能力即計算機擁有一系列的存儲介質,我們可以在存儲介質上存儲我們的代碼和數據。計算機體系結構中約定了哪些地方可以用來存儲數據:CPU內的寄存器、內存和外存。不同的存儲介質,容量、速度…

GCC中SIMD指令的應用方法

X86架構上的多媒體應用開發,如果能夠使用SIMD指令進行優化, 性能將大大提高。目前,IA-32的SIMD指令包括MMX,SSE,SSE2等幾級。 在GCC的開發環境中,有幾種使用SIMD指令的方式,本文逐一介紹。X86的…

使用angular4和asp.net core 2 web api做個練習項目(二), 這部分都是angular

上一篇: http://www.cnblogs.com/cgzl/p/7755801.html 完成client.service.ts: import { Injectable } from angular/core; import { Http, Headers } from angular/http; import { Observable } from rxjs/Observable; import { ErrorHandler } from angular/core; import rxj…

leelen可視對講怎么接線_樓宇對講系統怎么布線 樓宇對講系統布線方式【介紹】...

隨著智能小區規模不斷增加,樓宇可視對講系統應用越來越廣泛,因而視頻信號的傳輸方式與布線設計顯得越來越重要。視頻信號與數據和音頻信號不同,可行的一種傳輸方式為視頻信號基帶傳輸,下面小編就簡要介紹一下這種傳輸方式和布線方…

路由匯總實例

5.2.2.2 路由匯總策略 之前提到過,在網絡管理員計劃好子網選擇并進行預期地路由匯總時,手動路由匯總工作能取得最佳效果。例如,之前的例子設定好了一個考慮周全的計劃,管理員只使用遠離Yosemite路由器并以10.2開頭的子網。這個規定…

《操作系統》OS學習(五):連續內存分配 內存碎片、動態分配、碎片整理、伙伴系統

內存碎片 在沒有其他方式輔助的情況下,我們分配給一個進程的內存是連續的。在分配時候我們需要有動態分配與碎片處理。如何理解呢?就是每個進程需要一塊內存,我們要選取合適的位置的內存分配給它。當有的進程先結束了內存還給操作系統&#…

GCC 中文手冊 - 摘自純C論壇

GCC Section: GNU Tools (1) Updated: 2003/12/05 Index Return to Main Contents NAME gcc,g-GNU工程的C和C編譯器(egcs-1.1.2) 總覽(SYNOPSIS) gcc[option|filename ]... g[option|filename ]... 警告(WARNING) 本手冊頁內容摘自GNU C編譯器的完整文檔,僅限于解釋選項的含義…

python如何實現支持中文

#codingutf-8print("我要python支持中文") 默認情況下,python是不支持中文的。 如果要實現python支持中文(我是從python3.6開始學習的),只要在python文檔的開頭加入:“#codingutf-8"就可以了。轉載于:h…

世界之窗瀏覽器刪除文本框信息_文本框——Excel里的便利貼

工作表里面的單元格應該是足夠我們來記錄數據和信息了。但是文本框這個功能在工作表中還是存在,可以理解為便利貼功能。插入文本框1.點擊“插入”選項卡。2.然后點擊“文本框”。3.在下拉菜單里面,有兩種可供選擇:橫排文本框和垂直文本框。在…

RHEL 5服務篇—常用網絡配置命令

常用網絡配置命令 在“Linux系統管理”的文章中,大家已經學習了Linux系統的基本管理命令和技巧,為了進一步學習Linux網絡服務打下了良好的基礎。所以我作者以后將陸續推出Linux網絡服務的相關文章。希望大家能給與我大大的支持。 今天我們就來學習一下…

清華大學《操作系統》(六):非連續內存分配 段式、頁式、段頁式存儲管理

背景 連續內存分配給內存分配帶來了很多不便,可能所有空閑片區大小都無法滿足需求大小,這個分配就會失敗。基于這種現狀,就有了非連續內存分配的需求。非連續分配成功的幾率更高,但也面對更多的問題,比如分配時是不是…

python監控文件內容變化_Python監控文件內容變化

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里云文件存儲NAS是一個可共享訪問&#xf…

C語言第三次博客作業---單層循環結構

一、PTA實驗作業。 題目1 1.實驗代碼 int n,i; double height1,height2;//1為輸入身高&#xff0c;2為輸出身高。 char sex; //1<height1<3; //N<1; scanf("%d",&n); while(n--){getchar();scanf("%c%lf",&sex,&height1);switch(sex)…

函數和函數式編程

python的過程就是函數&#xff0c;因為解釋器會隱式地返回默認值None。 實際編程中大部分偏函數更接近過程&#xff0c;不顯示地返回任何東西。 當沒有顯示地返回元素或者如果返回None時&#xff0c;python會返回一個None。 * 元組 ** 字典 def子句的剩余部分包括了一個雖…

清華大學《操作系統》(七):虛擬存儲、覆蓋、交換

接下來幾節都是對虛擬存儲的講解。虛擬存儲是非連續存儲管理的擴展。通過將內存中的數據暫存到外存的方式&#xff0c;為進程提供更大的內存空間。虛擬存儲出現的主要原因是因為程序規模的增長速度遠遠大于存儲器容量的增長速度&#xff0c;導致內存空間不夠用。其實針對內存空…

遵義大數據中心項目工程概況_市委書記張新文到曹州云都大數據中心等項目現場調研建設情況...

4月25日&#xff0c;市委書記張新文到曹縣調研重點項目建設情況&#xff0c;研究推進措施。市委常委、秘書長任仲義參加活動。張新文首先來到曹州云都大數據中心項目建設現場&#xff0c;查看項目推進情況。曹州云都大數據中心&#xff0c;是涵蓋云計算區、研發辦公區、公寓生活…