1. 程式人生 > ><反向傳播(backprop)>梯度下降法gradient descent的發展歷史與各版本

<反向傳播(backprop)>梯度下降法gradient descent的發展歷史與各版本

  梯度下降法作為一種反向傳播演算法最早在上世紀由geoffrey hinton等人提出並被廣泛接受。最早GD由很多研究團隊各自發表,可他們大多無人問津,而hinton做的研究完整表述了GD方法,同時hinton為自己的研究多次走動人際關係使得其論文出現在了當時的《nature》上,從此GD開始得到業界的關注。這為後面各種改進版GD的出現與21世紀深度學習的大爆發奠定了最重要的基礎。

PART1:original版的梯度下降法

  首先已經有了 對weights和bias初始化過的神經網路計算圖,也有一套訓練集。

  接下來,代入x(i)後,y^(i)即表示為weights和bias 的函式,然後根據公式,cost function J(w,b,.......)=1/m * (全部Loss(y^(i),y(i))求和)+正則化項,這時我的cost fuction便已表示為全部weights和bias的函式。接下來對每個weight和bias求偏導,再利用梯度下降法與鏈式法則去優化我的引數(附一個我自己寫的偽碼)

然後補充一下 具體training set 是如何投進去的:
如果我們訓練集總共就幾千個或者說不到幾千個樣本,那直接把它餵給神經網路就行(讓m等於training set總樣本數)。
但往往training set樣本數是幾萬上百萬的,這時一口氣全部喂進去就太累了,我們往往採取分batch的方法投放資料集,即把資料集分成一撮撮(類比分治演算法,類比一大堆草要剁,我把草分成一捆捆放到鍘刀上):
記每堆資料有m個樣本,training set總樣本數為M
    當m=1時,也就是一次GD訓練走一個樣本,有點奢侈哈哈哈,稱為隨機(stochastic)梯度下降法。
此時cost function J(w,b,.......)=LOSS(y^,y)+正則化項
    當m=M時,也就是一次GD訓練走全部樣本,稱為batch梯度下降法。
此時cost function J(w,b,.......)=1/M * (全部Loss(y^(i),y(i))求和)+正則化項

     當m介於兩者之間時,稱為minibatch梯度下降法。

  這三種方法是最基礎的梯度下降法,隨機GD缺點是會失去向量化帶來的加速,導致整體下來速度慢(當然它是單次訓練最快的哈哈哈),而且會跳上來跳下去的,不太喜歡它,在訓練接近尾聲時,它的結果並非完全收斂,而是波動的,這一點可通過動態增大減小learningrate來調節,另外隨機GD可以用作線上學習,這算一個特色吧。batchGD缺點是訓練總樣本大時單次迭代時間太長導致整個訓練過程耗時久,機子卡死,坑爹啊。所以一般我們都用minibatch法來跑GD,這樣可以手動(也有自動調每個batch的m大小的,我就不在這寫了)控制我們的GD。

  可閱讀1986年的經典之作:Learning internal representations by error-propagation, by David Rumelhart,GeoffreyHinton

PART2:進階版GD--momentum動量梯度下降法

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  在正式講它之前,我們先介紹一種表示平均值的數學概念------滑動平均,也叫指數加權移動平均(Exponentially Weighted Moving Average)

  現在有一組資料,需要找一個數來代表這組資料的平均水平,那麼大多數人肯定想都不用想,所有數加起來然後除以數的個數,也可以叫做求期望。但是這種方法在計算機中並不友好。首先它需要一定的儲存空間來儲存這組資料,另外還要進行一次運算來算得平均數,如果資料量很大那麼計算也會略有延時。為了克服這些問題,我們採用了一種新方法來表示一組資料的平均水平,即指數加權移動平均。

  這裡引入了一個新變數v與人設引數β。核心公式為  vt=β * vt-1 + (1-β) * θ t   ,θ t 是當前第t個原始資料,以vt代表前t個數據的平均水平,vt-1 表示前t-1個數據的平均水平,β為更新引數,由人為指定。當β趨於1時v的走勢趨於直線,跟原始資料的相關性弱;當β趨於0時v的走勢趨於原始資料走勢,跟原始資料的相關性強。如果有看過吳恩達cousera深度學習課程的同學肯定見過他舉的氣溫變化例子的折線圖,這裡就不列出來了。 一般v0設定為0。

  這一概念不僅在反向傳播中有應用,RL領域中MC方法和TD方法更新Q(s,a)和V(s)的公式也是以EMA為基礎提出的。可以說EMA在CS中應用廣泛。

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  使用PART1中的梯度下降法,必然會遇到一個問題:迭代的時候老是震盪,不能儘快收斂到最優點(如下圖)。然而通過更改學習率a不能很好的解決這個問題。為了找到更牛逼的反向傳播方法,開始有人把EMA用到GD迭代上,從而誕生了GD的改進版本---動量梯度下降法。

   

  下面是momentumGD的引數更新方法:

  vt  = β * vt-1 + (1-β) * dw

  vt  = β * vt-1 + (1-β) * db

  w = w - a * vt   

  b = b - a * v

  這樣通過引入動量v來預示最優點和當前位置的相對方向,便有效地遏制了之前更新過程中的震動,降低了整體優化耗時。(見下圖)

  溫馨提示:momentum與SGD搭配使用更酸爽哦

 

PART3:momentum的改進版---NAG(Nesterov accelerated gradient)

  這名字聽起來逼格很高有沒有。其實也沒啥厲害的,就是在momentum基礎上改動了一下,但是它確實加速了收斂。

  下面是NAG的迭代公式:

  

  進一步推導,得到:

  

  (其中d相當於momentum的v,θ則是要更新的引數,a是學習率)

  從等價形式看,NAG在momentum基礎上多了一個 β [ g(θi-1) - g(θ i-2 ) ] 。意義已經很明顯了:如果這次梯度比上次梯度變大了,那麼有理由相信它會繼續大下去,如果這次梯度比上次梯度變小了,那麼有理由相信它會繼續小下去。是不是想起來了牛頓法??沒錯,用的都是二階導的思想。通過這一改動無疑成功加速了收斂。

  下面這張圖來自hinton的課程ppt,可以幫助理解,其中藍線是momentum,綠線是NAG。

  從全域性收斂的視角對比momentum和NAG:(上面為momentum,下面為NAG)

 

PART4:Adagrad與Adadelta

  前面兩個演算法是在梯度更新上做了改動,下面要說的Adagrad與Adadelta則是在學習率上做了改動。Adagrad能自適應地為各個引數分配不同學習率,解決了不同引數應該使用不同更新速率的問題。

  下面是Adagrad的更新公式:

  

  其中θ i,t  表示第i個引數第t次迭代時的值,η是人設學習率,Gi,t 是第i個引數到第t次迭代時的梯度累加量,Gi,t =Gi,t-1 + h * hT  (其中h為當前引數的梯度向量)。ε是人為設定的輔助值,用來防止G為0時程式報錯。

  通過用 來代替之前靜態的學習率a,我們達到了隨迭代次數增加學習率減小的效果。Adagrad 在資料分佈稀疏的場景能更好利用稀疏梯度的資訊,相比 SGD能更有效地收斂。而它的缺點也十分明顯,隨著時間的增加,它的分母項越來越大,最終導致學習率收縮到太小無法進行有效更新。

  在Adagra基礎上,google的研究人員做了一些改進從而得到了Adadelta。

  其對引數的更新方法如下:

  下圖是四種方法在mnist資料集上的對比圖:

 

  如果想進一步瞭解adadelta,可在此處檢視原作:ADADELTA: An Adaptive Learning Rate Method

PART5:均方根傳播(RMSprop)

  RMSprop是hinton在他的課程中講述的一種方法,跟上面說的Adadelta基本相似,

  每次迭代中,針對待優化引數θ:

    1、計算其梯度dθ ;

    2、計算S =β * S + (1-β) * dθ

    3、進行優化

  通過使用梯度平方的指數衰減學習率,RMSprop也對不同引數採用了不同更新速率。Hinton本人建議設定β為0.9,設定起始學習率a為0.001。

 

PART6:Adam


  把RMSprop和momentum結合到一起,便得到了強大的‘、目前最常用的Adam優化方法。該方法由OpenAI 的 Diederik Kingma 和多倫多大學的 Jimmy Ba 在2015年提交到ICLR的論文Adam:a method for stochastic optimation 提出,相較於以上其他演算法,該方法還有著很好的稀疏梯度和噪聲問題處理能力。

  演算法實現步驟:

 

Adam 的預設超引數配置:

  Adam的一大優點就是不怎麼需要調參,此處只是對超參作一個簡單說明和推薦設定。

  • a:學習率或步長,它控制了權重的更新比率(如 0.001)。較大的值(如 0.3)在學習率更新前會有更快的初始學習,而較小的值(如 1.0E-5)會令訓練收斂到更好的效能。
  • β1:一階矩估計的指數衰減率(如 0.9)。
  • β2:二階矩估計的指數衰減率(如 0.999)。該超引數在稀疏梯度(如在 NLP 或計算機視覺任務中)中應該設定為接近 1 的數。
  • ε:最不重要但也不可或缺的超引數,其為了防止在實現中除以零(如 10E-8)。

 

在CIFAR10資料集上,Adam和其他演算法的表現:


  

PART7:AdaMAX

  這是Adam的拓展版本。

  在Adam中,單個引數的更新規則是將其梯度與當前和過去梯度的L2範數成反比例縮放。把這裡的L2範數泛化到Lp範數也不是不可,儘管這裡的變體會因為p值的變大而在數值上變得不穩定,但在特例中令p趨於無窮便得到了一個穩定又簡單的演算法。此時時間 t 時的步長和 vt^(1/p) 成反比例變化。

  演算法實現步驟:

  AdaMax 引數更新的量級要比 Adam 更簡單,|∆t| ≤ α。

 =============================================================================================================

 =============================================================================================================

 

最後放一個十分直觀的彙總比較,該影象由Sebastian Ruder製作:

  

兩幅圖片來自Sebastian Ruder—An overview of gradient descent optimization algori