當前位置:
首頁 > 最新 > 一文清晰講解機器學習中梯度下降演算法

一文清晰講解機器學習中梯度下降演算法

本篇文章向大家介紹梯度下降(Gradient Descent)這一特殊的優化技術,我們在機器學習中會頻繁用到。

前言

無論是要解決現實生活中的難題,還是要創建一款新的軟體產品,我們最終的目標都是使其達到最優狀態。作為一名計算機科學專業的學生,我經常需要優化各種代碼,以便提高其整體的運行速度。

一般情況下,最優狀態會伴隨問題的最佳解決方案。如果閱讀近期發表的關於優化問題的文章的話,你會發現,優化問題在現實生活中扮演著非常重要的作用。

機器學習中的優化問題與我們剛剛提到的內容有些許不同。通常情況下,在優化的過程中,我們非常清楚數據的狀態,也知道我們想要優化哪些區域。但是,在機器學習中,我們本就對「新數據」一無所知,更不要提優化問題了!

因此在機器學習中,我們對訓練數據進行優化,隨後再在全新的驗證數據中檢驗其運行情況。

優化的廣泛應用

目前,優化技術正被廣泛應用於各種不同的領域中,例如:

結構——比如說:決定航天設計的外型。

經濟——比如說:成本最低化。

物理——比如說:優化量子計算時間。

優化還有許多更為高級的應用,例如:提供最優運輸路徑,使貨架空間最合理化等等。

許多受歡迎的機器演算法都源於優化技術,例如:線性回歸演算法、K-最近鄰演算法、神經網路演算法等等。在學術界以及各行各業中,優化研究比比皆是,優化應用隨處可見。

目錄

什麼是梯度下降?

運用梯度下降演算法所面臨的挑戰

梯度下降演算法的變式

梯度下降的實現過程

使用梯度下降演算法的實用小貼士

附錄

1. 什麼是梯度下降?

我會以經典的登山案例來解釋梯度下降的含義。

假設你現在在山頂處,必須抵達山腳下(也就是山谷最低處)的湖泊。但讓人頭疼的是,你的雙眼被蒙上了無法辨別前進方向。那麼,你會採取什麼辦法抵達湖泊處呢?

最好的辦法就是查看一下周圍的地勢,觀察有下降趨勢的地面,這會幫助你邁出第一步。如果沿著下降的路線前進,那麼你非常有可能到達湖泊。

以圖形的形式呈現該處地勢。注意下面的曲線圖:

現在讓我們用數學術語把這個情景繪製成地圖吧。

為了學習梯度下降演算法,假設我們需要找出最佳的參數(θ1)和(θ2)。與上述做法相似,在測繪「成本空間」時,我們需要找到相似的山脈和山谷。成本空間是指為參數選定了一個特殊值後,演算法的運行情況。

所以,在Y軸上,我們讓J(θ1)與X軸上的參數(θ1)以及Z軸上的參數(θ2)分別相交。在這裡,數值高的紅色區域代表山峰,數值低的藍色區域代表山谷。

梯度下降演算法的類型有很多種,主要分為兩種:

基於數據的獲取

1. 全批梯度下降演算法

2. 隨機梯度下降演算法

在全批梯度下降演算法中,需要利用全部數據同時計算梯度;然而在隨機梯度下降演算法中,通常只需選取其中一個樣例來計算梯度。

基於微分技術

1. 一階微分

2. 二階微分

梯度下降需要通過成本函數微分來計算梯度。我們可以用一階微分技術或者二階微分技術來計算。

2. 運用梯度下降演算法所面臨的挑戰

在大多數情況下,梯度下降是一種聲音技術。但在很多情況下,梯度下降無法正常工作,甚至不工作。原因有三點:

數據挑戰

梯度挑戰

執行挑戰

2.1 數據挑戰

如果數據按照某種方式進行組合形成了一個非凸的優化問題,那麼就很難利用梯度下降演算法對其進行優化了。梯度下降演算法只能解決那些意義非常明確的凸優化問題。

在優化凸問題時,可能會出現無數的極小點。最低點被稱為全局最小值,其它的點被稱為局部極小值。我們的目的是要達到全局極小值,而非局部極小值。

還有一個問題就是鞍點。梯度為零時,它是數據中的一個點,但是不是最優點。目前,我們還沒有特定的方法來規避鞍點的出現,是一個新的研究領域。

2.2 梯度挑戰

如果執行梯度下降演算法時出現了錯誤,那麼可能會導致諸如梯度消失或者梯度崩潰等的問題。當梯度太小或者太大時,就會出現這樣的問題。也正因為這些問題,演算法無法收斂。

2.3 執行挑戰

通常情況下,大多數神經網路的開發者不會留意執行情況,但是觀察網路資源利用率是非常重要的。比如,在執行梯度下降演算法時,了解需要多少資源是非常重要的。如果應用程序的儲存器太小,那麼網路就會失敗。

跟蹤諸如浮點數的注意事項以及軟/硬體的先決條件,也非常重要。

3. 梯度下降演算法的變式

讓我們來看一下最常用的梯度下降演算法及其執行情況。

3.1 普通的梯度下降

這是梯度下降技術中最簡單的形式。此處的 vanilla 是純凈/不摻雜任何雜質的意思。它的主要特性就是,使我們向著成本函數梯度的最小值又邁進了一小步。

我們來看一下它的偽代碼。

update = learning_rate * gradient_of_parameters

parameters = parameters - update

在這裡,我們通過參數梯度來更新參數。而後通過學習率使其多樣化,實質上,常數代表著我們期望的達到最小值的速率。學習率是一種超參數,其數值一旦確定,就需要我們認真對待。

3.2 動量梯度下降

在進行下一步之前,我們先對之前的演算法稍作調整,以便回顧前面的步驟。

這是一組偽代碼。

update = learning_rate * gradient

velocity = previous_update * momentum

parameter = parameter + velocity – update

此處,更新後的代碼與普通的梯度下降演算法一樣。但是考慮到之前的更新和常量(動量),我們引進了一個名為速率(velocity)的術語。

3.3 ADAGRAD 演算法

ADAGRAD 演算法使用了自適應技術來更新學習率。在這種演算法中,我們會根據前期所有更迭的梯度變化情況,改變學習率。

這是一組偽代碼。

grad_component = previous_grad_component + (gradient * gradient)

rate_change = square_root(grad_component) + epsilon

adapted_learning_rate = learning_rate * rate_change

update = adapted_learning_rate * gradient

parameter = parameter – update

在上述代碼中,epsilon 是一個用於抑制學習率產生變動率的常量。

3.4 ADAM 演算法

ADAM 演算法是一種以 adagrad 演算法為基礎並且能進一步減少其缺點的更加自適應的技術。也就是說,你可以認為 ADAM 演算法是動量和 ADAGRAD 演算法的綜合體。

這是一組偽代碼。

adapted_gradient = previous_gradient + ((gradient – previous_gradient) * (1 – beta1))

gradient_component = (gradient_change – previous_learning_rate)

adapted_learning_rate =  previous_learning_rate + (gradient_component * (1 – beta2))

update = adapted_learning_rate * adapted_gradient

parameter = parameter – update

上述代碼中的 beta1 和 beta2 是用來保持梯度和學習率不變的常量。

與此同時,還存在如 l-BFGS 等這樣的二階微分演算法。你可以在 scipy 資料庫中看到這種演算法的執行情況。

4. 梯度下降的實現過程

現在我們來看一下利用 python 實現梯度下降的基礎小案例。

在這裡,我們將會利用梯度下降優化演算法找出深度學習模型中圖像識別應用問題的最佳參數。我們的問題是圖像識別,從已給的28 x 28圖像中分辨出其中的數字。我們有一個關於圖像的子集,一部分圖像用於訓練模型,另一部分圖像用於測試模型。在本篇文章中,我們會向大家介紹定義梯度下降演算法的過程以及演算法的運行過程。請參考這篇文章中有關利用 python 實現端到端運行的內容。

這是定義普通梯度下降演算法的主代碼:

params = [weights_hidden, weights_output, bias_hidden, bias_output]

def sgd(cost, params, lr=0.05):

grads = T.grad(cost=cost, wrt=params)

updates = []

for p, g in zip(params, grads):

updates.append([p, p - g * lr])

return updates

updates = sgd(cost, params)

為了能更好的理解上述代碼,接下來我們會分成不同的步驟詳細講解。

我們把 sgd 這個含有參數的函數分別定義為 cost、params 和 lr,分別代表上述例子中的 J(θ),θ是深度學習演算法和學習率的參數。我們將默認的學習率設為0.05,但是學習率可以隨著我們的喜好輕易地發生改變。

def sgd(cost, params, lr=0.05):

然後,我們定義關於這個成本函數的梯度參數。在這裡,我們利用 theano 資料庫來尋找梯度,T是我們將導入的 theano 數據:

grads = T.grad(cost=cost, wrt=params)

最後,通過所有參數的迭代找出所有可能需要更新的參數。大家可以看到,在這裡我們使用的是普通梯度下降演算法。

for p, g in zip(params, grads):

updates.append([p, p - g * lr]

接下來,我們可以利用這個函數找出神經網路中的最優參數。通過這個函數,我們發現神經網路非常擅長在圖片中查找數據,如下圖所示:

Prediction is:  8

在這個實例中,我們了解到利用梯度下降演算法能夠得到深度學習演算法中的最優參數。

5. 使用梯度下降演算法的實用小貼士

對於上述提到的各種梯度下降演算法,各有利弊。接下來,我會介紹一些能夠幫助大家找到正確演算法的實用方法。

如果是為了快速地獲得原型,那就選取諸如Adam/Adagrad這樣的自適應技術,這會讓我們事半功倍,並且無須大量調優超參數。

如果是為了得到最好的結果,那就選取普通的梯度下降演算法或者動量梯度下降演算法。雖然利用梯度下降演算法達到預期效果的過程很緩慢,但是大部分的結果比自適應技術要好得多。

如果你的數據偏小而且能夠適應一次迭代,那麼就可以選擇諸如 l-BFGS這樣的二階技術。這是因為,二階技術雖然速度非常快並且非常準確,但是只適用於數據偏小的情況。

還有一種是利用學習特性來預測梯度下降學習率的新興方法(雖然我還沒有嘗試過這種新興方法,但是看起來前途無量)。可以仔細地閱讀一下這篇文章。

目前,無法學習神經網路演算法的原因由很多。但是如果你能檢查出演算法出現錯誤的地方,對學習神經網路演算法將會非常有幫助。

當選用梯度下降演算法時,你可以看看這些能幫助你規避問題的小提示:

誤碼率——特定迭代之後,你應該檢查訓練誤差和測試誤差,並且確保訓練誤差和測試誤差有所減少。如果事實並非如此,那麼可能會出現問題!

隱含層數的梯度風氣流——如果網路沒有出現梯度消失或梯度爆炸問題,那麼請檢查一下網路。

學習率——選用自適應技術時,你應該檢測一下學習率。

6. 附錄

本篇文章參考了梯度下降優化演算法概述

https://arxiv.org/abs/1609.04747

梯度下降 CS231n 課程教材

http://cs231n.github.io/neural-networks-3/

深度學習這本書的第四章—數值優化演算法

http://www.deeplearningbook.org/contents/numerical.html

和第八章—深度學習模型的優化

http://www.deeplearningbook.org/contents/optimization.html

尾聲

我希望你喜歡這篇文章。在閱讀完本篇文章後,你會對梯度下降演算法及其變式有一定的了解。與此同時,我還在文章中向大家提供了執行梯度下降演算法以及其變式演算法的實用小貼士。希望對你有所幫助!

本文作者 Faizan Shaikh 是一名數據科學愛好者,目前正在研究深度學習,目標是利用自己的技能,推動 AI 研究的發展。

https://www.analyticsvidhya.com/blog/2017/03/introduction-to-gradient-descent-algorithm-along-its-variants/

更多AI資訊請關注微信公眾號:AI科技大本營(rgznai100)


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器學習 的精彩文章:

當機器學習遇上3D列印,大型工業製造革命指日可待
五種機器學習是革命性製造
Splunk在.conf2017上帶來的新解決方案使機器學習成為主流
一篇文章帶你徹底了解什麼是機器學習

TAG:機器學習 |