機器學習--神經網絡算法系列--梯度下降與隨機梯度下降算法

原文:http://www.cnblogs.com/walccott/p/4957098.html

梯度下降與隨機梯度下降

梯度下降法先隨機給出參數的一組值,然後更新參數,使每次更新後的結構都能夠讓損失函數變小,最終達到最小即可。在梯度下降法中,目標函數其實可以看做是參數的函數,因爲給出了樣本輸入和輸出值後,目標函數就只剩下參數部分了,這時可以把參數看做是自變量,則目標函數變成參數的函數了。梯度下降每次都是更新每個參數,且每個參數更新的形式是一樣的,即用前一次該參數的值減掉學習率和目標函數對該參數的偏導數(如果只有1個參數的話,就是導數),爲什麼要這樣做呢?通過取不同點處的參數可以看出,這樣做恰好可以使原來的目標函數值變低,因此符合我們的要求(即求函數的最小值)。即使當學習速率固定(但不能太大),梯度下降法也是可以收斂到一個局部最小點的,因爲梯度值會越來越小,它和固定的學習率相乘後的積也會越來越小。在線性迴歸問題中我們就可以用梯度下降法來求迴歸方程中的參數。有時候該方法也稱爲批量梯度下降法,這裏的批量指的是每一時候參數的更新使用到了所有的訓練樣本。

首先我們來定義輸出誤差,即對於任意一組權值向量,那它得到的輸出和我們預想的輸出之間的誤差值。定義誤差的方法很多,不同的誤差計算方法可以得到不同的權值更新法則,這裏我們先用這樣的定義:


上面公式中D代表了所有的輸入實例,或者說是樣本,d代表了一個樣本實例,od表示感知器的輸出,td代表我們預想的輸出。

這樣,我們的目標就明確了,就是想找到一組權值讓這個誤差的值最小,顯然我們用誤差對權值求導將是一個很好的選擇,導數的意義是提供了一個方向,沿着這個方向改變權值,將會讓總的誤差變大,更形象的叫它爲梯度。




既然梯度確定了E最陡峭的上升的方向,那麼梯度下降的訓練法則是:


梯度上升和梯度下降其實是一個思想,上式中權值更新的+號改爲-號也就是梯度上升了。梯度上升用來求函數的最大值,梯度下降求最小值。


這樣每次移動的方向確定了,但每次移動的距離卻不知道。這個可以由步長(也稱學習率)來確定,記爲α。這樣權值調整可表示爲:


關於學習率

下降的步伐大小非常重要,因爲如果太小,則找到函數最小值的速度就很慢,如果太大,則可能會出現震盪。

如果學習速率過大,這每次迭代就有可能出現超調的現象,會在極值點兩側不斷髮散,最終損失函數的值是越變越大,而不是越來越小。在損失函數值——迭代次數的曲線圖中,可以看到,該曲線是向上遞增的。當然了,當學習速率過大時,還可能出現該曲線不斷震盪的情形。如果學習速率太小,這該曲線下降得很慢,甚至在很多次迭代處曲線值保持不變。那到底該選什麼值呢?這個一般是根據經驗來選取的,比如從…0.0001,0.001,.0.01,0.1,1.0…這些參數中選,看那個參數使得損失值和迭代次數之間的函數曲線下降速度最快。有定步長和可變步長兩種策略。



Feature Scaling

此種方法應用於梯度下降,爲了加快梯度下降的執行速度;由於梯度下降法是按照梯度方向來收斂到極值的,如果輸入樣本各個維數的尺寸不同(即範圍不同),則這些參數的構成的等高線不同的方向胖瘦不同,這樣會導致參數的極值收斂速度極慢。因此在進行梯度下降法求參數前,需要先進行feature scaling這一項,一般都是把樣本中的各維變成0均值,即先減掉該維的均值,然後除以該變量的range。
思想:將各個feature的值標準化,使得取值範圍大致都在-1<=x<=1之間;

常用的方法是Mean Normalization,即

多變量



隨機梯度下降

普通的梯度下降算法在更新迴歸係數時要遍歷整個數據集,是一種批處理方法,這樣訓練數據特別忙龐大時,可能出現如下問題:

1)收斂過程可能非常慢;

2)如果誤差曲面上有多個局極小值,那麼不能保證這個過程會找到全局最小值。

爲了解決上面的問題,實際中我們應用的是梯度下降的一種變體被稱爲隨機梯度下降。


上面公式中的誤差是針對於所有訓練樣本而得到的,而隨機梯度下降的思想是根據每個單獨的訓練樣本來更新權值,這樣我們上面的梯度公式就變成了:


經過推導後,我們就可以得到最終的權值更新的公式:


有了上面權重的更新公式後,我們就可以通過輸入大量的實例樣本,來根據我們預期的結果不斷地調整權值,從而最終得到一組權值使得我們的SIGMOID能夠對一個新的樣本輸入得到正確的或無限接近的結果。


這裏做一個對比

設代價函數爲



批量梯度下降


參數更新爲:

         

i是樣本編號下標,j是樣本維數下標,m爲樣例數目,n爲特徵數目。所以更新一個θj需要遍歷整個樣本集




隨機梯度下降

參數更新爲:

        

i是樣本編號下標,j是樣本維數下標,m爲樣例數目,n爲特徵數目。所以更新一個θj只需要一個樣本就可以。



Batch Gradient Descent: You need to run over every training example before doing an update, which means that if you have a large dataset, you might spend much time on getting something that works. 

Stochastic gradient descent, on the other hand, does updates every time it finds a training example, however, since it only uses one update, it may never converge, although you can still be pretty close to the minimum.  

隨機梯度下降的樣本學習順序可以這樣來:

第一次打亂樣本集D原來的順序,得到D1,然後按順序在D1上一個一個學習,所有樣本學習完之後,再打亂D的順序,得到D2,然後按順序在D1上一個一個學習。。。


還有一種mini-batch gradient descent


普通梯度下降

這裏的error和h是向量,m、n分別是樣本數量、樣本維數

  1. def gradAscent(dataMatIn, classLabels):  
  2.     dataMatrix = mat(dataMatIn)             #convert to NumPy matrix  
  3.     labelMat = mat(classLabels).transpose() #convert to NumPy matrix  
  4.     m,n = shape(dataMatrix)  
  5.     alpha = 0.001  
  6.     maxCycles = 500  
  7.     weights = ones((n,1))  
  8.     for k in range(maxCycles):              #heavy on matrix operations  
  9.         h = sigmoid(dataMatrix*weights)     #matrix mult  
  10.         error = (labelMat - h)              #vector subtraction  
  11.         weights = weights + alpha * dataMatrix.transpose()* error #matrix mult  
  12.     return weights  



隨機梯度下降

這裏的error和h是數值,m、n分別是樣本數量、樣本維數

  1. def stocGradAscent0(dataMatrix, classLabels):  
  2.     m,n = shape(dataMatrix)  
  3.     alpha = 0.01  
  4.     weights = ones(n)   #initialize to all ones  
  5.     for i in range(m):  
  6.         h = sigmoid(sum(dataMatrix[i]*weights))  
  7.         error = classLabels[i] - h  
  8.         weights = weights + alpha * error * dataMatrix[i]  
  9.     return weights  

改進的隨機梯度下降,m、n分別是樣本數量、樣本維數

  1. def stocGradAscent1(dataMatrix, classLabels, numIter=150):  
  2.     m,n = shape(dataMatrix)  
  3.     weights = ones(n)   #initialize to all ones  
  4.     for j in range(numIter):  
  5.         dataIndex = range(m)  
  6.         for i in range(m):  
  7.             alpha = 4/(1.0+j+i)+0.0001    #apha decreases with iteration, does not   
  8.             randIndex = int(random.uniform(0,len(dataIndex)))#隨機選取樣本  
  9.             h = sigmoid(sum(dataMatrix[randIndex]*weights))  
  10.             error = classLabels[randIndex] - h  
  11.             weights = weights + alpha * error * dataMatrix[randIndex]  
  12.             del(dataIndex[randIndex])#刪除所選的樣本  
  13.     return weights  



下面是一些機器學習算法的隨機梯度下降求解模型






與牛頓法的比較

梯度下降法是用來求函數值最小處的參數值,而牛頓法是用來求函數值爲0處的參數值,這兩者的目的初看是感覺有所不同,但是再仔細觀察下牛頓法是求函數值爲0時的情況,如果此時的函數是某個函數A的導數,則牛頓法也算是求函數A的最小值(當然也有可能是最大值)了,因此這兩者方法目的還是具有相同性的。牛頓法的參數求解也可以用矢量的形式表示,表達式中有hession矩陣和一元導函數向量。

首先的不同之處在於梯度法中需要選擇學習速率,而牛頓法不需要選擇任何參數。第二個不同之處在於梯度法需要大量的迭代次數才能找到最小值,而牛頓法只需要少量的次數便可完成。但是梯度法中的每一次迭代的代價要小,其複雜度爲O(n),而牛頓法的每一次迭代的代價要大,爲O(n^3)。因此當特徵的數量n比較小時適合選擇牛頓法,當特徵數n比較大時,最好選梯度法。這裏的大小以n等於1000爲界來計算。


總結

梯度下降與隨機梯度下降是很多機器學習算法求解的基石,可以說是非常重要的。要求弄懂其中的數學原理,隨手推導出公式,並能應用。



http://www.cnblogs.com/murongxixi/p/3467365.html

http://www.cnblogs.com/murongxixi/p/4254788.html

Stochastic Gradient Descent Training for L1-regularized Log-linear Models with Cumulative Penalty 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章