首先來看一個最簡單的例子,即線性迴歸。
與之前一樣,我們從代價函數(cost function)開始。
線性迴歸複習完畢。
所以,梯度下降算法是什麼?
上面算法的意思是說,為了執行梯度下降,我們就要計算代價函數 J 的梯度。為了計算代價函數的梯度,我們要對所有樣本的代價進行求和(黃色圓圈)。也就是說,如果有300萬個樣本,我們每計算一次梯度就要循環計算300萬次。
下面是Python代碼:
def gradientDescent(X, y, theta, alpha, num_iters):
"""
執行梯度下降
"""
m = y.size # 訓練樣本的數量
for i in range(num_iters):
y_hat = np.dot(X, theta)
theta = theta - alpha * (1.0/m) * np.dot(X.T, y_hat-y)
return theta
看到上面的 np.dot(X.T, y_hat-y) 了嗎?這是 “循環(求和)300萬個樣本” 的矢量化版本。
等等....這只是向最小化邁進了一步,我們真的要每計算一次代價就要計算300萬次嗎?
是的,如果使用梯度下降的話。
但如果使用隨機梯度(Stochastic Gradient Descent, SGD)下降,就沒有必要計算這麼多次!
基本上,在SGD中,我們在每次迭代時只使用 1 個樣本的梯度,用它來代替所有樣本的梯度之和。
def SGD(f, theta0, alpha, num_iters):
"""
參數:
f - 要優化的函數,它需要一個參數
併產生兩個輸出,一個代價和相對於參數的梯度
theta0 - 開始 SGD 的初始值
num_iters - SGD 的總迭代次數
返回:
theta - SGD 結束後的參數值
"""
start_iter = 0
theta= theta0
for iter in xrange(start_iter + 1, num_iters + 1):
_, grad = f(theta)
theta = theta - (alpha * grad) # 沒有使用點積
return theta
這是一個非常簡單的算法!
有幾點注意事項:
- 在SGD中,在循環之前,您需要隨機更改訓練樣本。
- 在SGD中,因為它一次只使用一個樣本,所以它的最小值路徑比批量梯度的路徑更嘈雜(更隨機)。但是沒關係,因為我們對路徑漠不關心,只要它給我們最小的值和更短的訓練時間。
- 小批量梯度下降在每次迭代時使用n個樣本點(而不是SGD中的1個樣本)。
閱讀更多 人工智能遇見磐創 的文章