還不了解梯度下降法?看完這篇就懂了!
- 2019 年 12 月 10 日
- 筆記
以下文章來源於數據科學家聯盟,作者餅乾Japson
0x00 前言:機器學習方法論
在此之前,我們已經學習了分類演算法:kNN演算法,回歸演算法:線性回歸。我們知道:
機器學習就是需找一種函數f(x)並進行優化, 且這種函數能夠做預測、分類、生成等工作。
那麼其實可以總結出關於「如何找到函數f(x)」的方法論。可以看作是機器學習的「三板斧」:
- 第一步:定義一個函數集合(define a function set)
- 第二步:判斷函數的好壞(goodness of a function)
- 第三步:選擇最好的函數(pick the best one)
我們先把目光放在第三步上:How to pick the best one ? 我們的目標是讓損失函數最小化。這就引出了下面需要介紹的方法:梯度下降是目前機器學習、深度學習解決最優化問題的演算法中,最核心、應用最廣的方法。
0x01 為什麼需要梯度下降演算法
如果我們拋開具體場景,僅從數學抽象的角度來看:每個模型都有自己的損失函數,不管是監督式學習還是非監督式學習。損失函數包含了若干個位置的模型參數,比如在多元線性回歸中,損失函數: ,其中向量表示未知的模型參數,我們就是要找到使損失函數儘可能小的參數未知模型參數。
在學習簡單線性回歸時,我們使用最小二乘法來求損失函數的最小值,但是這只是一個特例。在絕大多數的情況下,損失函數是很複雜的(比如邏輯回歸),根本無法得到參數估計值的表達式。因此需要一種對大多數函數都適用的方法。這就引出了「梯度演算法」。
我們先了解一下梯度下降是用來做什麼的?
首先梯度下降(Gradient Descent, GD),不是一個機器學習演算法,而是一種基於搜索的最優化方法。梯度下降(Gradient Descent, GD)優化演算法,其作用是用來對原始模型的損失函數進行優化,以便尋找到最優的參數,使得損失函數的值最小。
要找到使損失函數最小化的參數,如果純粹靠試錯搜索,比如隨機選擇1000個值,依次作為某個參數的值,得到1000個損失值,選擇其中那個讓損失值最小的值,作為最優的參數值,那這樣太笨了。我們需要更聰明的演算法,從損失值出發,去更新參數,且要大幅降低計算次數。
梯度下降演算法作為一個聰明很多的演算法,抓住了參數與損失值之間的導數,也就是能夠計算梯度(gradient),通過導數告訴我們此時此刻某參數應該朝什麼方向,以怎樣的速度運動,能安全高效降低損失值,朝最小損失值靠攏。
0x02 什麼是梯度
簡單地來說,多元函數的導數(derivative)就是梯度(gradient),分別對每個變數進行微分,然後用逗號分割開,梯度是用括弧包括起來,說明梯度其實一個向量,我們說損失函數L的梯度為:
我們知道導數就是變化率。梯度是向量,和參數維度一樣。
假設,我們有一個二元函數 。那麼f的梯度為:
例如在點(1,2),梯度∇f的取值為:
那麼這個梯度有什麼用呢?
在單變數的函數中,梯度其實就是函數的微分,代表著函數在某個給定點的切線的斜率 在多變數函數中,梯度是一個向量,向量有方向,梯度的方向就指出了函數在給定點的上升最快的方向
梯度指向誤差值增加最快的方向,導數為0(梯度為0向量)的點,就是優化問題的解。在上面的二元函數中,點(1,2)向著(4,2)的方向就是梯度方向 為了找到這個解,我們沿著梯度的反方向進行線性搜索,從而減少誤差值。每次搜索的步長為某個特定的數值,直到梯度與0向量非常接近為止。更新的點是所有點的x梯度,所有點的y梯度
0x03 理解梯度下降演算法
很多求解最優化問題的方法,大多源自於模擬生活中的某個過程。比如模擬生物繁殖,得到遺傳演算法。模擬鋼鐵冶煉的冷卻過程,得到退火演算法。其實梯度下降演算法就是模擬滾動,或者下山,在數學上可以通過函數的導數來達到這個模擬的效果。
梯度下降演算法是一種思想,沒有嚴格的定義。
3.1 場景假設
梯度下降就是從群山中山頂找一條最短的路走到山谷最低的地方。
既然是選擇一個方向下山,那麼這個方向怎麼選?每次該怎麼走?選方向在演算法中是以隨機方式給出的,這也是造成有時候走不到真正最低點的原因。如果選定了方向,以後每走一步,都是選擇最陡的方向,直到最低點。
總結起來就一句話:隨機選擇一個方向,然後每次邁步都選擇最陡的方向,直到這個方向上能達到的最低點。
梯度下降法的基本思想可以類比為一個下山的過程。假設這樣一個場景:
一個人被困在山上,需要從山頂到山谷。但此時霧很大,看不清下山的路徑。他必須利用自己周圍的資訊去找到下山的路徑。這個時候,他就可以利用梯度下降演算法來幫助自己下山。具體來說就是,以他當前的所處的位置為基準,隨機選擇一個方向,然後每次邁步都選擇最陡的方向。然後每走一段距離,都反覆採用同一個方法:如果發現腳下的路是下坡,就順著最陡的方向走一步,如果發現腳下的路是上坡,就逆著方向走一步,最後就能成功的抵達山谷。

3.2 數學推導
從數學的角度出發,針對損失函數L,假設選取的初始點為;現在將這個點稍微移動一點點,得到。那麼根據泰勒展開式(多元函數的一階展開式):
設我們移動的「一點點」為 ,則我們可以得到,將泰勒展開式代入其中,我們則得到:
如果我們令移動的距離分別為: ,其中規定,則可以得到:
這就說明,我們如果按照規定的移動距離公式移動參數,那麼損失函數的函數值始終是下降的,這樣就達到了我們要求的「損失變小」的要求了。如果一直重複這種移動,則可以證明損失函數最終能夠達到一個最小值。
那麼我們就可以得到損失函數值(也就是下一步的落腳點)的迭代公式:
針對於上述公式,有一些常見的問題:
為什麼要梯度要乘以一個負號?
我們已經知道:梯度的方向就是損失函數值在此點上升最快的方向,是損失增大的區域,而我們要使損失最小,因此就要逆著梯度方向走,自然就是負的梯度的方向,所以此處需要加上負號
關於參數 :
我們已經知道,梯度對應的是下山的方向,而參數 對應的是步伐的長度。在學術上,我們稱之為「學習率」(learning rate),是模型訓練時的一個很重要的超參數,能直接影響演算法的正確性和效率:
- 首先,學習率不能太大。因此從數學角度上來說,一階泰勒公式只是一個近似的公式,只有在學習率很小,也就是很小時才成立。並且從直觀上來說,如果學習率太大,那麼有可能會「邁過」最低點,從而發生「搖擺」的現象(不收斂),無法得到最低點
- 其次,學習率又不能太小。如果太小,會導致每次迭代時,參數幾乎不變化,收斂學習速度變慢,使得演算法的效率降低,需要很長時間才能達到最低點。
3.3 致命問題
梯度演算法有一個比較致命的問題:
從理論上,它只能保證達到局部最低點,而非全局最低點。在很多複雜函數中有很多極小值點,我們使用梯度下降法只能得到局部最優解,而不能得到全局最優解。那麼對應的解決方案如下:首先隨機產生多個初始參數集,即多組;然後分別對每個初始參數集使用梯度下降法,直到函數值收斂於某個值;最後從這些值中找出最小值,這個找到的最小值被當作函數的最小值。當然這種方式不一定能找到全局最優解,但是起碼能找到較好的。
對於梯度下降來說,初始點的位置,也是一個超參數。

0xFF 總結
在機器學習的「三板斧」中,第三步的目標是讓損失函數最小化,從而引出了梯度下降法,這一目前機器學習、深度學習解決最優化問題的演算法中,最核心、應用最廣的方法。所謂梯度下降,是一種基於搜索的最優化方法,其作用是用來對原始模型的損失函數進行優化,找到使損失函數(局部)最小的參數。
首先對梯度下降有一個整體的印象:梯度是向量,是多元函數的導數,指向誤差值增加最快的方向。我們沿著梯度的反方向進行線性搜索,從而減少誤差值,是為梯度下降。然後我們通過「下山」這樣的模擬場景,以及嚴謹的數據公式推導深刻理解了梯度下降演算法,並引出了學習率的概念。最後我們給出了梯度下降方法的不足和改進方法。
相信大家看完本篇文章後,對梯度下降演算法一定有了一個更加深刻的認識。如果沒懂?那就再多看幾遍吧(笑)