本文算是對經常使用梯度圖降低的算法綜述,從方向導數開始獲得梯度降低的原始算法,接着描述了動量梯度降低算法。 而因爲超參數學習率對梯度降低的重要性,因此梯度算法就有多個自適應梯度降低算法。 主要有如下內容:算法
方向導數指的是函數\(z=f(x,y)\)在某一點\(P\)沿某一方向的變化率,其表示形式爲\[\frac{\partial f}{\partial l}\]其中\(l\)表示變換的方向。網絡
設函數\(z=f(x,y)\)在點\(P(x,y)\)的某一鄰域\(U(p)\)內有定義。自點\(P\)處引射線\(l\),設射線\(l\)和\(X\)軸正向的夾角爲\(\theta\),而且假定射線\(l\)與函數\(z = f(x,y)\)的交點爲\(P'(x+\Delta x,y + \Delta y)\)。則函數在\(P,P'\)的增量爲\(f(x+\Delta x , y + \Delta y) - f(x,y)\),兩點之間的距離爲\(\rho = \sqrt{(\Delta x)^2 + (\Delta y)^2}\),當\(P'\)沿着\(l\)趨近於\(P\)時,若是函數增量和兩點距離的比值的極限存在,則稱這個極限爲函數\(f(x,y)\)在點\(P\)沿方向\(l\)的方向導數,記爲\(\frac{\partial f}{\partial l}\),即
\[ \frac{\partial f}{\partial l} = \lim_{\rho \rightarrow 0} \frac{f(x+\Delta x , y + \Delta y) - f(x,y)}{\rho} \]機器學習
假設,函數\(z=f(x,y)\)在點\(P(x,y)\)可微,則有:
\[ f(x + \Delta x,y + \Delta y) - f(x,y) = \frac{\partial f}{\partial x} \cdot \Delta x + \frac{\partial f}{\partial y}\cdot \Delta y + o(\rho) \]
將上式的左右兩邊同時除以\(\rho\)
\[ \frac{f(x + \Delta x,y + \Delta y) - f(x,y)}{\rho} = \frac{\partial f}{\partial x} \cdot \cos \theta + \frac{\partial f}{\partial y}\cdot \sin \theta + \frac{o(\rho)}{\rho} \]函數
取極限有
\[ \frac{\partial f}{\partial l} = \lim_{\rho \rightarrow 0} \frac{f(x+\Delta x , y + \Delta y) - f(x,y)}{\rho} = f_x \cdot \cos \theta + f_y \cdot \sin \theta \]學習
梯度是和方向導數相關的一個概念。
假設函數\(z=f(x,y)\)在平面區域內\(D\)內具備一階連續偏導數,則對每一點\((x,y) \in D\),均可獲得一個向量,
\[ \frac{\partial f}{\partial x} i + \frac{\partial f}{\partial y} j \]
該向量就稱爲函數\(z=f(x,y)\)在點\((x,y)\)處的梯度,記爲\(grad f(x,y)\),即
\[ \nabla f = grad f(x,y) = \frac{\partial f}{\partial x} i + \frac{\partial f}{\partial y} j \]優化
那麼梯度和方向導數,有什麼樣的關係呢。
設,向量\(e = \cos \theta i + \sin \theta j\)是與\(l\)同向的單位向量,則有方向導數的計算公式可知,
\[ \frac{\partial f}{\partial l} = \frac{\partial f}{\partial x} \cos \theta + \frac{\partial f}{\partial y} \sin \theta = \left [\frac{\partial f}{\partial x},\frac{\partial f}{\partial y} \right ] [\cos \theta,\sin \theta]^T = \nabla f \cdot e = \mid \nabla f \mid \cos <\nabla f,e> \]
$\cos <\nabla f,e> $表示梯度 \(\nabla f\) 與 \(e\)的夾角,當方向向量的方向\(l\)的方向與梯度一致時,方向導數\(\frac{\partial f}{\partial l}\)達到最大值,也就是說函數沿着梯度的方向增加最快。spa
函數在某點的梯度是一個向量,在該點沿着梯度方向的方向導數取得最大值,方向導數的最大值爲梯度的模。
\[ \mid \nabla f \mid = \sqrt{f_x ^2 + f_y^2} \]
梯度的方向由梯度向量相對於\(x\)軸的角度給出,
\[ \alpha(x,y) = arctan(\frac{f_y}{f_x}) \]3d
也就是說,一個函數在某點沿着梯度的方向增加最快,而逆着梯度的方向則減少最快。blog
在複雜函數求最小值的優化問題中,一般利用上面描述的梯度的性質,逆着梯度的方向不斷降低,來找到函數的極小值。
以進行一個線性迴歸的批量梯度降低爲例,描述下梯度降低方法的過程
\[ h_{\theta}(x^i) = \theta_1 x^i + \theta_0 \]get
其目標函數爲:
\[ J(\theta_0,\theta_1) = \frac{1}{2m}\sum_{i=1}^m(h_{\theta}(x^i) - y^i)^2 \]
其中,\(i = 1,2,\cdots,m\)爲第\(i\)個樣本。這裏的目標函數是全部樣本偏差和的均值。
則使用梯度降低進行優化時,有如下步驟
梯度降低中的幾個基本概念:
梯度降低是機器學習的經常使用優化方法,根據每次使用的樣本的數據能夠將梯度降低分爲三種形式:批量梯度降低(Batch Gradient Descent),隨機梯度降低(Stochastic Gradient Descent)以及小批量梯度降低(Mini-batch Gradient Descent)。
以進行一個線性迴歸爲例:
\[ h_{\theta}(x^i) = \theta_1 x^i + \theta_0 \]
其目標函數爲:
\[ J(\theta_0,\theta_1) = \frac{1}{2m}\sum_{i=1}^m(h_{\theta}(x^i) - y^i)^2 \]
其中,\(i = 1,2,\cdots,m\)爲第\(i\)個樣本。這裏的目標函數是全部樣本偏差和的均值。
則目標函數與參數\((\theta_0,\theta_1)\)之間關係爲
在上圖中,使用梯度降低的方法,求得最低位置的\((\theta_0,\theta_1)\)即爲所求。
批量梯度降低是最原始的形式,它指的是每一次迭代時使用說有樣本的數據進行梯度更新.
批量梯度降低算法的優缺點都很明顯:
從迭代次數來講,批量梯度降低迭代次數較少。對於凸偏差函數,批量梯度降低法可以保證收斂到全局最小值,對於非凸函數,則收斂到一個局部最小值。
不一樣於批量梯度降低,隨機梯度降低,每次只用要給樣本進行梯度更新,這樣訓練的速度快上很多。
其目標函數爲
\[ J^{(i)}\left(\theta_{0}, \theta_{1}\right)=\frac{1}{2}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right)^{2} \]
目標函數求導
\[\frac{\Delta J^{(i)}\left(\theta_{0}, \theta_{1}\right)}{\theta_{j}}=\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right) x_{j}^{(i)}\]
梯度更新
\[\theta_{j} :=\theta_{j}-\alpha\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right) x_{j}^{(i)}\]
隨機梯度降低每次只是用一個樣本,其訓練速度快。 可是在更新參數的時候,因爲每次只有一個樣本,並不能表明所有的訓練樣本,在訓練的過程當中SGD會一直的波動,這就使得要收斂某個最小值較爲困難。不過,已經有證實緩慢減少學習率,SGD與批梯度降低法具備相同的收斂行爲,對於非凸優化和凸優化,能夠分別收斂到局部最小值和全局最小值。
在深度學習中,最經常使用的優化方法就是小批量梯度降低。 小批量降低是對批量梯度降低和隨機梯度降低兩種方法的中和,每次隨機的使用batch_size個樣本進行參數更新,也能夠稱爲隨機批量梯度降低。(batch_size是一個超參數)。
一般,小批量數據的大小在50到256之間,也能夠根據不一樣的應用有所變化。在必定範圍內,通常來講batch_Size越大,其肯定的降低方向越準,引發訓練震盪越小。可是,batch_size增大到必定程度後,其肯定的降低方向並不會改變了,因此,過大的batch_size對訓練精度已經幫助不大,只會增長訓練的計算量。
梯度降低的難點:
梯度降低優化中的第一個難點就是上面提到的,學習率的設置問題。學習速率太小時收斂速度慢,而過大時致使訓練震盪,並且可能會發散。
而非凸偏差函數廣泛出如今神經網絡中,在優化這類函數時,另外一個難點是梯度降低的過程當中有可能陷入到局部極小值中。也有研究指出這種困難實際上並非來自局部最小值,而更多的來自鞍點,即那些在一個維度上是遞增的,而在另外一個維度上是遞減的。這些鞍點一般被具備相同偏差的點包圍,由於在任意維度上的梯度都近似爲0,因此SGD很難從這些鞍點中逃開。
鞍點(Saddle point)在微分方程中,沿着某一方向是穩定的,另外一條方向是不穩定的奇點,叫作鞍點。對於擁有兩個以上變量的曲線,它的曲面在鞍點好像一個馬鞍,在某些方向往上曲,在其餘方向往下曲。因爲鞍點周圍的梯度都近似爲0,梯度降低若是到達了鞍點就很難逃出來。下圖是\(z = x^2 - y^2\)圖形,在x軸方向向上曲,在y軸方向向下曲,像馬鞍,鞍點爲\((0,0)\)
另外,在梯度平坦的維度降低的很是慢,而在梯度較大的維度則有容易發生抖動。
理想的梯度降低算法要知足兩點:收斂速度要快;並且能全局收斂。因此就有各類梯度算法的變種。
基於動量的梯度降低是根據指數加權平均來的,首先要了解下指數加權平均。
指數加權平均(exponentially weighted averges),也稱爲指數加權移動平均,是經常使用的一種序列數據的處理方法。設在\(t\)時刻數據的觀測值是\(\theta_t\),在\(t\)時刻的移動平均值爲\(v_t\),則有
\[ v_t = \beta v_{t-1} + (1 - \beta)\theta_t \]
其中,\(\beta v_{t-1}\)是上一時刻的移動平均值,也看着一個歷史的積累量。一般設\(v_0 = 0\),\(\beta\)是一個參數,其值在\((0,1)\)之間。動平均值實際是按比例合併歷史量與當前觀測量,將上述遞推公司展開
\[ \begin{align*} v_0 & = 0\\ v_1 & = \beta v_0 + (1-\beta)\theta_1 \\ v_2 &= \beta v_1 + (1-\beta)\theta_2 = \beta (\beta v_0 + \theta_1) + (1-\beta)\theta_2 \\ \vdots \\ v_t &= \beta v_{t-1} + (1-\beta)\theta_t = \sum_{i=1}^t \beta^{t-i}(1-\beta)\theta_t \end{align*} \]
展開後能夠發現,在計算某時刻的\(v_t\)時,其各個時刻觀測值\(\theta_t\)的權值是呈指數衰減的,離當前時刻\(t\)越近的\(\theta_t\),其權值越大,也就是說距離當前時刻越近的觀測值對求得移動平均值的影響越大,這樣獲得的平均值的會比較平穩。因爲權重指數衰減,因此移動平均數只是計算比較相近時刻數據的加權平均數,通常認爲這個時刻的範圍爲\(\frac{1}{1-\beta}\),例如\(\beta=0.9\),能夠認爲是使用距離當前時刻以前10時刻內的\(\theta_t\)的觀測值,再往前因爲權重值國小,影響較小。
下面是倫敦一年中天天的溫度,使用指數加權平均的方法,來表示其溫度的變化趨勢
計算其各個時刻的移動品均值,設\(\beta = 0.9\)
\[ \begin{align*} v_0 &=0 \\ v_1 &= 0.9v_0 + 0.1\theta_1 \\ v_2 &= 0.9v_1 + 0.1 \theta_2 \\ \vdots \\ v_t & = 0.9 v_{t-1} + 0.1 \theta_t \end{align*} \]
將移動平均值即每日溫度的指數加權平均值的曲線圖
上圖的 \(\beta=0.9\),也就是近10天的加權平均值。設\(\beta =0.98\),也就是近50天的加權均值,能夠獲得以下曲線(綠色)
相比於紅色曲線,綠色曲線更爲平坦,由於使用50天的溫度,因此這個曲線,波動更小,更加平坦,缺點是曲線進一步右移,由於如今平均的溫度值更多,要平均更多的值,指數加權平均公式在溫度變化時,適應地更緩慢一些,因此會出現必定延遲。並且\(\beta = 0.98\)給歷史積累量的權值過多,而給當前量權值僅爲0.02過少。
那若是平均過少的天數呢,好比\(\beta = 0.5\)只使用2天內的溫度
能夠看到黃色曲線波動較大,有可能出現異常值,可是這個曲線可以更快適應溫度變化。
參數\(\beta\)的選擇較爲重要,不能過大或者國小。在本例中,\(\beta = 0.9\)取得的紅色曲線,顯然更能表示溫度變化的趨勢。
動量梯度降低算法是Boris Polyak在1964年提出的,其基於這樣一個物理事實:將一個小球從山頂滾下,其初始速率很慢,但在加速度做用下速率很快增長,並最終因爲阻力的存在達到一個穩定速率。
\[ \begin{align*} m &\leftarrow \gamma \cdot m+\eta \cdot \nabla J(\theta) \\ \theta &\leftarrow \theta-m \end{align*} \]
能夠看到,在更新權值時,不只僅使用當前位置的梯度,還加入了一個累計項:動量,多了也給超參數\(\gamma\)。
動量梯度降低,其實是引入了指數加權平均,在更新參數時不只僅的只考慮當前梯度的值,還要考慮前幾回梯度的值。
\[ \begin{align*} v_t &= \beta v_{t - 1} + (1 - \beta) \nabla J(\theta)_t \\ \theta &= \theta - \alpha v_t \end{align*} \]
將學習速率\(\alpha\)整合到第一個式子中,更簡潔一些
\[ \begin{align*} v_t &= \gamma v_{t - 1} + \eta \nabla J(\theta)_t \\ \theta &= \theta - v_t \end{align*} \]
在進行參數更新時,使用當前的\(v_t\)移動平均值來代替當前的梯度,進行參數更新。所謂的動量,也就是近幾回的梯度加權移動平均。例如,一般有\(\beta = 0.9\),也就是當前時刻最近的10次梯度作加權平均,而後用次平均值更新參數。
以下圖,紅點表明最小值的位置
原始的梯度降低算法,會在縱軸上不斷的擺動,這種波動就就減慢了梯度降低的速度。理想狀況是,在縱軸上但願學習的慢一點,而在橫軸上則要學習的快一點,儘快的達到最小值。 要解決這個問題有兩種思路:
如上圖,在縱軸方向其每次的梯度搖擺不定,引入動量後,每次使用一段時間的梯度的平均值,這樣不一樣方向的梯度就會相互抵消,從而減緩縱軸方向的波動。而在,橫軸方向,因爲每次梯度的方向都指向同一個位置,引入動量後,其平均後的均值仍然指向同一個方向,並不會影響其降低的速度。
動量梯度降低,每一次梯度降低都會累積以前的速度的做用,若是此次的梯度方向與以前相同,則會由於以前的速度繼續加速;若是此次的方向與以前相反,則會因爲以前存在速度的做用不會產生一個急轉彎,而是儘可能把路線向一條直線拉過去,這樣就減緩的波動。
球從山上滾下的時候,盲目地沿着斜率方向,每每並不能使人滿意。咱們但願有一個智能的球,這個球可以知道它將要去哪,以致於在從新遇到斜率上升時可以知道減速。
NAG算法是Yurii Nesterov在1983年提出的對衝量梯度降低算法的改進版本,其速度更快。其變化之處在於計算「超前梯度」更新衝量項。
在動量梯度降低中,使用動量項\(\gamma v_{t-1}\)來更新參數\(\theta\),經過計算\(\theta - \gamma v_{t-1}\)可以大致預測更新後參數所在的位置,也就是參數大體將更新爲多少。經過計算關於參數將來的近似位置的梯度,而不是關於當前的參數的梯度位置
\[ \begin{align*} v_t &= \gamma v_{t -1 } + \eta \nabla J(\theta - \gamma v_{t-1}) \\ \theta &= \theta - v_t \end{align*} \]
以下圖
動量梯度降低,首先計算當前的梯度項,上圖的藍色小向量;而後加上累積的動量項,獲得大藍色向量,在改方向上前進一步。
NAG則首先在以前累積的動量項(棕色向量)前進一步,計算梯度值,而後作一個修正(綠色的向量)。這個具備預見性的更新防止咱們前進得太快,同時加強了算法的響應能力。
直觀想象下這個過程,就像騎一輛自行車向下衝。通常的動量降低,就像騎到某一個地方,而後根據當前的坡度,決定往那個方向拐。而NAG則是首先判斷下前方的坡度,而後根據前方的坡度決定往那個方向拐。也就是預判下一個位置的坡度,對當前降低的方向進行修正,避免走冤枉路。
在基本的梯度優化算法中,有個常見問題是,要優化的變量對於目標函數的依賴是不相同的。有些變量,已經優化到極小值附近,可是有些變量仍然離極小值很遠,位於梯度較大的地方。這時候若是對全部的變量都使用同一個全局的優學習速率就有可能出現問題,學習率過小,則梯度很大的變量就會收斂的很慢;若是梯度很大,已經優化的差很少的變量可能會不穩定。
針對這個問題,Jhon Duchi提出了AdaGrad(Adaptive Gradient),自適應學習速率。AdaGrad的基本思想是對每一個變量使用不一樣的學習率。在最初,學習速率較大,用於快速降低。隨着優化過程的進行,對於已經降低不少的變量,則減少學習率;對於沒有怎麼降低的變量,則仍保持大的學習率。
AdaGrad對每一個變量更新時,利用該變量歷史積累的梯度來修正其學習速率。這樣,已經降低的不少的變量則會有小的學習率,而降低較少的變量則仍然保持較大的學習率。基於這個更新規則,其針對變量\(\theta_i\)的更新
\[ \theta_{(t+1,i)} = \theta_{(t,i)} - \frac{\eta}{\sqrt {\sum_{\tau =1}^t \nabla J(\theta_i)_\tau + \epsilon}} \cdot \nabla J(\theta_i)_{t+1} \]
其中,\(\nabla J(\theta_i)_t\)表示t時刻變量\(\theta_i\)的梯度。\(\sum_{\tau =1}^t \nabla J(\theta_i)_\tau\)就表示變量\(\theta_i\)歷史累積的梯度值 ,用來修正學習率。加上很小的值\(\tau\)是爲了防止0的出現。
AdaGrad雖然可以動態調整變量的學習率,可是其有兩個問題:
後面的幾種自適應算法都是對AdaGrad存在的上述問題進行修改.
RMSprop是Hinton在他的課程上講到的,其算是對Adagrad算法的改進,主要是解決學習速率過快衰減的問題。其思路引入了動量(指數加權移動平均數)的方法,引入了超參數\(\gamma\),在累積梯度的平方項近似衰減:
\[ \begin{align*} s_{(t,i)} &= \gamma s_{(t-1,i)} + (1-\gamma) \nabla J(\theta_i)_t \odot \nabla J(\theta_i)_t \\ \theta_{(t,i)} &= \theta_{(t-1,i)} - \frac{\eta}{\sqrt{s_{(t,i)} + \epsilon}} \odot \nabla J(\theta_i)_t \end{align*} \]
其中,\(i\)表示第\(i\)個變量,\(t\)表示\(t\)時刻更新,\(\gamma\)是超參數一般取\(\gamma=0.9\)。\(s_{(t,i)}\)表示梯度平方的指數加權移動平均數,用來代替AdaGrad中不斷累加的歷史梯度,有助於避免學習速率衰減過快的問題。同時Hinton也建議將全局的學習率\(\eta\)設置爲0.001。
AdaDelta對AdaGrad進行兩方面的改進:
針對學習率衰減過快的問題,其思路和RMSprop同樣,不在累積全部的歷史梯度,而是引入指數加權平均數,只計算必定時間段的梯度。
\[ \begin{align*} s_{(t,i)} &= \gamma s_{(t-1,i)} + (1-\gamma) \nabla J(\theta_i)_t \odot \nabla J(\theta_i)_t \\ \theta_{(t,i)} &= \theta_{(t-1,i)} - \frac{\eta}{\sqrt{s_{(t,i)} + \epsilon}} \odot \nabla J(\theta_i)_t \end{align*} \]
爲了解決學習率超參數的問題,AdaDelta維護了一個額外的狀態變量\(\Delta \theta_t\),根據上面的公式有
\[ \Delta \theta_t = - \frac{\eta}{\sqrt{s_{(t,i)} + \epsilon}} \odot \nabla J(\theta_i)_t \]
上述使用的是梯度平方的指數加權移動平均數,在AdaDelta中做者又定義了:每次參數的更新值\(\Delta \theta\)的平方的指數加權移動平均數
\[ E(\Delta \theta^2)_t = \gamma E(\Delta \theta^2)_{t-1} + (1 - \gamma)\Delta \theta^2_t \]
所以每次更新時,更新值的均方根(Root Mean Squard,RMS)
\[RMS(\Delta \theta)_t = \sqrt{E(\Delta \theta^2)_t +\epsilon }\]
使用\(RMS(\Delta \theta)_{t-1}\)來近似更新\(t\)時刻的學習速率\(\eta\),這樣能夠獲得其更新的規則爲
\[ \theta_{(t,i)} = \theta_{(t-1,i)} - \frac{RMS(\Delta \theta)_{t-1}}{\sqrt{s_{(t,i)} + \epsilon}} \odot \nabla J(\theta_i)_t \]
設初始的\(RMS(\Delta \theta)_0 = 0\),這樣就不用設置默認的學習速率了。 也就是,AdaDelta和RMSprop惟一的區別,就是使用\(RMS(\Delta \theta)_{t-1}\)來代替超參數學習速率。 至於爲何能夠代替,使用牛頓迭代的思想,這裏再也不說明,有興趣能夠參看原始論文ADADELTA: An Adaptive Learning Rate Method 。
Adaptive moment estimation,Adam 是Kingma等在2015年提出的一種新的優化算法,其結合了Momentum和RMSprop算法的思想。相比Momentum算法,其學習速率是自適應的,而相比RMSprop,其增長了衝量項。因此,Adam是二者的結合體。
Adam不僅使用梯度平方的指數加權移動平均數\(v_t\),還使用了梯度的指數加權移動平均數\(m_t\),相似動量。
\[ \begin{aligned} m_{t} &=\beta_{1} m_{t-1}+\left(1-\beta_{1}\right) g_{t} \\ v_{t} &=\beta_{2} v_{t-1}+\left(1-\beta_{2}\right) g_{t}^{2} \end{aligned} \]
能夠看到前兩項和Momentum和RMSprop是很是一致的, 因爲和的初始值通常設置爲0,在訓練初期其可能較小,須要對其進行放大
\[ \begin{aligned} \hat{m}_{t}&=\frac{m_{t}}{1-\beta_{1}^{t}}\\ \hat{v}_{t}&=\frac{v_{t}}{1-\beta_{2}^{t}} \end{aligned} \]
這樣就獲得了更新的規則
\[ \theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat{v}_{t}}+\epsilon} \hat{m}_{t} \]
做者建議\(\beta_1\)設置爲0.9,\(\beta_2\)設置爲0.999,取\(\epsilon = 10^{-8}\)。
下圖給出各個梯度降低算法的可視化降低過程
本文綜述了一些常見的梯度降低方法,主要是自適應梯度降低。 因爲超參數學習速率的難以設定,自適應梯度降低有很好的實用價值。除了使用自適應梯度降低算法外,也能夠手動的設定學習速率的自適應過程,例如學習速率的多項式衰減等。