歡迎光臨
每天分享高質量文章

【演演算法】隨機梯度演演算法

小編邀請您,先思考:

1 隨機梯度下降演演算法怎麼理解?

2 隨機梯度下降演演算法有哪些變體?

隨機梯度下降演演算法是深度學習中最常用的演演算法。演演算法就是不停地尋找某個節點中下降幅度最大的那個趨勢進行迭代計算,直到將資料收縮到符合要求的範圍之內。其實也很好理解,以簡單的二元函式為例,如果我們想找到二元函式的極值,一般第一步我們是對該二元函式求導,然後令其為0,找出此時自變數的值,將該自變數代入函式式,即可求出該函式的極值。


那麼在深度學習中,針對實際問題,我們首先需要建立一個模型,然後確定一個標的函式。標的函式通常是網路輸出值和標的之間的誤差,誤差的形式有很多種,例如常見的有平方差、交叉熵等等。


訓練模型的目的是使得標的函式達到極小值。對於一個深度神經網路,它的引數數目比較龐大,因此標的函式通常是一個包含很多參量的非線性函式。對於這個非線性函式,我們採用的是隨機梯度下降演演算法來對引數進行更新。具體步驟如下:


(1)對網路引數進行初始化,一般情況下,權重初始化為均值是0,方差為0.01的高斯分佈隨機值,而偏置統一初始化為0;

(2)將引數代入網路計算前饋輸出值,從而可以根據已有的標的標簽得出標的函式值;

(3)根據標的函式值以及各引數與標的函式所構成的樹結構,運用後向傳播演演算法計算出每個引數的梯度;

(4)設定學習率大小(隨著迭代的步驟增多,學習率通常要逐漸減小,這樣可以有效避免訓練中出現誤差震蕩情況),進行引數更新,最一般的更新方式是 新引數=舊引數-學習率×梯度;

(5)重覆進行第2~4步,直到網路收斂為止。


那麼為什麼叫隨機梯度下降演演算法呢?這裡的隨機是指每次迭代過程中,樣本都要被隨機打亂,這個也很容易理解,打亂是有效減小樣本之間造成的引數更新抵消問題。


隨機梯度下降演演算法通常還有三種不同的應用方式,它們分別是SGD、Batch-SGD、Mini-Batch SGD,下麵分別解釋一下這三種方式的不同。


SGD是最基本的隨機梯度下降,它是指每次引數更新只使用一個樣本,這樣可能導致更新較慢;


Batch-SGD是批隨機梯度下降,它是指每次引數更新使用所有樣本,即把所有樣本都代入計算一遍,然後取它們的引數更新均值,來對引數進行一次性更新,這種更新方式較為粗糙;


Mini-Batch-SGD是小批次隨機梯度下降,它是指每次引數更新使用一小批樣本,這批樣本的數量通常可以採取trial-and-error的方法來確定,這種方法被證明可以有效加快訓練速度。


下麵我來介紹七種常見的隨機梯度下降演演算法。

演演算法一:最基本的隨機梯度下降演演算法


在最基本的隨機梯度下降演演算法中,引數每一步透過減去它的梯度來更新的,通常需要首先打亂訓練樣本,然後將它們劃分為一定數量的mini-batch,如果mini-batch的數量為1,那麼更新方程一般為:


param = param-lr*g(param)


對於該演演算法,需要註意的是我們必須小心調節學習率。因為如果學習率設定太大的話,演演算法會導致標的函式發散;反之如果學習率設定太小的話,演演算法會導致標的函式收斂過慢。將訓練樣本隨機打亂會避免引數更新的抵消,對於大規模的機器學習任務,隨機梯度下降演演算法表現的效能可觀。


演演算法二:動量法


如果引數的初始值和學習率沒有設定恰當,演演算法一在實踐中不能表現出較好的效能。引入動量的演演算法可以幫助網路跳出區域性最優的限制。動量法已經被證明其在訓練深度神經網路中的效能可以媲美之前的Hessian最佳化演演算法。並且,動量法透過在多次迭代中,在標的值持續遞減的方向上累積一個速度向量來加速梯度下降。其更新公式為:

v=mu*v-lr*g(param)

param=param+v


其中mu是動量繫數,其最優值在實踐中可以透過trial-and-error的方法來確定。透過與演演算法一比較可見,動量法僅僅是在權重更新上加了一部分之前的權重更新。當梯度下降保持原來的方向時,這就會增加下降的布幅,從而使得更快地達到最優值;當梯度下降改變方向時,動量法就會使得改變數平滑一點,這個對於網路的初始值設定地不好具有重要的彌補作用。動量法可以使得網路較快地達到最優值而沒有太多震蕩。


演演算法三:Nesterov Accelerated Gradient


NAG演演算法是基於演演算法二的一個變種,既然我們已經有了基於之前的更新mu*v,我們現在不計算在param處的梯度,取而代之的是計算在param+mu*v處的梯度,於是NAG演演算法的更新公式為:

v=mu*v-lr*g(param+mu*v)

param=param+v


由於NAG演演算法在計算梯度時做了小小的改變,在實踐中,這使得NAG在很多情況下表現地要比演演算法二更加穩定。


現在既然已經有了根據標的函式的陡峭程度來更新引數,除此之外,我們還希望可以根據每個引數的特點來制定或大或小的更新步幅,換句話說,更新演演算法需要更精準。


演演算法四:AdaGrad


如果我們希望根據每個引數去調節學習率,那麼AdaGrad恰好解決了這個問題。AdaGrad演演算法根據每個引數過去的更新曆史來決定現在的更新學習率。AdaGrad會記錄之前每一步更新值的平方,透過將這些累加起來來調節每一步學習率的大小。這樣一來,對於那些頻繁更新的引數,學習率會比較小;而對於那些不頻繁更新的引數,學習率會比較大。從這個角度看,AdaGrad很適合比較稀疏的資料。更新公式如下:

G=G+[g(param)]^2

param=param-lr*g(param)/sqrt(G+epsilon)


其中epsilon是一個極小值,為了數值穩定。AdaGrad的一個優點是它可以避免手動去調節學習率,並且在很多時候,只要初始化學習率為0.01即可,然後可以放任不管。但是,一個明顯的缺點是隨著更新步驟的增多,學習率將會一直減小直至接近於0,這樣就會導致網路更新停滯。


演演算法五:RMSProp


RMSProp是為瞭解決演演算法四的學習率消失問題,透過在歷史更新與梯度平方之間設定一定的比例。其更新公式如下:

G=0.9*G+0.1*[g(param)]^2

param=param-lr*g(param)/sqrt(G+epsilon)


RMSProp與接下來要討論的演演算法六幾乎是同時提出的。


演演算法六:AdaDelta


AdaDelta也是為瞭解決AdaGrad的學習率消失問題,與AdaGrad累積歷史更新所不同的是,AdaDelta將過去的更新限制在固定的長度w裡面。並且,由於儲存過去w個更新在計算上效率很低,取而代之的是透過採取指數衰減的形式來保留最近的更新項(平方梯度)。

這裡需要定義一個叫做均方根的概念,均方根的公式如下:

RMS[g]=sqrt(E(g^2)+epsilon)

簡而言之,均方根就是平方均值的平方根。


AdaDelta的更新公式如下:


首先初始化兩個均值,E[g^2]=0,E[d_param^2]=0


E[g^2]=rou*E[g^2]+(1-rou)*g^2

d_param=RMS[d_param]/RMS[g]*g

E[d_param^2]=rou*E[d_param^2]+(1-rou)*d_param^2

param=param-lr*d_param


其中rou為衰減率。


演演算法七:Adam


最近,Adam演演算法被提出來,該演演算法非常有效,並且只需要一階梯度,而且對記憶體要求也很低。Adam同時考慮了梯度以及梯度的平方,因此,Adam同時具有AdaGrad和AdaDelta的優點,能夠很好地適應於稀疏資料或不當的初始化網路。

Adam演演算法的更新公式如下:


初始化一階向量m和二階向量v為0;

設定最優的beta1、beta2的值(論文中有介紹實踐最優預設值);


m=beta1*m+(1-beta1)*g

v=beta2*v+(1-beta2)*g^2

m=m/(1-beta1)

v=v/(1-beta2)

param=param-lr*m/(sqrt(v)+epsilon)


總結


根據我之前所使用的情況來看,Adam演演算法是最快的也是最穩定的。不過,我想具體問題應該有所不同吧,最常用的是演演算法二、演演算法四、演演算法七了。

贊(0)

分享創造快樂