1. 程式人生 > >【轉】18個技巧實戰深度學習,資深研究員的血淚教訓

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

作者:chen_h
微訊號 & QQ:862251340
微信公眾號:coderpai

(文/Nikolas Markou)我自 2013 年以來就一直在使用深度學習和深度置信網路。

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

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

對於深度學習,我是持懷疑態度的,所以我閱讀了很多相關的論文、書籍、筆記等。令我驚訝的是,這不是炒作,深度學習能工作,而且工作得很好。但是,它畢竟是一個新的概念(雖然它的基礎在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 版本,但買一本支援作者的貢獻也無妨。

此外,如果想了解深度學習的歷史和介紹,可以閱讀鄧力和俞棟合著的《深度學習:方法及應用》。

如果真的想從頭開始實現演算法,可以閱讀 Timothy Masters 寫的 Deep Belief Nets in C++ and CUDA C, Vol. 1: Restricted Boltzmann Machines and Supervised Feedforward Networks。

原文:新智元