優化算法–Adagrad
自适應學習率
随機梯度下降算法,目标函數自變量的每一個元素在相同時間步都使用同一個學習率來自我疊代。舉個例子,假設目标函數為 f f f,自變量為一個二維向量 [ x 1 , x 2 ] ⊤ [x_1, x_2]^\top [x1,x2]⊤,該向量中每一個元素在疊代時都使用相同的學習率。例如,在學習率為 η \eta η的梯度下降中,元素 x 1 x_1 x1和 x 2 x_2 x2都使用相同的學習率 η \eta η來自我疊代:
x 1 ← x 1 − η ∂ f ∂ x 1 , x 2 ← x 2 − η ∂ f ∂ x 2 . x_1 \leftarrow x_1 - \eta \frac{\partial{f}}{\partial{x_1}}, \quad x_2 \leftarrow x_2 - \eta \frac{\partial{f}}{\partial{x_2}}. x1←x1−η∂x1∂f,x2←x2−η∂x2∂f.
在上一篇 “優化算法momentum” 裡我們看到當 x 1 x_1 x1和 x 2 x_2 x2的梯度值有較大差别時,需要選擇足夠小的學習率使得自變量在梯度值較大的次元上不發散。但這樣會導緻自變量在梯度值較小的次元上疊代過慢。動量法依賴指數權重移動平均使得自變量的更新方向更加一緻,進而降低發散的可能。在工程上,我們也有比較粗糙的手段:随着疊代次數增多,學習率遞減,比如(0,1000)次–>$\eta= 0.1 , ( 1000 , 2000 ) 次 − − > 0.1,(1000,2000)次--> 0.1,(1000,2000)次−−>\eta= 0.01 , ( 2000 , 5000 ) 次 − − > 0.01,(2000,5000)次--> 0.01,(2000,5000)次−−>\eta=$0.001,也就是剛開始步子邁大一點,到了比較接近底部的時候步子邁小一點,年輕的時候闖一闖,年紀大了就求穩了。AdaGrad算法,它根據自變量在每個次元的梯度值的大小來調整各個次元上的學習率,進而避免統一的學習率難以适應所有次元的問題。
AdaGrad
AdaGrad算法會使用一個小批量随機梯度 g t \boldsymbol{g}_t gt按元素平方的累加變量 s t \boldsymbol{s}_t st。在時間步0,AdaGrad将 s 0 \boldsymbol{s}_0 s0中每個元素初始化為0。在時間步 t t t,首先将小批量随機梯度 g t \boldsymbol{g}_t gt按元素平方後累加到變量 s t \boldsymbol{s}_t st:
s t ← s t − 1 + g t ⊙ g t , \boldsymbol{s}_t \leftarrow \boldsymbol{s}_{t-1} + \boldsymbol{g}_t \odot \boldsymbol{g}_t, st←st−1+gt⊙gt,
其中 ⊙ \odot ⊙是按元素相乘。接着,我們将目标函數自變量中每個元素的學習率通過按元素運算重新調整一下:
x t ← x t − 1 − η s t + ϵ ⊙ g t , \boldsymbol{x}_t \leftarrow \boldsymbol{x}_{t-1} - \frac{\eta}{\sqrt{\boldsymbol{s}_t + \epsilon}} \odot \boldsymbol{g}_t, xt←xt−1−st+ϵ
η⊙gt,
其中 η \eta η是學習率, ϵ \epsilon ϵ是為了維持數值穩定性而添加的常數,如 1 0 − 6 10^{-6} 10−6。這裡開方、除法和乘法的運算都是按元素運算的。這些按元素運算使得目标函數自變量中每個元素都分别擁有自己的學習率。
AdaGrad的特點
需要強調的是,小批量随機梯度按元素平方的累加變量 s t \boldsymbol{s}_t st出現在學習率的分母項中。是以,如果目标函數有關自變量中某個元素的偏導數一直都較大,那麼該元素的學習率将下降較快;反之,如果目标函數有關自變量中某個元素的偏導數一直都較小,那麼該元素的學習率将下降較慢。然而 ,由于 s t \boldsymbol{s}_t st一直在累加按元素平方的梯度,自變量中每個元素的學習率在疊代過程中一直在降低(或不變)。是以,當學習率在疊代早期降得較快且目前解依然不佳時,AdaGrad算法在疊代後期由于學習率過小,可能較難找到一個有用的解。
優化算法–RMSProp
思想:AdaGrad+momentum
AdaGrad算法因為調整學習率時分母上的變量 s t \boldsymbol{s}_t st一直在累加按元素平方的小批量随機梯度,是以目标函數自變量每個元素的學習率在疊代過程中一直在降低(或不變)。為了解決這一問題,RMSProp算法對AdaGrad算法做了一些改進,并且結合了momentum中指數權重移動平均的思想。
RMSProp
不同于AdaGrad算法裡狀态變量 s t \boldsymbol{s}_t st是截至時間步 t t t所有小批量随機梯度 g t \boldsymbol{g}_t gt按元素平方和,RMSProp算法将這些梯度按元素平方做指數權重移動平均。給定超參數 0 ≤ γ < 1 0 \leq \gamma < 1 0≤γ<1,RMSProp算法在時間步 t > 0 t>0 t>0計算
s t ← γ s t − 1 + ( 1 − γ ) g t ⊙ g t . \boldsymbol{s}_t \leftarrow \gamma \boldsymbol{s}_{t-1} + (1 - \gamma) \boldsymbol{g}_t \odot \boldsymbol{g}_t. st←γst−1+(1−γ)gt⊙gt.
和AdaGrad算法一樣,RMSProp算法将目标函數自變量中每個元素的學習率通過按元素運算重新調整,然後更新自變量
x t ← x t − 1 − η s t + ϵ ⊙ g t , \boldsymbol{x}_t \leftarrow \boldsymbol{x}_{t-1} - \frac{\eta}{\sqrt{\boldsymbol{s}_t + \epsilon}} \odot \boldsymbol{g}_t, xt←xt−1−st+ϵ
η⊙gt,
其中 η \eta η是學習率, ϵ \epsilon ϵ是為了維持數值穩定性而添加的常數,如 1 0 − 6 10^{-6} 10−6。因為RMSProp算法的狀态變量 s t \boldsymbol{s}_t st是對平方項 g t ⊙ g t \boldsymbol{g}_t \odot \boldsymbol{g}_t gt⊙gt的指數權重移動平均,是以可以看作是最近 1 / ( 1 − γ ) 1/(1-\gamma) 1/(1−γ)個時間步的小批量随機梯度平方項的權重平均。如此一來,自變量每個元素的學習率在疊代過程中就不再一直降低(或不變)。
AdaDelta算法
我們經常講如果你隻能調節一個超參數,那麼你就調節學習率,調一個好的學習率是比較困難的,學習率太大會在底部振蕩(步子要一步一步的邁,步子邁大了容易扯着dan),學習率太小,可能無法達到損失函數的極小值。既然學習率調節這麼麻煩(就是個禍害),那麼就有人想要為民除害,AdaDelta算法就是這樣的”俠客“。
AdaDelta算法也像RMSProp算法一樣,使用了小批量随機梯度 g t \boldsymbol{g}_t gt按元素平方的指數權重移動平均變量 s t \boldsymbol{s}_t st。在時間步0,它的所有元素被初始化為0。給定超參數 0 ≤ ρ < 1 0 \leq \rho < 1 0≤ρ<1(對應RMSProp算法中的 γ \gamma γ),在時間步 t > 0 t>0 t>0,同RMSProp算法一樣計算
s t ← ρ s t − 1 + ( 1 − ρ ) g t ⊙ g t . \boldsymbol{s}_t \leftarrow \rho \boldsymbol{s}_{t-1} + (1 - \rho) \boldsymbol{g}_t \odot \boldsymbol{g}_t. st←ρst−1+(1−ρ)gt⊙gt.
與RMSProp算法不同的是,AdaDelta算法還維護一個額外的狀态變量 Δ x t \Delta\boldsymbol{x}_t Δxt,其元素同樣在時間步0時被初始化為0。我們使用 Δ x t − 1 \Delta\boldsymbol{x}_{t-1} Δxt−1來計算自變量的變化量:
g t ′ ← Δ x t − 1 + ϵ s t + ϵ ⊙ g t , \boldsymbol{g}_t' \leftarrow \sqrt{\frac{\Delta\boldsymbol{x}_{t-1} + \epsilon}{\boldsymbol{s}_t + \epsilon}} \odot \boldsymbol{g}_t, gt′←st+ϵΔxt−1+ϵ
⊙gt,
其中 ϵ \epsilon ϵ是為了維持數值穩定性而添加的常數,如 1 0 − 5 10^{-5} 10−5。接着更新自變量:
x t ← x t − 1 − g t ′ . \boldsymbol{x}_t \leftarrow \boldsymbol{x}_{t-1} - \boldsymbol{g}'_t. xt←xt−1−gt′.
最後,我們使用 Δ x t \Delta\boldsymbol{x}_t Δxt來記錄自變量變化量 g t ′ \boldsymbol{g}'_t gt′按元素平方的指數權重移動平均:
Δ x t ← ρ Δ x t − 1 + ( 1 − ρ ) g t ′ ⊙ g t ′ . \Delta\boldsymbol{x}_t \leftarrow \rho \Delta\boldsymbol{x}_{t-1} + (1 - \rho) \boldsymbol{g}'_t \odot \boldsymbol{g}'_t. Δxt←ρΔxt−1+(1−ρ)gt′⊙gt′.
可以看到,如不考慮 ϵ \epsilon ϵ的影響,AdaDelta算法跟RMSProp算法的不同之處在于使用 Δ x t − 1 \sqrt{\Delta\boldsymbol{x}_{t-1}} Δxt−1
來替代學習率 η \eta η。
Adam算法
RMSProp + momentum
Adam算法在RMSProp算法基礎上對小批量随機梯度也做了指數權重移動平均 。
Adam算法使用了動量變量 v t \boldsymbol{v}_t vt和RMSProp算法中小批量随機梯度按元素平方的指數權重移動平均變量 s t \boldsymbol{s}_t st,并在時間步0将它們中每個元素初始化為0。給定超參數 0 ≤ β 1 < 1 0 \leq \beta_1 < 1 0≤β1<1(算法作者建議設為0.9),時間步 t t t的動量變量 v t \boldsymbol{v}_t vt即小批量随機梯度 g t \boldsymbol{g}_t gt的指數權重移動平均:
v t ← β 1 v t − 1 + ( 1 − β 1 ) g t . \boldsymbol{v}_t \leftarrow \beta_1 \boldsymbol{v}_{t-1} + (1 - \beta_1) \boldsymbol{g}_t. vt←β1vt−1+(1−β1)gt.
和RMSProp算法中一樣,給定超參數 0 ≤ β 2 < 1 0 \leq \beta_2 < 1 0≤β2<1(算法作者建議設為0.999),
将小批量随機梯度按元素平方後的項 g t ⊙ g t \boldsymbol{g}_t \odot \boldsymbol{g}_t gt⊙gt做指數權重移動平均得到 s t \boldsymbol{s}_t st:
s t ← β 2 s t − 1 + ( 1 − β 2 ) g t ⊙ g t . \boldsymbol{s}_t \leftarrow \beta_2 \boldsymbol{s}_{t-1} + (1 - \beta_2) \boldsymbol{g}_t \odot \boldsymbol{g}_t. st←β2st−1+(1−β2)gt⊙gt.
由于我們将 v 0 \boldsymbol{v}_0 v0和 s 0 \boldsymbol{s}_0 s0中的元素都初始化為0,在時間步 t t t我們得到 v t = ( 1 − β 1 ) ∑ i = 1 t β 1 t − i g i \boldsymbol{v}_t = (1-\beta_1) \sum_{i=1}^t \beta_1^{t-i} \boldsymbol{g}_i vt=(1−β1)∑i=1tβ1t−igi。将過去各時間步小批量随機梯度的權值相加,得到 ( 1 − β 1 ) ∑ i = 1 t β 1 t − i = 1 − β 1 t (1-\beta_1) \sum_{i=1}^t \beta_1^{t-i} = 1 - \beta_1^t (1−β1)∑i=1tβ1t−i=1−β1t。需要注意的是,當 t t t較小時,過去各時間步小批量随機梯度權值之和會較小。例如,當 β 1 = 0.9 \beta_1 = 0.9 β1=0.9時, v 1 = 0.1 g 1 \boldsymbol{v}_1 = 0.1\boldsymbol{g}_1 v1=0.1g1。為了消除這樣的影響,對于任意時間步 t t t,我們可以将 v t \boldsymbol{v}_t vt再除以 1 − β 1 t 1 - \beta_1^t 1−β1t,進而使過去各時間步小批量随機梯度權值之和為1。這也叫作偏差修正。在Adam算法中,我們對變量 v t \boldsymbol{v}_t vt和 s t \boldsymbol{s}_t st均作偏差修正:
v ^ t ← v t 1 − β 1 t , \hat{\boldsymbol{v}}_t \leftarrow \frac{\boldsymbol{v}_t}{1 - \beta_1^t}, v^t←1−β1tvt,
s ^ t ← s t 1 − β 2 t . \hat{\boldsymbol{s}}_t \leftarrow \frac{\boldsymbol{s}_t}{1 - \beta_2^t}. s^t←1−β2tst.
接下來,Adam算法使用以上偏差修正後的變量 v ^ t \hat{\boldsymbol{v}}_t v^t和 s ^ t \hat{\boldsymbol{s}}_t s^t,将模型參數中每個元素的學習率通過按元素運算重新調整:
g t ′ ← η v ^ t s ^ t + ϵ , \boldsymbol{g}_t' \leftarrow \frac{\eta \hat{\boldsymbol{v}}_t}{\sqrt{\hat{\boldsymbol{s}}_t} + \epsilon}, gt′←s^t
+ϵηv^t,
其中 η \eta η是學習率, ϵ \epsilon ϵ是為了維持數值穩定性而添加的常數,如 1 0 − 8 10^{-8} 10−8。和AdaGrad算法、RMSProp算法以及AdaDelta算法一樣,目标函數自變量中每個元素都分别擁有自己的學習率。最後,使用 g t ′ \boldsymbol{g}_t' gt′疊代自變量:
x t ← x t − 1 − g t ′ . \boldsymbol{x}_t \leftarrow \boldsymbol{x}_{t-1} - \boldsymbol{g}_t'. xt←xt−1−gt′.
總結
- 建議閱讀順序為:SGD–>momentum–>AdaGrad–>RMSProp–>AdaDelta–>Adam,整個優化算法的發展越來越收到學術界和工業界的重視。
- 在人工智能學習中(Y=wX+b)可以大緻分為:通過樣本(X–>Y)建立模型(w,b),這是What,如何獲得一個比較好的模型,這是How。
- 現在what因為這幾年深度學習架構的發展得到了一個不錯的發展,大家的模型架構都趨于同質化,當然這裡面也有很多Track,但是How,也就是優化的發展相對于比較緩慢,最近剛剛有國内的學者剛剛釋出了R-Adam,引起了不小的轟動,還有一些paper在用傳統的控制算法的思路如PID中比例,積分,微分來優化模型,但這塊的突破并不像模型架構從AlexNet,VGG16,GoogleNet,ResNet,Faster RCNN,Yolo,Unet;優化算法的突破比較難,因為需要底層數學的突破,而模型架構更多的是工程創新,更多的是通過算力不斷的嘗試。
看完這個系列你就能看懂這首詩
梯度下降可沉甸,随機降低方差難。
引入動量别彎慢,Adagrad梯方貪。
Adadelta學率換,RMSProp梯方權。
Adam動量RMS伴,優化還需己調參。
注釋
梯方:梯度按元素平方
貪:因貪婪故而不斷累加
學率:學習率