一種直觀的方法認識梯度下降

【導讀】本文是深度學習專家 Thalles Silva 分享的一篇技術博客,主要講解機器學習算法中的梯度下降。首先從形象的角度介紹梯度下降:梯度、偏導數等。然後,根據一個具體的例子 “根據歷史數據來預測當前房價” 講解梯度下降及其代碼實現,在實例中主要使用 Mini-Batch 梯度下降(Mini-Batch Stochastic Gradient),並解釋了其誤差迭代曲線的變化趨勢和和原因,不太瞭解梯度下降算法的讀者可以仔細閱讀下。

作者博客:

https://sthalles.github.io/

An Intuitive Introduction to Gradient Descent

 毫無疑問,梯度下降是大多數機器學習(ML)算法的核心和靈魂。我認爲你應該花時間去理解它。因爲一旦你理解了它,你會更好地理解大多數 ML 算法的工作原理。

爲了學習梯度下降的核心,我們在文中舉了一個例子,這個任務是這個領域的老問題了,即通過歷史數據作爲先驗知識來預測房價。

基本概念



假設你想爬上一座高山。你的目標是以最快的速度登上山頂。你環顧四周,你意識到你有多條路徑可以開始。由於你處於最底層,所有這些選項似乎都可以讓你更接近頂峯。

但是你想以最快的方式達到頂峯。那麼,怎麼做呢?

到目前爲止,如果你還不清楚如何採取這一步驟,你可以使用梯度來幫助你。

正如 Khan Academy 視頻中所述,梯度捕捉了一個多變量函數的所有偏導數

讓我們一步一步看看它是如何工作的。

簡單來說,導數就是某個點的函數變化率或斜率。

函數爲例。 的導數是計算給定點 x 處斜率的另一函數 f'(x)。在這種情況下,對於的斜率是 2x 或 2 * 2 = 4。

簡而言之,導數指向最陡峭的上升方向。梯度是和導數完全一樣的東西。 唯一的例外是:梯度 (Gradient) 是存儲偏導數的矢量值函數。 換句話說,梯度是一個向量,它的每個分量都是相對於一個特定變量的偏導數。

作爲另一個例子,取函數

這裏,是一個多變量函數。它的梯度是一個矢量,包含的偏導數。第一個關於 x,第二個關於 y。

如果我們計算 f(x,y)的偏函數,我們可以得到。

所以梯度是以下矢量:

請注意,上面每個部分都表示每個函數變量的最陡上升方向。換句話說,梯度指向函數增加最多的方向。

回到爬山的例子,梯度表示指向到達山峯最快的方向

同理,如果我們有一個具有 4 個變量的函數,我們將得到一個具有 4 個偏導數的梯度向量。通常,n 變量函數有 n 維梯度向量

然而,對於梯度下降 (Gradient descent),這個含義是我們不是很想使 f 最大化,而是希望將其最小化。

下面舉一個具體的任務,來看一下。

預測房價 (Predicting House Prices)

我們的問題是根據已有歷史數據來預測當前的房價。如果要構建一個機器學習模型,我們通常至少需要 3 個元素。問題 T,性能指標 P 和經驗 E,模型將從中數據中學習一種模式用於數據的預測。

我們將使用一個簡單的線性迴歸模型嘗試來解決這個問題。這個模型將從經驗 E 中學習,並且在訓練之後,它可以泛化應用到未知的數據。

線性模型是一個很好的學習模型。它是許多其他 ML 算法的基礎,如神經網絡和支持向量機。

對於這個例子,經驗 E 是 HOUSES 數據集。 HOUSES 數據集包含聖路易斯奧比斯波縣及其周邊地區最近的房地產列表。

該集合包含 781 個數據記錄,可在下面鏈接以 CSV 格式下載。在 8 維特徵中,爲了簡單起見,我們將只關注其中的兩個:**大小和價格。**對於 781 個記錄中的每一個,以平方英尺爲單位的大小將是我們的輸入特徵,而價格是我們的目標值。

https://wiki.csc.calpoly.edu/datasets/wiki/Houses

此外,爲了檢查我們的模型是否正確地從經驗 E(數據)中學習,我們需要一種機制來衡量其性能。爲此,我們將平方誤差總和(SSE)作爲我們的衡量標準。

SSE 多年來一直是線性迴歸的基準度量。但理論上,比如絕對誤差一樣的任何其他誤差衡量方式都可以。SSE 的好處是它比絕對誤差對錯誤的懲罰更大。

現在我們已經把我們的算法形式化表示,讓我們深入看一下代碼。

首先我們使用 Pandas 將數據加載到 python 中,然後將 Size 和 Prices 特徵分開。之後,我們對數據進行歸一化處理。此外,用歸一化數據做梯度下降會比其他情況快得多。

# read the Houses dataset CSV file
housing_data = pd.read_csv("./RealEstate.csv", sep=",")

# only get the Size and the Price features
Xs = housing_data[['Size']]
Ys = housing_data[['Price']]

# get some statistics
max_size = np.max(Xs)
min_size = np.min(Xs)
max_price = np.max(Ys)
min_price = np.min(Ys)

# Normalize the input features
Xs = (Xs - min_size) / (max_size - min_size)
Ys = (Ys - min_price) / (max_price - min_price)

從下圖中,你可以看到房屋價格按其平方米的大小分佈。

線性迴歸模型通過在數據上繪製一條直線來擬合數據。因此,我們的模型由一個簡單的線性方程表示。

對於線性模型,兩個參數是斜率 m 和偏置 b(y 軸截距)。我們將要不斷改變這兩個變量的值來得到最小的誤差值,也就是最終的模型參數值。

我們輕微改變兩個參數值,使函數值可以沿着誤差曲面上最陡的方向下降。每次迭代後,這些權重變化將優化我們的模型,以便模型能更好地表示數據集。

請牢記,對於梯度下降,我們希望採取與梯度相反的方向

你可以把梯度下降想象成一個在山谷中滾動的球。我們希望它坐在山的最深處(最低點),但是,很容易在其他山谷處。

根據球開始滾動的位置,它可能會停留在山谷的底部。然而不是最低的一個。這被稱爲局部最小值,在我們的模型中,山谷就是誤差面。

請注意,並不是所有的局部最小值都不好。其中一些實際上幾乎與最低(全局)一樣低(好)。事實上,對於高維誤差曲面,最常見的是解決方案找到一個局部最小值,但這個局部最小值不是很差,幾乎和全局最優值差不多。

同樣,我們初始化模型權重的方式可能導致它停留在局部最小值。爲了避免這種情況,我們用來自零均值和低方差的隨機正態分佈的值初始化兩個權向量。

在每次迭代中,我們將從我們的數據集中隨機採樣子集,並將其與我們的權重線性組合。這個子集稱爲 mini-batch。在線性組合之後,我們將模型預測得到結果送入 SSE 函數以計算當前誤差。

用這個誤差值,我們可以計算誤差的偏導數以得到梯度

首先,我們得到關於 W0 的偏導數。

第二步,同理得到 W1 的偏導數:

有了這兩個偏導數,我們得到了梯度向量:

其中 Err 是 SSE 誤差函數。

有了這些,下一步就是使用梯度來更新權重向量 W0 和 W1,以最大限度地減少誤差值。

我們想要更新權重,以便他們可以在下一次迭代中將誤差降低。我們需要使它們沿着每個相應梯度的相反方向。 要做到這一點,我們將在這個方向上採取尺寸爲η的小步長。

**步長η是學習率,**它控制學習的速度。從經驗上講,一個好的學習率值是 0.1。最後,更新步驟規則設置爲:

在代碼中,完整的模型如下所示。注意兩個梯度 DW0 和 DW1 前面的負號。這保證我們將採取與梯度相反的步驟。

DW0 = - (Y_pred-Ys_batch)
    DW1 = - (Xs_batch * (Y_pred - Ys_batch))for Xs_batch, Ys_batch in next_batch(Xs, Ys, batch_size=128):

    # linearly combine input and weights
    Y_pred = W0 + np.dot(W1, Xs_batch)

    # calculate the SSE between predicted and true values
    err = 1/2 * sum((Ys_batch-Y_pred)**2)

    # calculate the gradients with respect to W0 and W1
    DW0 = - (Y_pred-Ys_batch)
    DW1 = - (Xs_batch * (Y_pred - Ys_batch))

    # update W0 and W1 in the opposite direction to the gradient
    W0 = W0 + lr * sum(DW0)
    W1 = W1 + lr * sum(DW1)

更新權重後,我們隨機 mini-batch 數據重複該過程。

一步一步地,每個權重更新都會導致直線向最佳表示進行小幅度移動。最後,當誤差方差足夠小時,我們可以停止學習。

我們這裏面梯度下降稱爲 Mini-Batch 隨機梯度(Mini-Batch Stochastic Gradient )下降。在這個版本中,我們使用一小部分訓練數據來計算梯度。每個 Mini-Batch 梯度都提供了最佳方向的近似值。即使梯度沒有指向確切的方向,實際上它是接近最好的解決方案。

如果仔細觀察誤差 / 迭代次數曲線圖,您會注意到一開始,學習速度很快。

然而,經過一些迭代後,它變得緩慢。發生這種情況是因爲,一開始,指向最陡下降的梯度矢量的幅度很大。結果,兩個權重變量 W0 和 W1 更劇烈的變化。

但是,當它們接近誤差曲面的頂點時,梯度變得越來越小,這導致了權重變化很慢。

最後,學習曲線穩定下來,學習過程完成。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/_7wScTczag06o6P3zQ2-7Q