梯度下降與隨機梯度下降


梯度下降法先隨機給出參數的一組值,然后更新參數,使每次更新后的結構都能夠讓損失函數變小,最終達到最小即可。在梯度下降法中,目標函數其實可以看做是參數的函數,因為給出了樣本輸入和輸出值后,目標函數就只剩下參數部分了,這時可以把參數看做是自變量,則目標函數變成參數的函數了。梯度下降每次都是更新每個參數,且每個參數更新的形式是一樣的,即用前一次該參數的值減掉學習率和目標函數對該參數的偏導數(如果只有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分別是樣本數量、樣本維數

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



隨機梯度下降

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

def stocGradAscent0(dataMatrix, classLabels):
    m,n = shape(dataMatrix)
    alpha = 0.01
    weights = ones(n)   #initialize to all ones
    for i in range(m):
        h = sigmoid(sum(dataMatrix[i]*weights))
        error = classLabels[i] - h
        weights = weights + alpha * error * dataMatrix[i]
    return weights

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

def stocGradAscent1(dataMatrix, classLabels, numIter=150):
    m,n = shape(dataMatrix)
    weights = ones(n)   #initialize to all ones
    for j in range(numIter):
        dataIndex = range(m)
        for i in range(m):
            alpha = 4/(1.0+j+i)+0.0001    #apha decreases with iteration, does not 
            randIndex = int(random.uniform(0,len(dataIndex)))#隨機選取樣本
            h = sigmoid(sum(dataMatrix[randIndex]*weights))
            error = classLabels[randIndex] - h
            weights = weights + alpha * error * dataMatrix[randIndex]
            del(dataIndex[randIndex])#刪除所選的樣本
    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 

版權聲明:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM