講透機器學習中的梯度下降

在之前的文章當中,我們一起推導了線性迴歸的公式,今天我們繼續來學習上次沒有結束的內容。


上次我們推導完了公式的時候,曾經說過由於有許多的問題,比如最主要的複雜度問題。隨著樣本和特徵數量的增大,通過公式求解的時間會急劇增大,並且如果特徵為空,還會出現公式無法計算的情況。所以和直接公式求解相比,實際當中更傾向於使用另外一種方法來代替,它就是今天這篇文章的主角——梯度下降法


梯度下降法可以說是機器學習和深度學習當中最重要的方法,可以說是沒有之一。尤其是在深度學習當中,幾乎清一色所有的神經網絡都是使用梯度下降法來訓練的。那麼,梯度下降法究竟是一種什麼樣的方法呢,讓我們先從梯度的定義開始。


梯度的定義


我們先來看看維基百科當中的定義:梯度(gradient)是一種關於多元導數的概括。平常的一元(單變量)函數的導數是標量值函數,而多元函數的梯度是向量值函數。多元可微函數 f 在點 P 上的梯度,是以 f 在 P 上的偏導數為分量的

向量


這句話很精煉,但是不一定容易理解,我們一點一點來看。我們之前高中學過導數,但是高中時候計算的求導往往針對的是一元函數。也就是說只有一個變量x,求導的結果是一個具體的值,它是一個標量。而多元函數在某個點求導的結果是一個向量,n元函數的求導的結果分量就是n,導數的每個分量是對應的變量在該點的偏導數。這個偏導數組成的向量,就是這個函數在該點的梯度。


那麼,根據上面的定義,我們可以明確一點,梯度是一個向量,它既有方向,也有大小。



梯度的解釋


維基百科當中還列舉了兩個關於梯度的例子,幫助我們更好的理解。


第一個例子是最經典的山坡模型,假設我們當下站在一個凹凸不平的山坡上,我們想要以最快的速度下山,那麼我們應該該從什麼方向出發呢?很簡單,我們應該計算一下腳下點的梯度,梯度的方向告訴我們下山最快的方向,梯度的大小代表這點的坡度


第二個例子是房間溫度模型,假設我們對房間建立座標系,那麼房間裡的每一個點都可以表示成 (x, y, z) ,該點的溫度是 f(x, y, z)。如果假設房間的溫度不隨時間變化,那麼房間裡每個點的梯度表示溫度變熱最快的方向,梯度的大小代表溫度變化的速率。


通過這兩個例子,應該很容易理解梯度的方向和大小這兩個概念。


舉例


假設f是一個定義在三維空間裡的函數,那麼,f在某一點的梯度,可以寫成:


講透機器學習中的梯度下降


這裡的 i, j, k 都是標準單位向量,表示座標軸 x, y, z的方向。


我們舉個例子:


講透機器學習中的梯度下降


套入剛才的梯度公式,可以得到:


講透機器學習中的梯度下降


如果我們知道 x, y, z的座標,代入其中,就可以知道對應的梯度了。


梯度下降法


理解了梯度的概念之後,再來看梯度下降法其實就是一張圖的事。請看下面這張圖。


講透機器學習中的梯度下降


這裡的黑色的曲線表示我們損失函數的函數曲線,我們要做的,就是找到這個最佳的參數x,使得損失函數的值最小。損失函數的值達到最小,也就說明了模型的效果達到了極限,這也就是我們預期的。


我們一開始的時候顯然是不知道最佳的x是多少的(廢話,知道了還求啥),所以我們假設一開始的時候在一個隨機的位置。就假設是圖中的x1的位置。接著我們對x1求梯度。


我們之前說了,梯度就是該點下降最陡峭的方向,梯度的大小就是它的陡峭程度。我們既然知道了梯度的方向之後,其實就很簡單了,我們要做的就是朝著梯度下降,也就是最陡峭的方向向前走一小步


我們假設,x1 處的梯度是 s1,那麼我們根據 s1 通過迭代的方法優化損失函數。說起來有些空洞,我寫出來就明白了。


講透機器學習中的梯度下降


從上面這個公式可以看出來,這是一個迭代公式。也就是說我們通過不停地迭代,來優化參數。理論上來說,這樣的迭代是沒有窮盡的,我們需要手動終止迭代。什麼時候可以停止呢?我們可以判斷每一次迭代的梯度,當梯度已經小到逼近於0的時候

,就說明模型的訓練已經收斂了,這個時候可以停止訓練了。


這裡的 η 是一個固定的參數,稱為學習率,它表示梯度對於迭代的影響程度。學習率越大,說明梯度對於參數變化的影響越大。如果學習率越小,自然每一次迭代參數的變化也就越小,說明到收斂需要的迭代次數也就越多,也可以單純理解成,收斂需要的時間也就越長。


那麼是不是學習率越大越好呢?顯然也不是的。因為如果學習率過大,很有可能會導致在迭代的過程當中錯過最優點。就好像油門踩猛了,一下子就過頭了,於是可能會出現永遠也無法收斂的情況。比如我們可以參考下面這張圖:


講透機器學習中的梯度下降

從這張圖上可以看到,變量一直在最值附近震盪,永遠也達不成收斂狀態。


如果學習率設置得小一些是不是就沒事了?也不是,如果設置的學習率過小,除了會導致迭代的次數非常龐大以至於訓練花費的時間過久之外,還有可能由於小數的部分過大,導致超出了浮點數精度的範圍,以至於出現非法值Nan這種情況出現。同樣,我們可以參考一下下圖:


講透機器學習中的梯度下降

這張圖畫的是學習率過小,導致一直在迭代,遲遲不能收斂的情況。


從上面這兩張圖,我們可以看得出來,在機器學習領域學習率的設置非常重要。一個好的參數不僅可以縮短模型訓練的時間,也可以使模型的效果更好。但是設置學習率業內雖然有種種方法,但是不同的問題場景,不同的模型的學習率設置方法都略有差別,也正因此,很多人才會調侃自己是調參工程師。


我們來看一下一個合適的學習率的迭代曲線是什麼樣的。

講透機器學習中的梯度下降

到這裡還沒有結束,好的學習率並不能解決所有的問題。在有些問題有些模型當中,很有可能最優解本身就是無法達到的,即使用非常科學的方法,設置非常好的參數。我們再來看一張圖:

講透機器學習中的梯度下降

這張圖有不止一個極值點,如果我們一開始的時候,參數落在了區間的左側,那麼很快模型就會收斂到一個極值,但是它並不是全局最優解,只是一個局部最優解。這時候無論我們如何設置學習率,都不可能找到右側的那個全局最優解。同樣,如果我們一開始參數落在了區間右側,那裡的曲線非常平坦,使得每次迭代的梯度都非常小,非常接近0.那麼雖然最終可以到達全局最優解,但是需要經過漫長的迭代過程。


所以,模型訓練、梯度下降雖然方法簡單,但是真實的使用場景也是非常複雜的。我們不可以掉以輕心,不過好在,對於線性迴歸的最小二乘法來說,損失函數是一個凸函數,意味著它一定有全局最優解,並且只有一個。隨著我們的迭代,一定可以達到收斂。


代碼實戰


Talk is cheap, show me the code.


光說不練假把式,既然我們已經學習到了梯度下降的精髓,也該親身用代碼體驗一下了。我們還是用之前線性迴歸的問題。如果有遺忘的同學可以點擊下方的鏈接回顧一下之前的內容:



還是和之前一樣,我們先生成一批點:


講透機器學習中的梯度下降


這是根據函數 y = 3x + 4 隨機出來的,我們接下來就要通過梯度下降的方法來做線性迴歸。首先,我們來推導一下梯度公式:


在使用梯度下降算法的時候,我們其實計算當前 θ 下的梯度。這個量反應的是當我們的 θ 發生變化的時候,整個的損失函數MSE(mean square error 均方差)會變化多少。而梯度,可以通過對變量求偏導得到。


我們單獨計算 θj 的損失函數偏導,帶入之前的損失函數公式,計算化簡可以得到:


講透機器學習中的梯度下降


這只是 θj 的偏導數,我們可以把向量 θ 中每一個變量的偏導數合在一起計算。標記為:


講透機器學習中的梯度下降


我們不難看出,在這個公式當中,我們涉及了全量的訓練樣本X。因此這種方法被稱為批量梯度下降。因此,當我們的訓練樣本非常大的時候,會使得我們的算法非常緩慢。但是使用梯度下降算法,和特徵的數量成正比,當特徵數量很大的時候,梯度下降要比方程直接求解快得多。


需要注意一點,我們推導得到的梯度是向上的方向。我們要下降,所以需要加一個負號,最後再乘上學習率,得到的公式如下:


講透機器學習中的梯度下降


根據公式,寫出代碼就不復雜了:


講透機器學習中的梯度下降


我們調用一下這段代碼,來查看一下結果:


講透機器學習中的梯度下降


和我們設置的參數非常接近,效果算是很不錯了。如果我們調整學習率和迭代次數,最後的效果可能會更好。


觀察一下代碼可以發現,我們在實現梯度下降的時候,用到了全部的樣本。顯然,隨著樣本的數量增大,梯度下降會變得非常慢。為了解決這個問題,專家們後續推出了許多優化的方法。不過由於篇幅的限制,我們會在下一篇文章當中和大家分享,感興趣的同學可以小小地期待一下。


梯度下降非常重要,可以說是機器學習領域至關重要的基礎之一,希望大家都能學會。


今天的文章就到這裡,如果覺得有所收穫,請順手點個關注或轉發吧,你們的支持是我最大的動力。


分享到:


相關文章: