Google研究员Ilya Sutskever:成功训练LDNN的13点建议
Google研究員Ilya Sutskever:成功訓練LDNN的13點建議
width="22" height="16" src="http://hits.sinajs.cn/A1/weiboshare.html?url=http%3A%2F%2Fwww.csdn.net%2Farticle%2F2015-06-29%2F2825073&type=3&count=&appkey=&title=%E6%9C%AC%E6%96%87%E7%94%B1Ilya%20Sutskever%EF%BC%88Google%E7%A0%94%E7%A9%B6%E5%91%98%E3%80%81%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E6%B3%B0%E6%96%97Geoffrey%20Hinton%E7%9A%84%E5%AD%A6%E7%94%9F%E3%80%81DNNresearch%E8%81%94%E5%90%88%E5%88%9B%E5%A7%8B%E4%BA%BA%EF%BC%89%E6%89%80%E5%86%99%EF%BC%8C%E8%AE%B2%E8%BF%B0%E4%BA%86%E6%9C%89%E5%85%B3%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E8%A7%81%E8%A7%A3%E5%8F%8A%E5%AE%9E%E7%94%A8%E5%BB%BA%E8%AE%AE%EF%BC%8C%E5%8C%85%E6%8B%AC%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E4%B8%BA%E4%BB%80%E4%B9%88%E5%BC%BA%E5%A4%A7%EF%BC%8C%E5%A6%82%E4%BD%95%E5%BC%BA%E5%A4%A7%EF%BC%8C%E4%BB%A5%E5%8F%8A%E8%AE%AD%E7%BB%83%E6%B7%B1%E5%BA%A6%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E7%9A%84tricks%E3%80%82&pic=&ralateUid=&language=zh_cn&rnd=1435670500257" frameborder="0" scrolling="no" allowtransparency="true">摘要:本文由Ilya Sutskever(Google研究員、深度學習泰斗Geoffrey Hinton的學生、DNNresearch聯合創始人)所寫,講述了有關深度學習的見解及實用建議,包括深度學習為什么強大,如何強大,以及訓練深度神經網絡的tricks。
【編者按】本文由Ilya Sutskever(Google研究員、深度學習泰斗Geoffrey Hinton的學生、DNNresearch的聯合創始人)受Yisong Yue之邀所寫,綜合講述了有關深度學習的見解及實用建議。文章由Yisong Yue授權《程序員》電子刊翻譯,并刊載于《程序員》15·2B期。
近年來IT界里掀起了一股深度學習熱,有望成為下一個技術創新風口。在諸如語音識別、影像識別及其他語言相關的如機器翻譯等領域里,深度學習業已取得了相當不錯的成績。
為什么呢?深度學習究竟有何神通?(接下來在論述深度神經網絡時,會簡寫為LDNN,Large Deep Neural Networks)現在的LDNN與過去又有何異同?最后,或許你會問及如何訓練一個LDNN。坊間流行的說法是“難,難,難”,同時給LDNN訓練披上了一件有著“黑色魔法”的外衣——經驗,經驗!誠然經驗不可或缺,但不應過分夸大。此外,很多開源神經網絡方案已幫助不少初學者找到了入門捷徑(如Caffe、cuda-convnet、Torch、Theano等)。
為什么深度學習是可行的
首先,工欲善其事,必先利其器。如果缺乏一個足夠強大的模型,再好的學習算法也只能隔靴搔癢。
其次,該模型必須是可訓練的。否則在瞬息萬變的時代,不可訓練的模型無疑是阿喀琉斯之踵。
慶幸的是,LDNN既強大又可訓練。
LDNN究竟強在哪里
談及LDNN時,我通常指的是10-20層的神經網絡(這是現有算法所能駕馭的)。以下列舉了幾點有關LDNN的強大之處。
傳統統計學模型學習的是簡單的模式或群集。相反,LDNN學習的是計算,盡管進行大規模并行運算時需要適量的計算步驟。這就是LDNN與其他統計模型的重要分水嶺。
更具體地說:眾所周知,任何算法都可由合適的深層電路圖來實現(如把算法實現中的每一時步作為一層)。而且,電路圖層次越深,電路算法實現的難度越大(比方說運行時)。如果把神經網絡用作電路圖,越深層的神經網絡越能執行更多的算法運算——深度=力度。
注意:需要明白一點的是神經網絡中的單個神經元能夠對輸入聚集或輸入分集進行計算,要做的就是對它們的連接賦上合適的值。
出人意料的是,事實上神經網絡比布爾電路更加高效。進一步說,要解決某個問題,一個相當淺層DNN的層次開銷比布爾電路所需的要少得多。例如,一個有著兩個隱藏層和適量計算單元的DNN能夠對NN位數字進行排序。當我知道這結論時是相當的驚訝,所以我嘗試創建一個小型神經網絡然后訓練它使之對106位數字進行排序,其執行結果與結論高度一致!而如果使用布爾電路對NN位數排序,在相同條件下,這是實現不了的。
DNN比布爾電路高效的原因是神經元會執行閾值操作,而微布爾電路則做不到。
最后,盡管人類神經元速度慢,但能在短時間內完成很多復雜的任務。具體地說,有個常識是一個人類神經元每秒的運作次數少于100次。意即假若某人能在0.1秒內解決問題,我們的神經元在足夠時間內只會運作10次。所以說一個10層大型神經網絡能夠完成任何人類需時0.1秒來做完的任務。
人的普遍認知是人類神經元要比人工神經元強大得多,但其實有可能相反。究竟孰優孰劣,暫時還言之尚早。
有趣的是,人類通常能在0.1秒左右解決極其復雜的認知問題。例如,對于眼前的事物,不論是表情,臉部還是語言交流,我們都能很快識別并作出反應。事實上,如果世上有一個人能解決最復雜的問題,即使僅有一位,也足夠說服人們相信LDNN能做到相同的事情——務必確保獲得正確的數據輸入。
小型神經網絡可行嗎?也許是的。人的神經網絡必定無法進行指數級生長,因為人的腦部是不可能瘋長的!如果人的神經元出現雜音,意思是當一個人工神經元可以完成需要多個人類神經元合力才能完成的工作時,與人腦相匹配的DNN所需的神經元個數將明顯減少。
上述的幾個爭論點主要闡明了在不同情況下,存在著一個能基本解決問題的LDNN連接配置。關鍵的,解決問題所需的單元個數要遠少于指數級;因此,利用現有硬件來訓練并獲得一個高性能網絡是可行的。最后的這點非常重要,以下繼續深入說明。
我們知道機器進行算法學習是持續性的:也就是說,只要提供充足的數據,它們就能把問題解決。但持續性往往意味著指數級的大數據量。舉例來說,當最近鄰算法把所有可能性都考慮到了,便能解決任何問題;向量機與此類似,需要做的是提供足夠的訓練樣本。這同樣適用于一個有著單個隱藏層的神經網絡:如果每個可能的訓練樣本都對應著一個神經元,而該神經元不關心其他事例,那么我們便可從輸入和輸出中學習并展示每個可能的功能。問題解決依賴于數據,但在有限的資源里不一定任何時候都能實現。
這便是LDNN與舊版的區別:使用大型而非巨大的LDNN來解決實際問題。如果人能短時間內解決問題,就足以證明即使是最小型神經網絡也蘊藏著巨大的能力。
我必須承認的一點是,DNN能否把給定的問題解決好還有待時間來證明,雖然LDNN常常能在可操作的數據范圍內把同一個問題處理好。
這就是我要說的。對于某個問題,例如是視覺目標識別,我們所要做的是要對一個50層巨型卷積碼神經網絡進行訓練。顯然達到如此級別的神經網絡足以與人類神經網絡媲美,不是嗎?所以找到這樣的權值是成敗的關鍵。
學習
什么是學習?學習是為神經網絡權值找到合適的設置值來使訓練數據效益最大化。換言之,我們要把來自標識數據的信息作為輸入參數,以供神經網絡使用。
深度學習的成功取決于一個幸運的事實:精心調配并已初始化好的隨機梯度下降法(SGD)能夠很好地對LDNN進行訓練。這是有意義的,因為一個神經網絡的訓練錯誤也是其權值的功能時,該錯誤是高度非凸的。當進行非凸優化時,其結果是不可預知的;只有結果為凸是好的,非凸就是不好的。但SGD看起來似乎能對此做出改善。對神經網絡進行訓練是個NP困難,事實上要找出有著3個隱藏單元的神經網絡最佳數據集是NP困難的。而SGD能在實際中解決該問題。這是深度學習的立足之本。
可以相當自信地說,成功的LDNN訓練依賴于數據的“簡單”關聯,從而使LDNN不斷自我學習以解決數據的“復雜”關聯。對此我有著一個成功的實驗:訓練一個神經網絡來解決奇偶問題是較困難的。我成功實現了25bits、29bits的檢驗,但從來沒有超過30bits(或許有人可以實現,但我真的還沒有)。現在,我們知道奇偶問題是非常不穩定的,它缺乏任何的線性關聯:每個線性輸入與輸出是不關聯的,這對于神經網絡是個問題,因為在初始化時神經網絡是高度線性的(難道說我需要使用更大的初始權值?有關權值初始問題會在稍后講述)。所以我的假設是(很多專家也分享過),當神經網絡開始進行學習時就已關注到輸入輸出高度關聯,當引入隱藏單元對此進行監測時,神經網絡便可處理更復雜的關聯。我設想了更多樣的關聯,包括簡單和復雜,一個網絡從一個關聯跳入更復雜的關聯,這不正是機會主義登山者的真實寫照嗎?
泛化
雖然有關神經網絡優化還缺乏實質性談資(除了又凸又無聊的局部最小值問題),相比之下泛化的討論則可有趣且具體得多。
例如以下這件往事:Valiant在1984年發表一篇名為“可學習理論”的著名論文,他簡單證明了如果給定有限的函數個數,比方說N個,一旦有著比log N更多的訓練案例而該增量是個很小的常量因子時,每次訓練錯誤將會接近每次測試錯誤。顯然,如果所有的訓練錯誤都接近它的測試錯誤,那么過度擬合基本上是不可能的(當訓練錯誤和測試錯誤之間差距太大的時候才會發生擬合。我也曾在Vapnik書中看過類似結論)。這個定理很容易證明,這里就不多說了。
但這個簡單的結果對任何神經網絡的實現都有著非常重要的意義。假如有一個含有N個參數的神經網絡,每個參數都是32位float。那么當一個神經網絡被指定為32×N bits時,那么意味著不同的神經網絡不會超過232?,甚至更少。也就是說,一旦有著超過32×N的訓練樣本,我們不會過度擬合多少。這樣很好。理論上我們可以對參數進行計數。更重要的是,如果我們確信每個權值僅需要4個bits,而其他都是噪值,那么訓練樣本的數字必定是一個很小的常量因子4×N,而不是32×N。
結論
如果我們要使用一個LDNN來解決難題,就需要給予足夠的參數。所以我們需要一個超高質量的標記訓練集,使之確保有足夠的信息來匹配所有的網絡連接。一旦得到了該訓練集,我們應該在這之上運行SGD直到問題解決。如果神經網絡是較大而深的,這是可實現的。
80年代以來的改變
過去,人們曾認為神經網絡可以解決“一切問題”。但最后為什么沒有成功呢?這里面有如下幾個原因。
- 過去計算機速度很慢,因此過去的神經網絡是微型的,這導致性能的先天不足。換句話說,小型神經網絡功能不強。
- 數據集很小。即使能奇跡般地訓練LDNN,也缺乏足夠的大信息數據集來約束巨量的神經網絡參數。所以失敗是不可避免的。
- 沒有人知道如何訓練深度網絡。深度網絡很重要。當前20-25個連續圈層是最好的對象識別網絡配置。一個兩層的神經網絡注定在對象識別上是低效的。在過去人們認為SGD不可能用來訓練深度網絡,因為當時認為這是難以置信的。
科學發展是多么的有趣,特別是回首以往,會發現現在進行深度神經網絡訓練是小事一樁了。
實踐建議
好吧,或許你已經躍躍欲試了。LDNN代表著現在也代表著未來,難道不想訓練它?但傳言說LDNN很高深,這是真的嗎?過去或許是,但現在很多社區已經做出努力和嘗試,只要把以下所述牢記于心,訓練神經網絡就不會太難。下面是有關社區的知識總結,這很重要請仔細閱讀。
獲取數據:確保要有高質量的輸入/輸出數據集,這個數據集要足夠大、具有代表性以及擁有相對清楚的標簽。缺乏數據集是很難成功的。
預處理:將數據進行集中是非常重要的,也就是要使數據均值為0,從而使每個維度的每次變動為1。有時,當輸入的維度隨量級排序變化時,最好使用那個維度的log(1+x)。基本上,重要的是要找到一個0值的可信編碼以及自然分界的維度。這樣做可使學習工作得更好。情況就是這樣的,因為權值是通過公式來更新的:wij中的變化 \propto xidL/dyj(w表示從層x到層y的權值,L是損失函數)。如果x的均值很大(例如100),那么權值的更新將會非常大,并且是相互關聯的,這使得學習變得低劣而緩慢。保持0均值和較小的方差是成功的關鍵因素。
批處理:在如今的計算機上每次只執行一個訓練樣本是很低效的。反之如果進行的是128個例子的批處理,效率將大幅提高,因為其輸出量是非常可觀的。事實上使用數量級為1的批處理效果不錯,這不僅可獲得性能的提升同時可降低過度擬合;不過這有可能會被大型批處理超越。但不要使用過大的批處理,因為有可能導致低效和過多過度擬合。所以我的建議是:根據硬件配置選取適合的批處理規模,量力而為會更加高效。
梯度歸一化:根據批處理的大小來拆分梯度。這是一個好主意,因為如果對批處理進行倍增(或倍減),無需改變學習率(無論如何,不要太多)。
學習率計劃:從一個正常大小的學習率(LR)開始,朝著終點不斷縮小。
1LR的典型取值是0.1,令人驚訝的是,對于大量的神經網絡問題來說,0.1是學習率的一個很好的值。通常學習率傾向于更小而非更大。使用一個驗證集——一個不進行訓練的訓練集子集,來決定何時降低學習率以及何時停止訓練(例如當驗證集的錯誤開始增多的時候)。
學習率計劃的實踐建議:若發現驗證集遭遇瓶頸,不妨將LR除以2(或5),然后繼續。最終,LR將會變得非常小,這也到了停止訓練的時候了。這樣做可以確保在驗證性能受到損害的時候,你不會擬合(或過度擬合)訓練數據。降低LR是很重要的,通過驗證集來控制LR是個正確的做法。
但最重要的是要關注學習率。一些研究人員(比如Alex Krizhevsky)使用的方法是,監視更新范數和權值范數之間的比率。比率取值大約為10ˉ3。如果取值過小,那么學習會變得非常慢;如果取值過大,那么學習將會非常不穩定甚至失敗。
權值初始化。關注權值在學習開始時的隨機初始化。
如果想偷懶,不妨試試0.02*randn(num_params)。這個范圍的值在許多不同的問題上工作得很好。當然,更小(或更大)的值也值得一試。如果它工作得不好(例如是一個非常規的和/或非常深的神經網絡架構),那么需要使用init_scale/sqrt(layer_width)*randn來初始化每個權值矩陣。在這種情況下,init_scale應該設置為0.1或者1,或者類似的值。
對于深度且循環的網絡,隨機初始化是極其重要的。如果沒有處理好,那么它看起來就像沒有學習到任何東西。我們知道,一旦條件都設置好了,神經網絡就會學習。
一個有趣的故事:多年來,研究人員相信SGD不能訓練來自隨機初始化的深度神經網絡。每次嘗試都以失敗告終。令人尷尬的是,他們沒有成功是因為使用“小的隨機權值”來進行初始化,雖然小數值的做法在淺度網絡上工作得非常好,但在深度網絡上的表現一點也不好。當網絡很深時,許多權值矩陣之間會進行乘積,所以不好的結果會被放大。
但如果是淺度網絡,SGD可以幫助我們解決該問題。
所以關注初始化是很有必要的。嘗試多種不同的初始化,努力就會得到回報。如果網絡完全不工作(即沒法實施),繼續改進隨機初始化是正確的選擇。
如果正在訓練RNN或者LSTM,要對梯度(記得梯度已除以批量大小)范數使用一個硬約束。像15或者5這樣的約束在我個人的實驗中工作得很好。請將梯度除以批處理大小,再檢查一下它的范數是否超過15(或5)。如果超過了,將它縮小到15(或5)。這個小竅門在RNN和LSTM的訓練中發揮著巨大作用,不這樣做的話,爆炸性的梯度將會導致學習失敗,最后不得不使用像1e-6這樣微小而無用的學習率。
數值梯度檢查:如果沒有使用過Theano或者Torch,梯度實現只能親力親為了。在實現梯度的時候很容易出錯,所以使用數值梯度檢查是至關重要的。這樣做會讓你對自己的代碼充滿信心。調整超級參數(比如學習率和初始化)是非常有價值的,因此好刀要用在刀刃上。
如果正在使用LSTM同時想在具有大范圍依賴的問題上訓練它們,那么應該將LSTM遺忘關口的偏差初始化為較大的值。默認狀態下,遺忘關口是S型的全部輸入,當權值很小時,遺忘關口會被設置為0.5,這只能對部分問題有效。這是對LSTM初始化的一個警示。
數據增加(Data augmentation):使用算法來增加訓練實例數量是個有創意的做法。如果是圖像,那么應該轉換和旋轉它們;如果是音頻,應該將清晰的部分和所有類型的雜音進行混合處理。數據添加是一門藝術(除非是在處理圖像),這需要一定的常識。
dropout:dropout提供了一個簡單的方法來提升性能。記得要調整退出率,而在測試時不要忘記關閉dropout,然后對權值求乘積(也就是1-dropout率)。當然,要確保將網絡訓練得更久一點。不同于普通訓練,在進入深入訓練之后,驗證錯誤通常會有所增加。dropout網絡會隨著時間推移而工作得越來越好,所以耐心是關鍵。
綜合(Ensembling)。訓練10個神經網絡,然后對其預測數據進行平均。該做法雖然簡單,但能獲得更直接、更可觀的性能提升。有人可能會困惑,為什么平均會這么有效?不妨用一個例子來說明:假如兩個分類器的錯誤率為70%,如果其中一個的正確率保持較高,那么平均后的預測會更接近正確結果。這對于可信網絡的效果會更加明顯,當網絡可信時結果是對的,不可信時結果是錯的。
以上13點意見涵蓋了成功訓練LDNN的一切,希望我沒有遺漏。
最后總結如下:
- LDNN是非常強大的;
- 如果有臺高性能計算機,LDNN是可訓練的;
- 如果有一個超高質量的數據集,我們可以為任務找到最好的LDNN;
- LDNN可以解決問題,或者說至少對解決問題有所幫助。
寫在最后
未來會是怎樣的呢?預測未來顯然是困難的,但一般而言,能夠執行更多計算的模型也許會非常好。神經圖靈機在這個方向上邁出了非常重要的一步。其他問題,包括無監督學習,截止2015年1月8日,于我而言還僅是冰山一角。使用無監督學習來學習復雜數據是個很好的嘗試。路漫漫其修遠兮,我們仍需努力。?
總結
以上是生活随笔為你收集整理的Google研究员Ilya Sutskever:成功训练LDNN的13点建议的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 线性判别分析(Linear Discri
- 下一篇: 深度学习-LeCun、Bengio和Hi