摘要雖然梯度下降優(yōu)化算法越來越受歡迎,但通常作為黑盒優(yōu)化器使用,因此很難對其優(yōu)點和缺點的進行實際的解釋。本文旨在讓讀者對不同的算法有直觀的認識,以幫助讀者使用這些算法。在本綜述中,我們介紹梯度下降的不同變形形式,總結這些算法面臨的挑戰(zhàn),介紹最常用的優(yōu)化算法,回顧并行和分布式架構,以及調研用于優(yōu)化梯度下降的其他的策略。 1 引言梯度下降法是最著名的優(yōu)化算法之一,也是迄今優(yōu)化神經網(wǎng)絡時最常用的方法。同時,在每一個最新的深度學習庫中都包含了各種優(yōu)化的梯度下降法的實現(xiàn)(例如:參見lasagne,caffe和keras的文檔)。然而,這些算法通常是作為黑盒優(yōu)化器使用,因此,很難對其優(yōu)點和缺點的進行實際的解釋。 本文旨在讓讀者對不同的優(yōu)化梯度下降的算法有直觀的認識,以幫助讀者使用這些算法。在第2部分,我們首先介紹梯度下降的不同變形形式。在第3部分,我們將簡要總結在訓練的過程中所面臨的挑戰(zhàn)。隨后,在第4部分,我們將介紹最常用的優(yōu)化算法,包括這些算法在解決以上挑戰(zhàn)時的動機以及如何得到更新規(guī)則的推導形式。在第5部分,我們將簡單討論在并行和分布式環(huán)境中優(yōu)化梯度下降的算法和框架。最后,在第6部分,我們將思考對優(yōu)化梯度下降有用的一些其他策略。 梯度下降法是最小化目標函數(shù) 2 梯度下降法的變形形式梯度下降法有3中變形形式,它們之間的區(qū)別為我們在計算目標函數(shù)的梯度時使用到多少數(shù)據(jù)。根據(jù)數(shù)據(jù)量的不同,我們在參數(shù)更新的精度和更新過程中所需要的時間兩個方面做出權衡。 2.1 批梯度下降法Vanilla梯度下降法,又稱為批梯度下降法(batch gradient descent),在整個訓練數(shù)據(jù)集上計算損失函數(shù)關于參數(shù)
因為在執(zhí)行每次更新時,我們需要在整個數(shù)據(jù)集上計算所有的梯度,所以批梯度下降法的速度會很慢,同時,批梯度下降法無法處理超出內存容量限制的數(shù)據(jù)集。批梯度下降法同樣也不能在線更新模型,即在運行的過程中,不能增加新的樣本。 批梯度下降法的代碼如下所示:
對于給定的迭代次數(shù),首先,我們利用全部數(shù)據(jù)集計算損失函數(shù)關于參數(shù)向量 然后,我們利用梯度的方向和學習率更新參數(shù),學習率決定我們將以多大的步長更新參數(shù)。對于凸誤差函數(shù),批梯度下降法能夠保證收斂到全局最小值,對于非凸函數(shù),則收斂到一個局部最小值。 2.2 隨機梯度下降法相反,隨機梯度下降法(stochastic gradient descent, SGD)根據(jù)每一條訓練樣本
對于大數(shù)據(jù)集,因為批梯度下降法在每一個參數(shù)更新之前,會對相似的樣本計算梯度,所以在計算過程中會有冗余。而SGD在每一次更新中只執(zhí)行一次,從而消除了冗余。因而,通常SGD的運行速度更快,同時,可以用于在線學習。SGD以高方差頻繁地更新,導致目標函數(shù)出現(xiàn)如圖1所示的劇烈波動。 圖1:SGD波動(來源:Wikipedia)
與批梯度下降法的收斂會使得損失函數(shù)陷入局部最小相比,由于SGD的波動性,一方面,波動性使得SGD可以跳到新的和潛在更好的局部最優(yōu)。另一方面,這使得最終收斂到特定最小值的過程變得復雜,因為SGD會一直持續(xù)波動。然而,已經證明當我們緩慢減小學習率,SGD與批梯度下降法具有相同的收斂行為,對于非凸優(yōu)化和凸優(yōu)化,可以分別收斂到局部最小值和全局最小值。與批梯度下降的代碼相比,SGD的代碼片段僅僅是在對訓練樣本的遍歷和利用每一條樣本計算梯度的過程中增加一層循環(huán)。注意,如6.1節(jié)中的解釋,在每一次循環(huán)中,我們打亂訓練樣本。
2.3 小批量梯度下降法小批量梯度下降法最終結合了上述兩種方法的優(yōu)點,在每次更新時使用
這種方法,a)減少參數(shù)更新的方差,這樣可以得到更加穩(wěn)定的收斂結果;b)可以利用最新的深度學習庫中高度優(yōu)化的矩陣優(yōu)化方法,高效地求解每個小批量數(shù)據(jù)的梯度。通常,小批量數(shù)據(jù)的大小在50到256之間,也可以根據(jù)不同的應用有所變化。當訓練神經網(wǎng)絡模型時,小批量梯度下降法是典型的選擇算法,當使用小批量梯度下降法時,也將其稱為SGD。注意:在下文的改進的SGD中,為了簡單,我們省略了參數(shù) 在代碼中,不是在所有樣本上做迭代,我們現(xiàn)在只是在大小為50的小批量數(shù)據(jù)上做迭代:
3 挑戰(zhàn)雖然Vanilla小批量梯度下降法并不能保證較好的收斂性,但是需要強調的是,這也給我們留下了如下的一些挑戰(zhàn):
4 梯度下降優(yōu)化算法下面,我們將列舉一些算法,這些算法被深度學習社區(qū)廣泛用來處理前面提到的挑戰(zhàn)。我們不會討論在實際中不適合在高維數(shù)據(jù)集中計算的算法,例如諸如牛頓法的二階方法。 4.1 動量法SGD很難通過陡谷,即在一個維度上的表面彎曲程度遠大于其他維度的區(qū)域[19],這種情況通常出現(xiàn)在局部最優(yōu)點附近。在這種情況下,SGD搖擺地通過陡谷的斜坡,同時,沿著底部到局部最優(yōu)點的路徑上只是緩慢地前進,這個過程如圖2a所示。 圖2:來源:Genevieve B. Orr
如圖2b所示,動量法[16]是一種幫助SGD在相關方向上加速并抑制搖擺的一種方法。動量法將歷史步長的更新向量的一個分量
動量項 從本質上說,動量法,就像我們從山上推下一個球,球在滾下來的過程中累積動量,變得越來越快(直到達到終極速度,如果有空氣阻力的存在,則 4.2 Nesterov加速梯度下降法然而,球從山上滾下的時候,盲目地沿著斜率方向,往往并不能令人滿意。我們希望有一個智能的球,這個球能夠知道它將要去哪,以至于在重新遇到斜率上升時能夠知道減速。 Nesterov加速梯度下降法(Nesterov accelerated gradient,NAG)[13]是一種能夠給動量項這樣的預知能力的方法。我們知道,我們利用動量項
同時,我們設置動量項 圖3:Nesterov更新(來源:G. Hinton的課程6c)
對于NAG的直觀理解的另一種解釋可以參見http://cs231n./neural-networks-3/,同時Ilya Sutskever在其博士論文[18]中給出更詳細的綜述。 既然我們能夠使得我們的更新適應誤差函數(shù)的斜率以相應地加速SGD,我們同樣也想要使得我們的更新能夠適應每一個單獨參數(shù),以根據(jù)每個參數(shù)的重要性決定大的或者小的更新。 4.3 AdagradAdagrad[7]是這樣的一種基于梯度的優(yōu)化算法:讓學習率適應參數(shù),對于出現(xiàn)次數(shù)較少的特征,我們對其采用更大的學習率,對于出現(xiàn)次數(shù)較多的特征,我們對其采用較小的學習率。因此,Adagrad非常適合處理稀疏數(shù)據(jù)。Dean等人[6]發(fā)現(xiàn)Adagrad能夠極大提高了SGD的魯棒性并將其應用于Google的大規(guī)模神經網(wǎng)絡的訓練,其中包含了YouTube視頻中的貓的識別。此外,Pennington等人[15]利用Adagrad訓練Glove詞向量,因為低頻詞比高頻詞需要更大的步長。 前面,我們每次更新所有的參數(shù)
在
對于上述的更新規(guī)則,在
其中, 由于
Adagrad算法的一個主要優(yōu)點是無需手動調整學習率。在大多數(shù)的應用場景中,通常采用常數(shù) Adagrad的一個主要缺點是它在分母中累加梯度的平方:由于沒增加一個正項,在整個訓練過程中,累加的和會持續(xù)增長。這會導致學習率變小以至于最終變得無限小,在學習率無限小時,Adagrad算法將無法取得額外的信息。接下來的算法旨在解決這個不足。 4.4 AdadeltaAdadelta[21]是Adagrad的一種擴展算法,以處理Adagrad學習速率單調遞減的問題。不是計算所有的梯度平方,Adadelta將計算計算歷史梯度的窗口大小限制為一個固定值 在Adadelta中,無需存儲先前的
我們將
我們先前得到的Adagrad參數(shù)更新向量變?yōu)椋?/p>
現(xiàn)在,我們簡單將對角矩陣
由于分母僅僅是梯度的均方根(root mean squared,RMS)誤差,我們可以簡寫為:
作者指出上述更新公式中的每個部分(與SGD,動量法或者Adagrad)并不一致,即更新規(guī)則中必須與參數(shù)具有相同的假設單位。為了實現(xiàn)這個要求,作者首次定義了另一個指數(shù)衰減均值,這次不是梯度平方,而是參數(shù)的平方的更新:
因此,參數(shù)更新的均方根誤差為:
由于
使用Adadelta算法,我們甚至都無需設置默認的學習率,因為更新規(guī)則中已經移除了學習率。 4.5 RMSpropRMSprop是一個未被發(fā)表的自適應學習率的算法,該算法由Geoff Hinton在其Coursera課堂的課程6e中提出。 RMSprop和Adadelta在相同的時間里被獨立的提出,都起源于對Adagrad的極速遞減的學習率問題的求解。實際上,RMSprop是先前我們得到的Adadelta的第一個更新向量的特例:
同樣,RMSprop將學習率分解成一個平方梯度的指數(shù)衰減的平均。Hinton建議將 4.6 Adam自適應矩估計(Adaptive Moment Estimation,Adam)[9]是另一種自適應學習率的算法,Adam對每一個參數(shù)都計算自適應的學習率。除了像Adadelta和RMSprop一樣存儲一個指數(shù)衰減的歷史平方梯度的平均
通過計算偏差校正的一階矩和二階矩估計來抵消偏差:
正如我們在Adadelta和RMSprop中看到的那樣,他們利用上述的公式更新參數(shù),由此生成了Adam的更新規(guī)則:
作者建議 4.7 算法可視化下面兩張圖給出了上述優(yōu)化算法的優(yōu)化行為的直觀理解。(還可以看看這里關于Karpathy對相同的圖片的描述以及另一個簡明關于算法討論的概述)。 在圖4a中,我們看到不同算法在損失曲面的等高線上走的不同路線。所有的算法都是從同一個點出發(fā)并選擇不同路徑到達最優(yōu)點。注意:Adagrad,Adadelta和RMSprop能夠立即轉移到正確的移動方向上并以類似的速度收斂,而動量法和NAG會導致偏離,想像一下球從山上滾下的畫面。然而,NAG能夠在偏離之后快速修正其路線,因為NAG通過對最優(yōu)點的預見增強其響應能力。 圖4b中展示了不同算法在鞍點出的行為,鞍點即為一個點在一個維度上的斜率為正,而在其他維度上的斜率為負,正如我們前面提及的,鞍點對SGD的訓練造成很大困難。這里注意,SGD,動量法和NAG在鞍點處很難打破對稱性,盡管后面兩個算法最終設法逃離了鞍點。而Adagrad,RMSprop和Adadelta能夠快速想著梯度為負的方向移動,其中Adadelta走在最前面。
圖4:來源和全部動畫:Alec Radford
正如我們所看到的,自適應學習速率的方法,即 Adagrad、 Adadelta、 RMSprop 和Adam,最適合這些場景下最合適,并在這些場景下得到最好的收斂性。 4.8 選擇使用哪種優(yōu)化算法?那么,我們應該選擇使用哪種優(yōu)化算法呢?如果輸入數(shù)據(jù)是稀疏的,選擇任一自適應學習率算法可能會得到最好的結果。選用這類算法的另一個好處是無需調整學習率,選用默認值就可能達到最好的結果。 總的來說,RMSprop是Adagrad的擴展形式,用于處理在Adagrad中急速遞減的學習率。RMSprop與Adadelta相同,所不同的是Adadelta在更新規(guī)則中使用參數(shù)的均方根進行更新。最后,Adam是將偏差校正和動量加入到RMSprop中。在這樣的情況下,RMSprop、Adadelta和Adam是很相似的算法并且在相似的環(huán)境中性能都不錯。Kingma等人[9]指出在優(yōu)化后期由于梯度變得越來越稀疏,偏差校正能夠幫助Adam微弱地勝過RMSprop。綜合看來,Adam可能是最佳的選擇。 有趣的是,最近許多論文中采用不帶動量的SGD和一種簡單的學習率的退火策略。已表明,通常SGD能夠找到最小值點,但是比其他優(yōu)化的SGD花費更多的時間,與其他算法相比,SGD更加依賴魯棒的初始化和退火策略,同時,SGD可能會陷入鞍點,而不是局部極小值點。因此,如果你關心的是快速收斂和訓練一個深層的或者復雜的神經網(wǎng)絡,你應該選擇一個自適應學習率的方法。 5 并行和分布式SGD當存在大量的大規(guī)模數(shù)據(jù)和廉價的集群時,利用分布式SGD來加速是一個顯然的選擇。SGD本身有固有的順序:一步一步,我們進一步進展到最小。SGD提供了良好的收斂性,但SGD的運行緩慢,特別是對于大型數(shù)據(jù)集。相反,SGD異步運行速度更快,但客戶端之間非最理想的通信會導致差的收斂。此外,我們也可以在一臺機器上并行SGD,這樣就無需大的計算集群。以下是已經提出的優(yōu)化的并行和分布式的SGD的算法和框架。 5.1 Hogwild!Niu等人[14]提出稱為Hogwild!的更新機制,Hogwild!允許在多個CPU上并行執(zhí)行SGD更新。在無需對參數(shù)加鎖的情況下,處理器可以訪問共享的內存。這種方法只適用于稀疏的輸入數(shù)據(jù),因為每一次更新只會修改一部分參數(shù)。在這種情況下,該更新策略幾乎可以達到一個最優(yōu)的收斂速率,因為CPU之間不可能重寫有用的信息。 5.2 Downpour SGDDownpour SGD是SGD的一種異步的變形形式,在Google,Dean等人[6]在他們的DistBelief框架(TensorFlow的前身)中使用了該方法。Downpour SGD在訓練集的子集上并行運行多個模型的副本。這些模型將各自的更新發(fā)送給一個參數(shù)服務器,參數(shù)服務器跨越了多臺機器。每一臺機器負責存儲和更新模型的一部分參數(shù)。然而,因為副本之間是彼此不互相通信的,即通過共享權重或者更新,因此可能會導致參數(shù)發(fā)散而不利于收斂。 5.3 延遲容忍SGD通過容忍延遲算法的開發(fā),McMahan和Streeter[11]將AdaGraad擴展成并行的模式,該方法不僅適應于歷史梯度,同時適應于更新延遲。該方法已經在實踐中被證實是有效的。 5.4 TensorFlowTensorFlow[1]是Google近期開源的框架,該框架用于實現(xiàn)和部署大規(guī)模機器學習模型。TensorFlow是基于DistBelief開發(fā),同時TensorFlow已經在內部用來在大量移動設備和大規(guī)模分布式系統(tǒng)的執(zhí)行計算。在2016年4月發(fā)布的分布式版本依賴于圖計算,圖計算即是對每一個設備將圖劃分成多個子圖,同時,通過發(fā)送、接收節(jié)點對完成節(jié)點之間的通信。 5.5 彈性平均SGDZhang等人[22]提出的彈性平均SGD(Elastic Averaging SGD,EASGD)連接了異步SGD的參數(shù)客戶端和一個彈性力,即參數(shù)服務器存儲的一個中心變量。EASGD使得局部變量能夠從中心變量震蕩得更遠,這在理論上使得在參數(shù)空間中能夠得到更多的探索。經驗表明這種增強的探索能力通過發(fā)現(xiàn)新的局部最優(yōu)點,能夠提高整體的性能。 6 優(yōu)化SGD的其他策略最后,我們介紹可以與前面提及到的任一算法配合使用的其他的一些策略,以進一步提高SGD的性能。對于其他的一些常用技巧的概述可以參見[10]。 6.1 數(shù)據(jù)集的洗牌和課程學習總的來說,我們希望避免向我們的模型中以一定意義的順序提供訓練數(shù)據(jù),因為這樣會使得優(yōu)化算法產生偏差。因此,在每一輪迭代后對訓練數(shù)據(jù)洗牌是一個不錯的主意。 另一方面,在很多情況下,我們是逐步解決問題的,而將訓練集按照某個有意義的順序排列會提高模型的性能和SGD的收斂性,如何將訓練集建立一個有意義的排列被稱為課程學習[3]。 Zaremba and Sutskever[20]只能使用課程學習訓練LSTM來評估簡單程序,并表明組合或混合策略比單一的策略更好,通過增加難度來排列示例。 6.2 批量歸一化為了便于學習,我們通常用0均值和單位方差初始化我們的參數(shù)的初始值來歸一化。 隨著不斷訓練,參數(shù)得到不同的程度的更新,我們失去了這種歸一化,隨著網(wǎng)絡變得越來越深,這種現(xiàn)象會降低訓練速度,且放大參數(shù)變化。 批量歸一化[8]在每次小批量數(shù)據(jù)反向傳播之后重新對參數(shù)進行0均值單位方差標準化。通過將模型架構的一部分歸一化,我們能夠使用更高的學習率,更少關注初始化參數(shù)。批量歸一化還充當正則化的作用,減少(有時甚至消除)Dropout的必要性。 6.3 Early stopping如Geoff Hinton所說:“Early Stopping是美麗好免費午餐”(NIPS 2015 Tutorial slides)。你因此必須在訓練的過程中時常在驗證集上監(jiān)測誤差,在驗證集上如果損失函數(shù)不再顯著地降低,那么應該提前結束訓練。 6.4 梯度噪音Neelakantan等人[12]在每個梯度更新中增加滿足高斯分布
高斯分布的方差需要根據(jù)如下的策略退火:
他們指出增加了噪音,使得網(wǎng)絡對不好的初始化更加魯棒,同時對深層的和復雜的網(wǎng)絡的訓練特別有益。他們猜測增加的噪音使得模型更優(yōu)機會逃離當前的局部最優(yōu)點,以發(fā)現(xiàn)新的局部最優(yōu)點,這在更深層的模型中更加常見。 7 總結在這篇博客文章中,我們初步研究了梯度下降的三個變形形式,其中,小批量梯度下降是最受歡迎的。 然后我們研究了最常用于優(yōu)化SGD的算法:動量法,Nesterov加速梯度,Adagrad,Adadelta,RMSprop,Adam以及不同的優(yōu)化異步SGD的算法。 最后,我們已經考慮其他一些改善SGD的策略,如洗牌和課程學習,批量歸一化和early stopping。 參考文獻
|
|
|