常永虎,李虎陽
(遵義醫(yī)科大學醫(yī)學信息工程學院,遵義563000)
以往建立一個機器學習模型需要清洗數(shù)據(jù)、找特征、構建模型并訓練和應用模型四個階段。在這個過程當中,時間成本最高的環(huán)節(jié)是找特征。深度學習由于能夠自動找特征,從而降低模型建立的人工時間成本而變得流行,它使工程師只需經歷清洗數(shù)據(jù)、構建模型、訓練和應用模型三個階段就可以完成一個任務。但不管機器學習算法還是深度學習算法,都需經歷訓練模型階段。此階段是計算復雜度最高的階段,甚至用幾百臺機器投入幾天到幾個月來解決模型訓練問題也是很常見的。一個好的模型訓練算法通??梢越档湍P陀柧毜挠嬎銖碗s度,也可以提高模型的精確度,使模型達到最優(yōu)結果。在此過程中使用到的算法通常叫做優(yōu)化算法,梯度下降類算法作為最流行的優(yōu)化算法之一,目前是神經網絡問題中最常用的優(yōu)化算法。
機器學習類算法研究的熱潮不斷高漲,各類開源機器學習框架也層出不窮,其中包括Karas、Tensor-Flow、Caffe、MXNet、pandas、scipy 等。雖然這些框架中都已經集成了常用的梯度下降類算法,但不同的梯度下降算法在不同的模型訓練中會表現(xiàn)出不同的性能,也不是最先進的梯度下降類算法在所有的模型中都表現(xiàn)最優(yōu)。因此,本文的目的是通過對比梯度下降類算法在不同模型中的表現(xiàn),為讀者直觀地呈現(xiàn)不同梯度下降類算法的效果,從而幫助讀者在實際模型訓練過程中選擇更合適的梯度下降類算法
在微積分中,對多元函數(shù)的參數(shù)求解偏導數(shù),然后以向量的形式將各個參數(shù)的偏導數(shù)寫出來就是梯度。如函數(shù)f(x,y),分別對x 和y 求偏導數(shù),求得的偏導數(shù)組成的向量是(?f/?x,?f/?y)就是梯度。梯度下降算法是求解無約束優(yōu)化問題的最簡單、最經典的方法之一。它的目的是找到目標函數(shù)J(θ)取極小值點時的θ值,其中參數(shù)θ屬于Rn空間。它的基本思想是沿著J(θ)的梯度反方向不斷的更新θ,并設置一個學習率η決定其每次更新的步長直到J(θ)的結果足夠小。以此來達到最小化目標函數(shù)的目的。
最原始的梯度下降法叫做批梯度下降法,此方法的基本思路是每次都在整個數(shù)據(jù)集上計算損失函數(shù)關于θ的梯度。然后不斷重復計算公式(1),直到梯度接近于0。
此方法是最初的梯度下降算法,通過此方法,可以使計算機通過迭代計算,求解任意具有一階導數(shù)的極值。但也有三類主要問題[1]。第一類問題是計算效率問題,主要表現(xiàn)有兩點:①這種方法每更新一次,就需要在整個數(shù)據(jù)集上計算一次梯度。當數(shù)據(jù)量非常大的時候,整個算法的就會非常慢且特別吃內存。②每次更新的步長是一個超參數(shù)。當更新步長太大時,算法效果出現(xiàn)抖動,通常無法收斂到最佳效果。當更新步長太小時,算法收斂速度較慢且容易陷入局部最小值。第二類問題是梯度計算問題:主要表現(xiàn)在神經網絡訓練過程中。由于神經網絡特征較多導致目標函數(shù)有時是一個非凸的函數(shù),此時很難避免參數(shù)被困在極小值附近。這類情況常常導致梯度接近于零,所以普通梯度下降法很難從中逃脫。因此,無法收斂到全局最小值。第三類問題是:梯度下降法中的學習率η是一個固定值,常常很難確定η的取值。具體表現(xiàn)為:①如圖1 所示:過小的學習率導致目標函數(shù)收斂緩慢,而過大的學習率會導致目標函數(shù)在其極小值附近劇烈震蕩。②由于所有參數(shù)都使用相同的學習率,導致數(shù)據(jù)中出現(xiàn)頻率低的特征常常無法達到最優(yōu)效果。針對梯度下降算法這些問題,圖1 總結了相應的三類改進策略及相應算法。
圖1 不同學習率收斂震蕩對比圖
在樣本量極大的時候,對大量相似樣本計算其梯度是沒必要的。因此,這部分主要通過調整每次迭代計算的樣本量提高計算效率。
(1)批梯度下降法
此算法先將所有樣本隨機排序,然后將樣本分組,每次計算只對其中一組數(shù)據(jù)做優(yōu)化計算,當所有樣本都計算一遍后再重新分組重新計算。若樣本被分成N組,則此方法在所有樣本都計算完一遍后就進行了N次梯度優(yōu)化,而原始梯度下降法只能優(yōu)化一次。因此提高了算法效率[2]。
(2)隨機梯度下降法
隨機梯度下降法簡稱SGD(Stochastic Gradient Descent)[3]。SGD 在批梯度下降法的思想上更進一步,它將批梯度下降法的每批數(shù)據(jù)量降到1,即每次梯度更新只用一個樣本。如圖2 所示。這種方法加快了收斂速度但同時由于頻繁更新參數(shù)導致目標函數(shù)在劇烈震蕩中逐步下降。
圖2 SGC收斂波動(來源:Wikipedia)
綜上所述,批梯度下降法和隨機梯度下降算法具有相同的優(yōu)化思路,即都取訓練樣本的一個子集。因此,算法的好壞主要取決于子集的大小。通常,根據(jù)不同的應用場景,小批量的大小取50 到256 較為合適。
由于本文主要討論深度學習中常用的優(yōu)化的梯度類算法,所以在此不再討論那些不適用于高維數(shù)據(jù)的方法,如類似于牛頓法的二階算法。
(1)動量法
牛頓法[4]將目標函數(shù)比作高低不平的地面或山坡,把優(yōu)化過程比作小球滾下坡的過程。這種方法主要應對那些類似于峽谷形狀的函數(shù),可以避免其在峽谷兩邊震蕩而下降緩慢。動量法是在更新向量(梯度向量)之前增加前一次的更新向量,從而在他們相同的方向上累加速度,在不同的方向上減小速度,以此減小震蕩,加快收斂速度。
其中:vt表示第t 次的下降動量,vt-1表示t-1 次的下降動量。γ為下降動量的衰減值,通常取0.9。θ 表示要更新的向量。?θJ(θt)表示第t 次更新時的梯度值,η 表示學習速率。
這種方法能夠明顯加速SGD 的學習速率并且可以減小SGD 無謂的震蕩,但在下降到極值點附近的時候由于速度過快而無法及時停止。
(2)NAG 法
NAG[6]的全稱是Nesterov Accelerated Gradient。此方法主要為了解決動量法無法及時停止的問題。NAG認為在t 次更新中會用到動量項γvt-1,所以θ-Vt-1就是參數(shù)向量下一個位置。所以,我們與其在當前位置計算梯度還不如在當前位置的下一個位置計算梯度。這樣既沒有增加計算量,又可以讓參數(shù)及時的根據(jù)梯度修正下降誤差。
公式中各符號含義與上文相同。從公式可以看出,NAG 法與動量法的區(qū)別只在于計算梯度的位置不同。動量項γ的參考值也是在0.9 附近取值效果最好。
圖3 SGD、動量法和NAG下降對比
圖3 展示了不同梯度下降法在sixhump 函數(shù)中的收斂過程。左圖為SGD 收斂路徑圖,中圖為動量法收斂路徑圖,右圖為NAG 收斂路徑圖。圖中的每個藍點代表每次梯度計算后下降的位置。所以,點越稠密表示下降速度越慢;點越稀疏表示下降速度越快。通過對比可看出,SGD 算法每次下降的點與相鄰點距離是固定的且非常近,NAG 和動量法都有一段加速區(qū)域和震蕩區(qū)域,但NAG 的震蕩明顯比動量法弱。
學習率對于梯度類優(yōu)化算法非常重要。尤其在稀疏性很強的數(shù)據(jù)集中,一個好的學習率調整算法不但能夠使目標函數(shù)更快地找到極小值,而且可以優(yōu)化出更精確的目標函數(shù)。
(1)AdaGrad 方法
AdaGrad[7]能夠根據(jù)參數(shù)的重要性調整學習率。它能夠根據(jù)參數(shù)更新的平凡程度自動調整學習率。所以它非常適合稀疏性很強的數(shù)據(jù)集。Dean 等人[8]使用AdaGrad 實現(xiàn)了YouTube 中貓的識別算法。Pennington 等人[9]使用AdaGrad 算法對GloVe 詞嵌入網絡進行訓練并最終使不常出現(xiàn)的詞語得到了和經常出現(xiàn)的詞語近似的學習率。這種方法在每次更新參數(shù)的同時更新學習率。更新方法如公式(6)。
公式(6)主要增加Gt,Gt表示前t 次更名梯度的平方和。通過增加這一項,參數(shù)隨著更新頻率和更新幅度的大小逐漸變小而不影響稀疏屬性的更新。除此之外,AdaGrad 的另外一個優(yōu)點是不需要手動調整學習率,一般直接使用就可以。同時,也注意到公式的分母部分只增不減,使整個學習率隨之越來越小直到無限小。
(2)AdaDelta 方法
AdaDelta[10]方法是AdaGrad 方法的改進,主要解決了AdaGrad 方法單調遞減學習率的問題。AdaDelta 方法采用指數(shù)衰減移動平均的方式來取代AdaGrad 里面將以往全部梯度值都平等納入平方和的做法。它將上面Gt 的計算方法替換成如下方法:
通過對比可以發(fā)現(xiàn),只要將公式中E[g2]t替換成Gt,AdaDelta 方法就會回退到AdaGrad 方法。這里的γ建議取0.9,而默認的學習率為0.001。
(3)Adam 方法
Adam(Adaptive moment Estimation)[11]是另一種針對調整學習率的方法。這種方法不但像AdaDelta 一樣通過收集歷史梯度值逐步衰減學習率,還能像動量法一樣記錄梯度本身的指數(shù)衰減值。
其中,mt和vt分別是梯度的一階和二階矩估計。
Adam 的更新規(guī)則是:
Adam 作者提出β1、β2和ε 的取值分別是0.9、0.999 和10-8。它的實驗結果表明Adam 的實際收斂效果更好且對學習率的調整表現(xiàn)更好。
前一節(jié)提到了三類算法,這些算法在各自不同的角度表現(xiàn)出優(yōu)秀的效果。在模型訓練過程中,影響其訓練效果的主要是一些局部極值點。在高維模型中,這種局部極值點更多,各個特征值就可能會有更復雜的分布。一種最難處理的分布是所有維度都處于極值點,但一些處于極大值,另一些處于極小值,這種點被稱作鞍點。那么在實際模型訓練任務中,各個算法的在鞍點[12]附近的表現(xiàn)如何?
圖4 梯度類下降算法在按點附近的表現(xiàn)
從圖4 可以發(fā)現(xiàn)AdaDelta 首先擺脫鞍點并快速下降,Rmsprop 次之。而SGD 可緩慢擺脫鞍點,動量法處于RmsProp 和SGD 之間。究其原因,主要是AdaDelta方法不會出現(xiàn)擾動,能最先逃出鞍點,SGD 方法在原始梯度下降法基礎上增加了隨機性,所以可以逃出鞍點,動量法由于保留了之前的優(yōu)化速率和方向,所以在最初出現(xiàn)震蕩區(qū)域而導致優(yōu)化速度比較慢,但逃離鞍點后優(yōu)化速度越來越快。
如果輸入的數(shù)據(jù)有稀疏性,動態(tài)調整學習率的算法會比較好,因為使用者不需要調整學習率,直接使用默認學習率就可以達到較好效果。但也有一些研究成果僅僅使用原始梯度下降算法就可以找到極小值。如果使用者關心算法的收斂速度或者訓練的是一個參數(shù)較多或隱層較深的網絡,就需要選取一個動態(tài)調整學習率的算法,因為他們有可能會卡在鞍點附近[13]。
以上是對幾種梯度下降優(yōu)化算法的直觀展示與分析。為了驗證其在深度學習算法中的表現(xiàn),本文將在minst 手寫數(shù)字識別數(shù)據(jù)集上構建一個三層CNN 網絡[14]。網絡結構如圖5 所示。第一個隱層有512 個神經元,激活函數(shù)使用ReLU,Dropout 比例為0.2。第二個隱層有512 個神經元,激活函數(shù)為ReLU,Dropout 比例為0.2。輸出層有10 個神經元,激活函數(shù)使用Soft-Max,輸出結果使用onehot 方式表示。
圖5 神經網絡結構
分別使用SGD,動量法、NAG、AdaGrad、AdaDelta、Adam 六種優(yōu)化方法訓練網絡,訓練效果如圖6 所示。
圖6 手寫數(shù)字識別準確率折線圖
從圖6 中可以看出:SGD、動量法和NAG 的收斂折線基本重合,說明SGD、動量法和NAG 三種方法的收斂速度基本相同;Adam、AdaGrad 和AdaDelta 的收斂折線基本重合,說明Adam、AdaGrad 和AdaDelta 三種方法的收斂速度基本相同。從收斂速度看,Adam 類方法的收斂速度更快;從最終的目標函數(shù)準確度看,Adam 類方法的收斂效果更好。
圖7 CIRAR-10數(shù)據(jù)集誤判折線圖(來源:文獻[20])
實驗結果表明,調整學習率的Adam 類算法普遍比動量法類的方法收斂速度快且收斂效果更好。究其原因,主要是因為深度學習類算法省略了特征提取步驟,將所有特征都作為參數(shù)進行訓練,這是深度學習提高精度的主要原因。但同時,這也使深度學習訓練數(shù)據(jù)變得稀疏。在學習過程中,SGD、動量法和NAG 使用相同的學習率導致稀疏特征無法收斂。Adam 類方法在最初使用較大的學習率,這就使得稀疏特征能夠在有限的梯度計算過程中獲得更好的收斂效果。也正是由于Adam 類方法最初的大學習率,使得Adam 類方法能夠使目標函數(shù)在訓練之初就能獲得較高的準確率。
Adam 類方法與動量類方法相比,即可以擺脫鞍點的束縛又具有較快的收斂速度,那么Adam 類方法是否適用于所有深度學習場景?顯然不是。SGD 雖然收斂慢且對稀疏數(shù)據(jù)的收斂效果沒有Adam 好,但SGD方法的泛化能力強,如果使用得當,可以訓練出更低錯誤率的目標函數(shù)。文獻[20]在CIRAR-10[21]數(shù)據(jù)集上比較了SGD 和Adam 方法兩種方法的訓練效果,訓練效果如圖7。圖7 的橫坐標表示迭代次數(shù),縱坐標表示目標函數(shù)的誤判率。從圖7 可以看出,雖然Adam 類方法在訓練之初的收斂速度較快,且準確率率高于SGD方法,但在第150 次訓練后,SGD 的誤判率低于Adam方法。這個實驗說明,SGD 方法的泛化能力強于Adam方法。
本文詳細介紹了不同類型的梯度下降算法,并比較了它們在不同數(shù)據(jù)分布的情況下的收斂速度,同時也比較了它們在稀疏數(shù)據(jù)中的收斂速度和最終效果。通過比較,我們發(fā)現(xiàn):①對于稀疏數(shù)據(jù),自適應學習率的算法表現(xiàn)基本相同且優(yōu)于其他算法,因此,盡量使用學習率可自適應的優(yōu)化算法。②如果在意更快的收斂速度,并且訓練的算法比較復雜的時候,自適應學習率算法要優(yōu)于其他算法。③AdaDelta、RMSprop 和Adam是比較接近的算法,在收斂速度和收斂結果方面表現(xiàn)基本無差別。④原始無法跳出鞍點,SGD 方法由于增加了隨機性而能夠逃出鞍點但收斂速度很慢。⑤SGD方法具有更好的泛化能力,通過優(yōu)化SGD 方法,并在訓練過程中手動調整不同的學習率,在一些非稀疏的數(shù)據(jù)集上能夠得到更好的收斂效果。
除本文著重介紹的SDG 優(yōu)化策略及其一些變體外,還可以從被訓練的數(shù)據(jù)以及選擇模型特點的角度考慮,進一步提高SGD 的性能和目標函數(shù)的準確度。例如,一些研究者[22-23]為了使學習過程更加無偏,可以在在每次迭代過程中打亂數(shù)據(jù)或對數(shù)據(jù)做有意義的排序;還有一些研究者[24]為了保證學習率在每次迭代過程之前先對數(shù)據(jù)做0 均值1 方差的標準化等操作;又或者根據(jù)梯度類算法的特點,采用相結合的策略或混合策略,對訓練集按照訓練難度進行遞增排序,在不同的時期使用不同的優(yōu)化算法。