天天看點

【幹貨】18個技巧實戰深度學習,資深研究員的血淚教訓

我加入了一個綠地項目,負責選擇在計算機視覺平台上使用的核心機器學習算法。

這些算法要麼是不能很好地工作,要麼能夠很好地工作但不能泛化,需要很多時間或在遇到類似的資料集時,它無法收斂。我迷失了。然後,我從學術界抓住了希望,學術界掀起了深度學習的熱風,宣稱它能解決所有問題。

對于深度學習,我是持懷疑态度的,是以我閱讀了很多相關的論文、書籍、筆記等。令我驚訝的是,這不是炒作,深度學習能工作,而且工作得很好。但是,它畢竟是一個新的概念(雖然它的基礎在70年代就已築起了),出現了很多有關如何充分利用深度學習的技巧和 tips(例如 alex krizhevsky 就幾乎概況了大部分的 tips,而且可以說是他預先發現了批标準化)。

下面是我發現的一些有助于充分利用 dnn 的小技巧:

記得要 shuffle。不要讓你的網絡通過完全相同的 minibatch,如果架構允許,在每個 epoch 都 shuffle 一次。

擴充資料集。dnn 需要大量的資料,而且模型在小的資料集上很容易過拟合。我強烈建議你要擴充原始的資料集。如果你的是一個視覺任務,可以增加噪點、增白,減少像素,旋轉或色移,模糊,等等可以擴充的一切。有一點不好的是,假如你擴充得太大,可能訓練的資料大多數是相同的。我建立了一個應用随機變換的層來解決這個問題,這樣就不會有相同的樣本。若果你用的是語音資料,可以進行移位和失真處理。

在整個資料集上訓練之前,先在非常小的子資料集上訓練進行過拟合,這樣你會知道你的網絡可以收斂。這個 tip 來自 karpathy。

始終使用 dropout 将過拟合的幾率最小化。在大小 > 256 (完全連接配接層或卷積層)之後就應該使用 dropout。關于這一點有一篇很好的論文:dropout as a bayesian approximation: representing model uncertainty in deep learning [gal yarin & zoubin ghahramani,2015].

避免 lrn 池化,max 池化會更快。

避免 sigmoid/tanh 的門,它們代價昂貴,容易飽和,而且可能會停止反向傳播。實際上,你的網絡越深,就越應該避免使用 sigmoid 和 tanh。可以使用更便宜而且更有效的 relu 和 prelu 的門,正如在 yoshua bengio 等人的論文 deep sparse rectifier neural networks 中所提到的,這兩者能夠促進稀疏性,而且它們的反向傳播更加魯棒。

在最大池化之前不要使用 relu 或 prelu ,而是在儲存計算之後使用它。

不要使用 relu ,它們太舊了。雖然他們是非常有用的非線性函數,可以解決很多問題。但是,你可以試試用它微調一個新模型,由于 relu 阻礙反向傳播,初始化不好,你沒法得到任何微調效果。但是你應該用 prelu 以及一個非常小的乘數,通常是0.1。使用 prelu 的話收斂更快,而且不會像 relu 那樣在初始階段被卡住。elu 也很好,但成本高。

經常使用批标準化。參考論文:batch normalization: accelerating deep network training by reducing internal covariate shift [sergey ioffe & christian szegedy,2015]。這會很有效。批标準化允許更快的收斂(非常快)以及更小的資料集。這樣你能夠節省時間和資源。

雖然大多數人喜歡删除平均值,不過我不喜歡。我喜歡壓縮輸入資料為[-1,+1]。這可以說是訓練和部署方面的技巧,而不是針對提升性能的技巧。

要能适用更小的模型。假如你是像我這樣部署深度學習模型,你很快就會體會到把千兆位元組規模的模型推給使用者或地球另一端的伺服器的痛苦。哪怕要犧牲一些準确度,也應該小型化。

假如你使用比較小的模型,可以試試 ensemble。通常 ensemble 5個網絡能夠提升準确度約3%。

盡可能使用 xavier 初始化。你可以隻在大的完全連接配接層上使用它,然後避免在 cnn 層上使用。有關這點的解釋可以閱讀這篇文章:an explanation of xavier initialization(by andy jones)

如果你的輸入資料有空間參數,可以試試端到端的 cnn。可以閱讀這篇論文:squeezenet: alexnet-level accuracy with 50x fewer parameters and <0.5mb model size [forrest n. iandola et. al. 2016],它介紹了一種新的方法,而且性能非常好,你可以嘗試應用上面提到的tips。

修改你的模型,隻要可能就使用 1x1 的 cnn 層,它的位置對提高性能很有幫助。

假如沒有高端的 gpu,就不要嘗試訓練任何東西了。

假如你要利用模型或你自己的層來制作模闆,記得把所有東西參數化,否則你得重建所有二進制檔案。

最後,要明白你在做什麼。深度學習就像是機器學習裡的中子彈,它不是任何任務、任何時候都有效的。了解你正在使用的結構以及你試圖達成的目的,才不至于盲目地複制模型。

了解 dl 背後的數學,推薦閱讀 ian goodfellow , yoshua bengio 和 aaron courville 合著的經典教材《深度學習》,這本書真的很好,講解得很清楚。網上有免費的 pdf 版本,但買一本支援作者的貢獻也無妨。

繼續閱讀