Nikolas Markou自 2013 年以來就一直在使用深度學習和深度置信網絡。他曾加入了一個綠地項目,負責選擇在計算機視覺平臺上使用的核心機器學習算法。這些算法要麼是不能很好地工作,要麼能夠很好地工作但不能泛化,需要很多時間或在遇到類似的數據集時,它無法收斂。Nikolas Markou迷失了。然後,他從學術界抓住了希望,學術界掀起了深度學習的熱風,宣稱它能解決所有問題。
對於深度學習,Nikolas Markou是持懷疑態度的,所以他閱讀了很多相關的論文、書籍、筆記等。令Nikolas Markou驚訝的是,這不是炒作,深度學習能工作,而且工作得很好。但是,它畢竟是一個新的概念(雖然它的基礎在70年代就已築起了),出現了很多有關如何充分利用深度學習的技巧和 tips(例如 Alex Krizhevsky 就幾乎概況了大部分的 tips,而且可以說是他預先發現了批標準化)。
下面是Nikolas Markou發現的一些有助於充分利用 DNN 的小技巧:
記得要 shuffle。不要讓你的網絡通過完全相同的 minibatch,如果框架允許,在每個 epoch 都 shuffle 一次。
擴展數據集。DNN 需要大量的數據,而且模型在小的數據集上很容易過擬合。Nikolas Markou強烈建議你要擴展原始的數據集。如果你的是一個視覺任務,可以增加噪點、增白,減少像素,旋轉或色移,模糊,等等可以擴展的一切。有一點不好的是,假如你擴展得太大,可能訓練的數據大多數是相同的。Nikolas Markou創建了一個應用隨機變換的層來解決這個問題,這樣就不會有相同的樣本。若果你用的是語音數據,可以進行移位和失真處理。
在整個數據集上訓練之前,先在非常小的子數據集上訓練進行過擬合,這樣你會知道你的網絡可以收斂。這個 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]。這會很有效。批標準化允許更快的收斂(非常快)以及更小的數據集。這樣你能夠節省時間和資源。雖然大多數人喜歡刪除平均值,不過Nikolas Markou不喜歡。Nikolas Markou喜歡壓縮輸入數據為[-1,+1]。這可以說是訓練和部署方面的技巧,而不是針對提升性能的技巧。
要能適用更小的模型。假如你是像Nikolas Markou這樣部署深度學習模型,你很快就會體會到把千兆字節規模的模型推給用戶或地球另一端的伺服器的痛苦。哪怕要犧牲一些準確度,也應該小型化。
假如你使用比較小的模型,可以試試 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。