梯度下降算法

2021-12-29 圖靈人工智慧

點擊上方「圖靈人工智慧」,選擇「星標」公眾號

您想知道的人工智慧乾貨,第一時間送達

梯度下降是非常常用的優化算法。作為機器學習的基礎知識,這是一個必須要掌握的算法。藉助本文,讓我們來一起詳細了解一下這個算法。

前言

本文代碼獲取:

https://github.com/paulQuei/gradient_descent

本文的算法示例通過Python語言實現,在實現中使用到了numpy和matplotlib。如果你不熟悉這兩個工具,請自行在網上搜索教程。

關於優化

大多數學習算法都涉及某種形式的優化。優化指的是改變x以最小化或者最大化某個函數的任務。

我們通常以最小化指代大多數最優化問題。最大化可經由最小化來實現。

我們把要最小化或最大化的函數成為目標函數(objective function)或準則(criterion)。

我們通常使用一個上標*表示最小化或最大化函數的x值,記做這樣:

[x^* = arg; min; f(x)]

優化本身是一個非常大的話題。如果有興趣,可以通過《數值優化》和《運籌學》的書籍進行學習。

模型與假設函數

所有的模型都是錯誤的,但其中有些是有用的。– George Edward Pelham Box

模型是我們對要分析的數據的一種假設,它是為解決某個具體問題從數據中學習到的,因此它是機器學習最核心的概念。

針對一個問題,通常有大量的模型可以選擇。

本文不會深入討論這方面的內容,關於各種模型請參閱機器學習的相關書籍。本文僅以最簡單的線性模型為基礎來討論梯度下降算法。

這裡我們先介紹一下在監督學習(supervised learning)中常見的三個符號:

m,描述訓練樣本的數量

x,描述輸入變量或特徵

y,描述輸出變量或者叫目標值

請注意,一個樣本可能有很多的特徵,因此x和y通常是一個向量。不過在剛開始學習的時候,為了便於理解,你可以暫時理解為這就是一個具體的數值。

訓練集會包含很多的樣本,我們用 表示其中第i個樣本。

x是數據樣本的特徵,y是其目標值。例如,在預測房價的模型中,x是房子的各種信息,例如:面積,樓層,位置等等,y是房子的價格。在圖像識別的任務中,x是圖形的所有像素點數據,y是圖像中包含的目標對象。

我們是希望尋找一個函數,將x映射到y,這個函數要足夠的好,以至於能夠預測對應的y。由於歷史原因,這個函數叫做假設函數(hypothesis function)。

學習的過程如下圖所示。即:首先根據已有的數據(稱之為訓練集)訓練我們的算法模型,然後根據模型的假設函數來進行新數據的預測。

線性模型(linear model)正如其名稱那樣:是希望通過一個直線的形式來描述模式。線性模型的假設函數如下所示:

[h_{\theta}(x) = \theta_{0} + \theta_{1} * x]

這個公式對於大家來說應該都是非常簡單的。如果把它繪製出來,其實就是一條直線。

下圖是一個具體的例子,即:的圖形:

線性模型與直覺

在實際的機器學習工程中,你會擁有大量的數據。這些數據會來自於某個數據源。它們存儲在csv文件中,或者以其他的形式打包。

但是本文作為演示使用,我們通過一些簡單的代碼自動生成了需要的數據。為了便於計算,演示的數據量也很小。

import numpy as np
max_x = 10
data_size = 10
theta_0 = 5
theta_1 = 2
def get_data:
x = np.linspace(1, max_x, data_size)
noise = np.random.normal(0, 0.2, len(x))
y = theta_0 + theta_1 * x + noisereturn x, y

這段代碼很簡單,我們生成了x範圍是 [1, 10] 整數的10條數據。對應的y是以線性模型的形式計算得到,其函數是:。現實中的數據常常受到各種因素的幹擾,所以對於y我們故意加上了一些高斯噪聲。因此最終的y值為比原先會有輕微的偏離。

最後我們的數據如下所示:

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [6.66, 9.11, 11.08, 12.67, 15.12, 16.76, 18.75, 21.35, 22.77, 24.56]

我們可以把這10條數據繪製出來這樣就有一個直觀的了解了,如下圖所示:

雖然演示用的數據是我們通過公式計算得到的。但在實際的工程中,模型的參數是需要我們通過數據學習到的。所以下文我們假設我們不知道這裡線性模式的兩個參數是什麼,而是通過算法的形式求得。

最後再跟已知的參數進行對比以驗證我們的算法是否正確。

有了上面的數據,我們可以嘗試畫一條直線來描述我們的模型。

例如,像下面這樣畫一條水平的直線:

很顯然,這條水平線離數據太遠了,非常的不匹配。

那我們可以再畫一條斜線。

我們初次畫的斜線可能也不貼切,它可能像下面這樣:

最後我們通過不斷嘗試,找到了最終最合適的那條,如下所示:

梯度下降算法的計算過程,就和這種本能式的試探是類似的,它就是不停的迭代,一步步的接近最終的結果。

代價函數

上面我們嘗試了幾次通過一條直線來擬合(fitting)已有的數據。

二維平面上的一條直線可以通過兩個參數唯一的確定,兩個參數的確定也即模型的確定。那如何描述模型與數據的擬合程度呢?答案就是代價函數。

代價函數(cost function)描述了學習到的模型與實際結果的偏差程度。以上面的三幅圖為例,最後一幅圖中的紅線相比第一條水平的綠線,其偏離程度(代價)應該是更小的。

很顯然,我們希望我們的假設函數與數據儘可能的貼近,也就是說:希望代價函數的結果儘可能的小。這就涉及到結果的優化,而梯度下降就是尋找最小值的方法之一。

代價函數也叫損失函數。

對於每一個樣本,假設函數會依據計算出一個估算值,我們常常用來表示。即 。

很自然的,我們會想到,通過下面這個公式來描述我們的模型與實際值的偏差程度:

[(h_\theta(x^i) - y^i)^2 = (\widehat{y}^{i} - y^i)^2 = (\theta_{0} + \theta_{1} * x^{i} - y^{i})^2]

請注意, 是實際數據的值, 是我們的模型的估算值。前者對應了上圖中的離散點的y坐標,後者對應了離散點在直線上投影點的y坐標。

每一條數據都會存在一個偏差值,而代價函數就是對所有樣本的偏差求平均值,其計算公式如下所示:

[L(\theta) = \frac {1}{m} \sum_{i=1}^{m}(h_\theta(x^i) - y^i)^2 = \frac {1}{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i})^2]

當損失函數的結果越小,則意味著通過我們的假設函數估算出的結果與真實值越接近。這也就是為什麼我們要最小化損失函數的原因。

不同的模型可能會用不同的損失函數。例如,logistic回歸的假設函數是這樣的:。其代價函數是這樣的:

藉助上面這個公式,我們可以寫一個函數來實現代價函數:

def cost_function(x, y, t0, t1):
cost_sum = 0
for i in range(len(x)):
cost_item = np.power(t0 + t1 * x[i] - y[i], 2)
cost_sum += cost_itemreturn cost_sum / len(x)

這個函數的代碼應該不用多做解釋,它就是根據上面的完成計算。

我們可以嘗試選取不同的 和 組合來計算代價函數的值,然後將結果繪製出來:

import numpy as np
import matplotlib.pyplot as pltfrom matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
theta_0 = 5
theta_1 = 2
def draw_cost(x, y):fig = plt.figure(figsize=(10, 8))
ax = fig.gca(projection='3d')
scatter_count = 100
radius = 1
t0_range = np.linspace(theta_0 - radius, theta_0 + radius, scatter_count)t1_range = np.linspace(theta_1 - radius, theta_1 + radius, scatter_count)cost = np.zeros((len(t0_range), len(t1_range)))
for a in range(len(t0_range)):
for b in range(len(t1_range)):
cost[a][b] = cost_function(x, y, t0_range[a], t1_range[b])t0, t1 = np.meshgrid(t0_range, t1_range)ax.set_xlabel('theta_0')
ax.set_ylabel('theta_1')
ax.plot_surface(t0, t1, cost, cmap=cm.hsv)

在這段代碼中,我們對 和 各自指定了一個範圍進行100次的採樣,然後以不同的 組合對來計算代價函數的值。

如果我們將所有點的代價函數值繪製出來,其結果如下圖所示:

從這個圖形中我們可以看出,當 越接近 [5, 2]時其結果(偏差)越小。相反,離得越遠,結果越大。

直觀解釋

從上面這幅圖中我們可以看出,代價函數在不同的位置結果大小不同。

從三維的角度來看,這就和地面的高低起伏一樣。最高的地方就好像是山頂。

而我們的目標就是:從任意一點作為起點,能夠快速尋找到一條路徑並以此到達圖形最低點(代價值最小)的位置。

而梯度下降的算法過程就和我們從山頂想要快速下山的做法是一樣的。

在生活中,我們很自然會想到沿著最陡峭的路往下行是下山速度最快的。如下面這幅圖所示:

針對這幅圖,細心的讀者可能很快就會有很多的疑問,例如:

對於一個函數,怎麼確定下行的方向?

每一步該往前走多遠?

有沒有可能停留在半山腰的平臺上?

這些問題也就是本文接下來要討論的內容。

算法描述

梯度下降算法最開始的一點就是需要確定下降的方向,即:梯度。

我們常常用 來表示梯度。

對於一個二維空間的曲線來說,梯度就是其切線的方向。如下圖所示:

而對於更高維空間的函數來說,梯度由所有變量的偏導數決定。

其表達式如下所示:

[\nabla f({\theta}) = ( \frac{\partial f({\theta})}{\partial \theta_1} , \frac{\partial f({\theta})}{\partial \theta_2} , ... , \frac{\partial f({\theta})}{\partial \theta_n} )]

在機器學習中,我們主要是用梯度下降算法來最小化代價函數,記做:

[\theta ^* = arg min L(\theta)]

其中,L是代價函數,是參數。

梯度下降算法的主體邏輯很簡單,就是沿著梯度的方向一直下降,直到參數收斂為止

記做:

[\theta ^{k + 1}_i = \theta^{k}_i - \lambda \nabla f(\theta^{k})]

這裡的下標i表示第i個參數。

上標k指的是第k步的計算結果,而非k次方。在能夠理解的基礎上,下文的公式中將省略上標k。

這裡有幾點需要說明:

收斂是指函數的變化率很小。具體選擇多少合適需要根據具體的項目來確定。在演示項目中我們可以選擇0.01或者0.001這樣的值。不同的值將影響算法的迭代次數,因為在梯度下降的最後,我們會越來越接近平坦的地方,這個時候函數的變化率也越來越小。如果選擇一個很小的值,將可能導致算法迭代次數暴增。

公式中的 稱作步長,也稱作學習率(learning rate)。它決定了每一步往前走多遠,關於這個值我們會在下文中詳細講解。你可以暫時人為它是一個類似0.01或0.001的固定值。

在具體的項目,我們不會讓算法無休止的運行下去,所以通常會設置一個迭代次數的最大上限。

線性回歸的梯度下降

有了上面的知識,我們可以回到線性模型代價函數的梯度下降算法實現了。

首先,根據代價函數我們可以得到梯度向量如下:

[\nabla f({\theta}) = (\frac{\partial L(\theta)}{ \partial\theta_{0}}, \frac{ \partial L(\theta)}{ \partial\theta_{1}}) = (\frac {2}{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) , \frac {2}{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) x^{i})]

接著,將每個偏導數帶入迭代的公式中,得到:

[\theta_{0} := \theta_{0} - \lambda \frac{\partial L(\theta_{0})}{ \partial\theta_{0}} = \theta_{0} - \frac {2 \lambda }{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) \ \theta_{1} := \theta_{1} - \lambda \frac{\partial L(\theta_{1})}{ \partial\theta_{1}} = \theta_{1} - \frac {2 \lambda }{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) x^{i}]

由此就可以通過代碼實現我們的梯度下降算法了,算法邏輯並不複雜:

learning_rate = 0.01
def gradient_descent(x, y):t0 = 10
t1 = 10
delta = 0.001
for times in range(1000):
sum1 = 0
sum2 = 0
for i in range(len(x)):
sum1 += (t0 + t1 * x[i] - y[i])sum2 += (t0 + t1 * x[i] - y[i]) * x[i]t0_ = t0 - 2 * learning_rate * sum1 / len(x)
t1_ = t1 - 2 * learning_rate * sum2 / len(x)
print('Times: {}, gradient: [{}, {}]'.format(times, t0_, t1_))
if (abs(t0 - t0_) < delta and abs(t1 - t1_) < delta):
print('Gradient descent finish')
return t0_, t1_
t0 = t0_t1 = t1_print('Gradient descent too many times')
return t0, t1

這段代碼說明如下:

我們隨機選擇了 都為10作為起點

設置最多迭代1000次

收斂的範圍設為0.001

學習步長設為0.01

如果我們將算法迭代過程中求得的線性模式繪製出來,可以得到下面這幅動態圖:

最後算法得到的結果如下:

...
Times: 657, gradient: [5.196562662718697, 1.952931052920264]
Times: 658, gradient: [5.195558390180733, 1.9530753071808193]
Times: 659, gradient: [5.194558335124868, 1.9532189556399233]
Times: 660, gradient: [5.193562479839619, 1.9533620008416623]
Gradient descent finish

從輸出中可以看出,算法迭代了660次就收斂了。這時的結果[5.193562479839619, 1.9533620008416623],這已經比較接近目標值 [5, 2]了。如果需要更高的精度,可以將delta的值調的更小,當然,此時會需要更多的迭代次數。

高維擴展

雖然我們舉的例子是二維的,但是對於更高維的情況也是類似的。同樣是根據迭代的公式進行運算即可:

[\theta_{i} = \theta_{i} - \lambda \frac {\partial L(\theta)}{\partial \theta_i} = \theta_{i} - \frac{2\lambda}{m} \sum_{i=1}^{m}(h_\theta(x^{k})-y^k)x_i^k]

這裡的下標i表示第i個參數,上標k表示第k個數據。

梯度下降家族BGD

在上面的內容中我們看到,算法的每一次迭代都需要把所有樣本進行遍歷處理。這種做法稱為之Batch Gradient Descent,簡稱BGD。作為演示示例只有10條數據,這是沒有問題的。

但在實際的項目中,數據集的數量可能是幾百萬幾千萬條,這時候每一步迭代的計算量就會非常的大了。

於是就有了下面兩個變種。

SGD

Stochastic Gradient Descent,簡稱SGD,這種算法是每次從樣本集中僅僅選擇一個樣本來進行計算。很顯然,這樣做算法在每一步的計算量一下就少了很多。

其算法公式如下:

[\theta_{i} = \theta_{i} - \lambda \frac {\partial L(\theta)}{\partial \theta_i} = \theta_{i} - \lambda(h_\theta(x^k)-y^k)x_i^k]

當然,減少算法計算量也是有代價的,那就是:算法結果會強依賴於隨機取到的數據情況,這可能會導致算法的最終結果不太令人滿意。

MBGD

以上兩種做法其實是兩個極端,一個是每次用到了所有數據,另一個是每次只用一個數據。

我們自然就會想到兩者取其中的方法:每次選擇一小部分數據進行迭代。這樣既避免了數據集過大導致每次迭代計算量過大的問題,也避免了單個數據對算法的影響。

這種算法稱之為Mini-batch Gradient Descent,簡稱MBGD。

其算法公式如下:

[\theta_{i} = \theta_{i} - \lambda \frac {\partial L(\theta)}{\partial \theta_i} = \theta_{i} - \frac{2\lambda}{m} \sum_{i=a}^{a + b}(h_\theta(x^k)-y^k)x_i^k]

當然,我們可以認為SGD是Mini-batch為1的特例。

針對上面提到的算法變種,該如何選擇呢?

下面是Andrew Ng給出的建議:

下表是 Optimization for Deep Learning 中對三種算法的對比

方法準確性更新速度內存佔用在線學習BGD好慢高否SGD好(with annealing)快低是MBGD好中等中等是算法優化

式7是算法的基本形式,在這個基礎上有很多人進行了更多的研究。接下來我們介紹幾種梯度下降算法的優化方法。

Momentum

Momentum是動量的意思。這個算法的思想就是藉助了動力學的模型:每次算法的迭代會使用到上一次的速度作為依據。

算法的公式如下:

[v^t = \gamma v^{t - 1} + \lambda \nabla f(\theta) \ \theta = \theta - v_t]

對比式7可以看出,這個算法的主要區別就是引入了,並且,每個時刻的受前一個時刻的影響。

從形式上看,動量算法引入了變量 v 充當速度角色——它代表參數在參數空間移動的方向和速率。速度被設為負梯度的指數衰減平均。名稱動量來自物理類比,根據牛頓運動定律,負梯度是移動參數空間中粒子的力。動量在物理學上定義為質量乘以速度。在動量學習算法中,我們假設是單位質量,因此速度向量 v 也可以看作是粒子的動量。

對於可以取值0,而是一個常量,設為0.9是一個比較好的選擇。

下圖是momentum算法的效果對比:

對原來的算法稍加修改就可以增加動量效果:

def gradient_descent_with_momentum(x, y):
t0 = 10
t1 = 10
delta = 0.001
v0 = 0
v1 = 0
gamma = 0.9
for times in range(1000):
sum1 = 0
sum2 = 0
for i in range(len(x)):
sum1 += (t0 + t1 * x[i] - y[i])sum2 += (t0 + t1 * x[i] - y[i]) * x[i]v0 = gamma * v0 + 2 * learning_rate * sum1 / len(x)
v1 = gamma * v1 + 2 * learning_rate * sum2 / len(x)
t0_ = t0 - v0t1_ = t1 - v1print('Times: {}, gradient: [{}, {}]'.format(times, t0_, t1_))
if (abs(t0 - t0_) < delta and abs(t1 - t1_) < delta):
print('Gradient descent finish')
return t0_, t1_
t0 = t0_t1 = t1_print('Gradient descent too many times')
return t0, t1

以下是該算法的輸出:

...
Times: 125, gradient: [4.955453758569991, 2.000005017897775]
Times: 126, gradient: [4.955309381126545, 1.9956928964532015]
Times: 127, gradient: [4.9542964317327005, 1.9855674828684156]
Times: 128, gradient: [4.9536358220657, 1.9781180992510465]
Times: 129, gradient: [4.95412496254411, 1.9788858350530971]
Gradient descent finish

從結果可以看出,改進的算法只用了129次迭代就收斂了。速度比原來660次快了很多。

同樣的,我們可以把算法計算的過程做成動態圖:

對比原始的算法過程可以看出,改進算法最大的區別是:在尋找目標值時會在最終結果上下跳動,但是越往後跳動的幅度越小,這也就是動量所產生的效果。

Learning Rate 優化

至此,你可能還是好奇該如何設定學習率的值。

事實上,這個值的選取需要一定的經驗或者反覆嘗試才能確定。

《深度學習》一書中是這樣描述的:「與其說是科學,這更像是一門藝術,我們應該謹慎地參考關於這個問題的大部分指導。」。

關鍵在於,這個值的選取不能過大也不能過小。

如果這個值過小,會導致每一次迭代的步長很小,其結果就是算法需要迭代非常多的次數。

那麼,如果這個值過大會怎麼樣呢?其結果就是:算法可能在結果的周圍來回震蕩,卻落不到目標的點上。下面這幅圖描述了這個現象:

事實上,學習率的取值未必一定要是一個常數,關於這個值的設定有很多的研究。

下面是比較常見的一些改進算法。

AdaGrad

AdaGrad是Adaptive Gradient的簡寫,該算法會為每個參數設定不同的學習率。它使用歷史梯度的平方和作為基礎來進行計算。

其算法公式如下:

[\theta_i = \theta_i - \frac{\lambda}{\sqrt{G_t + \epsilon}} \nabla f(\theta)]

對比式7,這裡的改動就在於分號下面的根號。

根號中有兩個符號,第二個符號比較好理解,它就是為了避免除0而人為引入的一個很小的常數,例如可以設為:0.001。

第一個符號的表達式展開如下:

[G_t = \sum_{i = 1}^{t} \nabla f(\theta){i}\nabla f(\theta){i}^{T}]

這個值其實是歷史中每次梯度的平方的累加和。

AdaGrad算法能夠在訓練中自動的對learning rate進行調整,對於出現頻率較低參數採用較大的學習率;相反,對於出現頻率較高的參數採用較小的學習率。因此,Adagrad非常適合處理稀疏數據。

但該算法的缺點是它可能導致學習率非常小以至於算法收斂非常的慢。

關於這個算法的直觀解釋可以看李宏毅教授的視頻課程:ML Lecture 3-1: Gradient Descent。

RMSProp

RMS是Root Mean Square的簡寫。RMSProp是AI教父Geoff Hinton提出的一種自適應學習率方法。AdaGrad會累加之前所有的梯度平方,而RMSProp僅僅是計算對應的平均值,因此可緩解Adagrad算法學習率下降較快的問題。

該算法的公式如下:

[E[\nabla f(\theta_{i})^2]^{t} = \gamma E[\nabla f(\theta_{i})^2]^{t - 1} + (1-\gamma)(\nabla f(\theta_{i})^{t})^{2} \ \theta_i = \theta_i - \frac{\lambda}{\sqrt{E[g^2]^{t+1} + \epsilon}} \nabla f(\theta_{i})]

類似的,是為了避免除0而引入。是衰退參數,通常設為0.9。

這裡的 是t時刻梯度平方的平均值。

Adam

Adam是Adaptive Moment Estimation的簡寫。它利用梯度的一階矩估計和二階矩估計動態調整每個參數的學習率。

Adam的優點主要在於經過偏置校正後,每一次迭代學習率都有個確定範圍,使得參數比較平穩。

該算法公式如下:

[m^{t} = \beta_{1} m^{t-1} + (1-\beta_{1}) \nabla f(\theta) \ v^{t} = \beta_{2} v^{t-1} + (1-\beta_{2}) \nabla f(\theta)^2 \ \widehat{m}^{t} = \frac{m^{t}}{1 - \beta^{t}_1} \ \widehat{v}^{t} = \frac{v^{t}}{1 - \beta^{t}_2} \ \theta = \theta - \frac{\lambda}{\sqrt{\widehat{v}^{t}} + \epsilon}\widehat{m}^{t}]

,分別是對梯度的一階矩估計和二階矩估計。, 是對,的校正,這樣可以近似為對期望的無偏估計。

Adam算法的提出者建議 默認值為0.9,默認值為0.999,默認值為 。

在實際應用中 ,Adam較為常用,它可以比較快地得到一個預估結果。

優化小結

這裡我們列舉了幾種優化算法。它們很難說哪種最好,不同的算法適合於不同的場景。在實際的工程中,可能需要逐個嘗試一下才能確定選擇哪一個,這個過程也是目前現階段AI項目要經歷的工序之一。

實際上,該方面的研究遠不止於此,如果有興趣,可以繼續閱讀 《Sebastian Ruder: An overview of gradient descent optimization algorithms》 這篇論文或者 Optimization for Deep Learning 這個Slides進行更多的研究。

由於篇幅所限,這裡不再繼續展開了。

算法限制

梯度下降算法存在一定的限制。首先,它要求函數必須是可微分的,對於不可微的函數,無法使用這種方法。

除此之外,在某些情況下,使用梯度下降算法在接近極值點的時候可能收斂速度很慢,或者產生Z字形的震蕩。這一點需要通過調整學習率來迴避。

另外,梯度下降還會遇到下面兩類問題。

局部最小值

局部最小值(Local Minima)指的是,我們找到的最小值僅僅是一個區域內的最小值,而並非全局的。由於算法的起點是隨意取的,以下面這個圖形為例,我們很容易落到局部最小值的點裡面。

這就是好像你從上頂往下走,你第一次走到的平臺未必是山腳,它有可能只是半山腰的一個平臺的而已。

算法的起點決定了算法收斂的速度以及是否會落到局部最小值上。

壞消息是,目前似乎沒有特別好的方法來確定選取那個點作為起點是比較好的,這就有一點看運氣的成分了。多次嘗試不同的隨機點或許是一個比較好的方法,這也就是為什麼做算法的優化這項工作是特別消耗時間的了。

但好消息是:

對於凸函數或者凹函數來說,不存在局部極值的問題。其局部極值一定是全局極值。

最近的一些研究表明,某些局部極值並沒有想像中的那麼糟糕,它們已經非常的接近全局極值所帶來的結果了。

鞍點

除了Local Minima,在梯度下降的過程中,還有可能遇到另外一種情況,即:鞍點(Saddle Point)。鞍點指的是我們找到點某個點確實是梯度為0,但它卻不是函數的極值,它的周圍既有比它小的值,也有比它大的值。這就好像馬鞍一樣。

如下圖所示:

多類隨機函數表現出以下性質:在低維空間中,局部極值很普遍。但在高維空間中,局部極值比較少見,而鞍點則很常見。

不過對於鞍點,可以通過數學方法Hessian矩陣來確定。關於這點,這裡就不再展開了,有興趣的讀者可以以這裡提供的幾個連結繼續探索。

參考資料與推薦讀物

Wikipeida: Gradient descent

Sebastian Ruder: An overview of gradient descent optimization algorithms

吳恩達:機器學習

吳恩達:深度學習

Peter Flach:機器學習

李宏毅 - ML Lecture 3-1: Gradient Descent

PDF: 李宏毅 - Gradient Descent

Intro to optimization in deep learning: Gradient Descent

Intro to optimization in deep learning: Momentum, RMSProp and Adam

Stochastic Gradient Descent – Mini-batch and more

劉建平Pinard - 梯度下降(Gradient Descent)小結

多元函數的偏導數、方向導數、梯度以及微分之間的關係思考

[Machine Learning] 梯度下降法的三種形式BGD、SGD以及MBGD

來源:海豚數據科學實驗室;版權屬於原作者,僅用於學術分享


往期精彩必讀文章(單擊就可查看):

1.圖靈獎得主Hamming的22年前經典演講:如何做研究,才能不被歷史遺忘

2.當這位70歲的Hinton老人還在努力推翻自己積累了30年的學術成果時,我才知道什麼叫做生命力(附Capsule最全解析)

3.你為什麼獲得不了圖靈獎,原來本科學的是計算機專業,數據顯示歷屆圖靈獎得主當中竟然只有三位在本科時主修計算機專業.

4.圖靈獎得主Jeff Ullman直言:機器學習不是數據科學的全部!統計學也不是

5.魔幻現實!英國百年名校認為基礎數學沒用,要裁掉數學系補貼AI研究,圖靈聽後笑了笑

6.圖靈獎得主Yann LeCun的六十年

7.圖靈獎得主長文報告:是什麼開啟了計算機架構的新黃金十年?

8.看了 72 位圖靈獎得主成就,才發現我對計算機一無所知

9.重讀圖靈經典之作,九條反駁意見引人深思

10.從圖靈獎看人工智慧的歷史沉浮

相關焦點

  • 機器學習——梯度下降、梯度下降的線性回歸算法
    一、梯度下降梯度下降是一個用來求函數最小值的算法,我們將使用梯度下降算法來求出代價函數J(θo,θ1)的最小值。梯度下降算法中要做的就是不停地一點點改變θo和θ1,直到J成為最小值或局部最小值。通常將θo和θ1的初始值設為0。
  • 梯度下降算法詳解
    原創 | CDA數據分析研究院,轉載需授權介紹如果說在機器學習領域有哪個優化算法最廣為認知,用途最廣,非梯度下降算法莫屬。但是換一種思路,比如用梯度下降算法去優化線性回歸的損失函數,完全就可以不用考慮多重共線性帶來的問題。其實不僅是線性回歸,邏輯回歸同樣是可以用梯度下降進行優化,因為這兩個算法的損失函數都是嚴格意義上的凸函數,即存在全局唯一極小值,較小的學習率和足夠的迭代次數,一定可以達到最小值附近,滿足精度要求是完全沒有問題的。
  • 梯度下降算法原理講解
    ,進而從數學上解釋梯度下降算法的原理,解釋為什麼要用梯度,最後實現一個簡單的梯度下降算法的實例!這個時候,便可利用梯度下降算法來幫助自己下山。我們在前文提到,梯度的方向實際就是函數在此點上升最快的方向!而我們需要朝著下降最快的方向走,自然就是負的梯度的方向,所以此處需要加上負號;那麼如果時上坡,也就是梯度上升算法,當然就不需要添加負號了。3.
  • 梯度下降優化算法綜述
    幾乎當前每一個先進的(state-of-the-art)機器學習庫或者深度學習庫都會包括梯度下降算法的不同變種實現。但是,它們就像一個黑盒優化器,很難得到它們優缺點的實際解釋。 這篇文章旨在提供梯度下降算法中的不同變種的介紹,幫助使用者根據具體需要進行使用。
  • 10個梯度下降優化算法+備忘單
    在一個線性回歸問題中,我已經用梯度下降實現了SGD, momentum, Nesterov, RMSprop 以及Adam,獲取代碼(JavaScript)通過梯度下降,優化算法可以在如下三個主要方面起作用:1、修改學習率成分,α, 或2、修改梯度成分
  • 深度學習之梯度下降算法(必看)
    這裡就要引出梯度下降算法(Gradient Descent)。通俗解釋梯度下降先從一個生活中的例子出發,通俗的解釋一下什麼是梯度下降算法:你可以想像一下,從前有座山,山裡有座廟,咳咳,跑題了。假設在山頂上有一個盲人,此時這個盲人要下山,山上天氣還不好,而且下山的路徑還無法確定,這個盲人想要下山,就可以採用梯度下降算法。盲人以他當前的所處的位置為基準,尋找這個位置最陡峭的地方,然後朝著山的高度下降的地方走,一直重複上述過程,那麼就能夠達到山底,請原諒我這糟糕的畫畫功底。
  • 從中學數學到AI算法01:切線、導數、偏導數、梯度、梯度下降算法
    內容導讀:切線、導數、偏導數、梯度、梯度下降算法,從中學、大學數學到人工智慧,這些概念是一脈相承的。本文將這些知識進行大串聯。如果你是個中學生,讀完本篇文章,你將會了解到,中學裡學習的數學將來會在人工智慧的哪些方面應用。
  • 詳解梯度下降算法 正確訓練模型利刃!
    【IT168 資訊】梯度下降是目前最流行的優化策略,目前用於機器學習和深度學習。它在訓練模型時使用,可以與每種算法結合使用,易於理解和實施。因此,每個使用機器學習的人都應該理解它的概念。閱讀完這篇文章後,你將了解梯度下降是如何工作的,它今天使用了哪些類型,以及它們的優點和權衡。
  • 機器學習:隨機梯度下降和批量梯度下降算法介紹
    機器學習:隨機梯度下降和批量梯度下降算法介紹 佚名 發表於 2017-11-28 04:00:28 隨機梯度下降(Stochastic gradient
  • 梯度與梯度下降法
    梯度下降梯度下降算法(Gradient Descent)是神經網絡模型訓練最常用的優化算法。梯度下降算法背後的原理:目標函數J(θ)J(θ)關於參數θθ的梯度將是目標函數上升最快的方向。參數更新公式如下:其中∇θJ(θ)∇θJ(θ)是參數的梯度,根據計算目標函數J(θ)J(θ)採用數據量的不同,梯度下降算法又可以分為批量梯度下降算法(Batch Gradient Descent),隨機梯度下降算法(Stochastic GradientDescent
  • 【速覽】CVPR 2020 | 協同梯度下降算法(Cogradient Descent)
    本文提出了協同梯度下降算法(CoGradient Descent),引入投影函數協同不同變量間的收斂速度,避免局部極小,實現更加充分的訓練。圖 1 CoGD示意圖傳統的雙線性問題優化的策略為在優化一個變量同時保持另一個變量固定,而我們的策略與之不同,我們試圖在優化的過程中考慮到兩個變量(A,x)之間的耦合關係。
  • 梯度下降法
    >批量梯度下降法、隨機梯度下降法和小批量梯度下降法梯度下降法(Gradient Descent熟悉該算法的人都應該聽說過這張「下山圖」:它的本質是求解「如何快速求解函數極值點」問題。本文我們就對梯度下降法做一個詳細的介紹,分別從算法推導、算法變種、算法實現和算法局限四個部分講解,這過程中我們會實例化每種算法實現的細節,我們也會看到梯度下降不同變種的區別和聯繫。
  • 【乾貨】深度學習必備:隨機梯度下降(SGD)優化算法及可視化
    來源:CSDN 授權轉載作者:Sebastian Ruder譯者:一隻鳥的天空【新智元導讀】梯度下降算法是機器學習中使用非常廣泛的優化算法,也是眾多機器學習算法中最常用的優化方法。幾乎當前每一個先進的(state-of-the-art)機器學習庫或者深度學習庫都會包括梯度下降算法的不同變種實現。但是,它們就像一個黑盒優化器,很難得到它們優缺點的實際解釋。這篇文章旨在提供梯度下降算法中的不同變種的介紹,幫助使用者根據具體需要進行使用。
  • 從梯度下降到擬牛頓法:詳解訓練神經網絡的五大學習算法
    梯度下降梯度下降,又稱為最速下降法是一種非常簡單和直觀的訓練算法。該算法從梯度向量中獲取優化信息,因此其為一階算法(通過一階偏導求最優權重)。如果我們指定 f(wi)= fi、f(wi)= gi,那麼該優化方法由點 w0 開始迭代,在滿足終止條件之前,就在訓練方向 di=-gi 上將 wi 移向 wi+1。因此,梯度下降法就是如下方程式進行迭代。
  • 梯度下降—Python實現
    梯度下降是數據科學的基礎,無論是深度學習還是機器學習。深入了解梯度下降原理一定會對你今後的工作有所幫助。你將真正了解這些超參數的作用以及處理使用此算法可能遇到的問題。然而,梯度下降並不局限於一種算法。另外兩種流行的梯度下降(隨機和小批量梯度下降)建立在主要算法的基礎上,你可能會看到比普通批量梯度下降更多的算法。
  • 梯度提升(Gradient Boosting)算法
    梯度下降法 3. 梯度提升算法4. 梯度提升原理推導 5. 對梯度提升算法的若干思考 6. 總結 7. Reference1. 引言提升樹利用加法模型與前向分歩算法實現學習的優化過程。當損失函數是平方誤差損失函數和指數損失函數時,每一步優化是很簡單的。
  • 機器學習中的梯度下降法
    本文中我講介紹一些機器學習領域中常用的且非常掌握的最優化算法,看完本篇文章後你將會明白:什麼是梯度下降法?  如何將梯度下降法運用到線性回歸模型中? 如何利用梯度下降法處理大規模的數據?梯度下降法的一些技巧  讓我們開始吧!梯度下降法是一個用於尋找最小化成本函數的參數值的最優化算法。
  • 一文看懂各種神經網絡優化算法:從梯度下降到Adam方法
    應該用梯度下降,隨機梯度下降,還是Adam方法?這篇文章介紹了不同優化算法之間的主要區別,以及如何選擇最佳的優化方法。什麼是優化算法?優化算法的功能,是通過改善訓練方式,來最小化(或最大化)損失函數E(x)。模型內部有些參數,是用來計算測試集中目標值Y的真實值和預測值的偏差程度的,基於這些參數,就形成了損失函數E(x)。
  • 基於梯度下降算法的線性回歸擬合(附python/matlab/julia代碼)
    梯度下降梯度下降法的原理  梯度下降法(gradient descent)是一種常用的一階(first-order)優化方法,是求解無約束優化問題最簡單、最經典的方法之一。  梯度下降最典型的例子就是從山上往下走,每次都尋找當前位置最陡峭的方向小碎步往下走,最終就會到達山下(暫不考慮有山谷的情況)。  首先來解釋什麼是梯度?這就要先講微分。
  • 【機器學習】梯度下降的Python實現
    你將真正了解這些超參數的作用、在背後發生的情況以及如何處理使用此算法可能遇到的問題,而不是玩弄超參數並希望獲得最佳結果。然而,梯度下降並不局限於一種算法。另外兩種流行的梯度下降(隨機和小批量梯度下降)建立在主要算法的基礎上,你可能會看到比普通批量梯度下降更多的算法。