看到梯度下降演算法,首先我們應該去了解幾個問題,這是什麼?幹什麼用的?為什麼會產生這個概念或者事物?實現的具體思路是什麼?為什麼這麼實現,其背後的原理是什麼?
首先我們應該明確的一點是,所謂的梯度下降演算法並不是乙個機器學習演算法,而是乙個基於搜尋的最優化演算法。我們在上一節所講到的線性回歸演算法的目標是最優化乙個損失函式,這也是梯度下降演算法的思路。而梯度上公升演算法是最大化乙個效用函式。
其次我們需要明確,為什麼會產生這種演算法呢?從上一節我們可以看出來,我們可以通過正規方程解的方式求解出theta的值,但是很多數情況下theta的值是沒法求出其具體的公式的,因此梯度下降演算法應允而生。
實現的具體思路及邏輯:
要實現梯度下降,要就是實現最小化乙個損失函式,需要用到導數,引數為theta,對theta進行求解導數,需要不斷的遞減theta然後進行求解,此時便用到了學習速率。
而且學習速率取值的大小也十分的重要。
如圖所示:
公式推導:
**封裝:
def
fit_gd
(self,x_train,y_train,eta=
0.01
,n_iters=
1e4)
:'''check'''
assert x_train.shape[0]
== y_train.shape[0]
,\ "the size must be valid"
'''no.1 get j'''
defj
(x_b,theta,y)
:try
:return np.
sum(y - x_b.dot(theta))/
len(y)
except
:return
float
('inf'
)def
dj(x_b,theta,y)
:return x_b.t.dot(x_b.dot(theta)
- y)*2
/len
(x_b)
defgradient_decent
(x_b,y,initial_theta,eta,n_iters =
1e4,epsilon =1e-
8): theta = initial_theta
cur_iters =
0while cur_iters < n_iters:
gradient = dj(x_b,y,theta)
last_theta = theta
theta = theta - gradient*n_iters
if(abs
(j(x_b,y,theta)
- j(x_b,y,last_theta)
)< epsilon)
:break
cur_iters +=
1 x_b = np.hstack(
[np.ones(
(len
(x_train),1
)),x_train]
) initial_theta = np.zeros(x_b.shape[1]
) self._theta = gradient_decent(x_b,y_train,initial_theta,eta,n_iters)
self.coef_ = self._theta[1:
] self.interception_ = self._theta[0]
return self
隨機梯度下降法
隨機梯度下降法和批量梯度下降法在計算theta時是兩種不同的方式,兩者互有千秋,將兩者正式融合的是小批量梯度下降法(**會在github中開源,部落格不會詳細介紹)。
現在介紹兩者區別:
批量梯度下降法(batch gradient descent):是梯度下降的最原始的一種方式,使用特點和思路是使用全部的樣本進行更新theta,這樣的做法效率很低,訓練過程慢。
隨機梯度下降法:和bgd不同,隨機梯度下降法在更新theta時使用的是隨機的乙個樣本進行更新,例如如果存在10萬條資料,我們使用幾萬條資料便將theta更新到最優解了,大大提公升了訓練模型的效率,但是準確率較低。(通常情況下,我們願意使用犧牲模型一定的精度來換取訓練模型所用的時間)。
另外,實現隨機梯度下降時所用的學習速率需要注意:
我們每次都是採取的隨機的乙個樣本,如果採用固定的學習速率的話,如果我們接近找到的最佳的theta,就會慢慢的跳出最優位置,解決方案是需要讓學習速率根據執行的次數越來越小。
模擬退火的思想,我們將學習速率定義為下面的函式:
經驗上比較適合的值:a = 5、b = 50;
封裝隨機梯度下降演算法
def
fit_sgd
(self,x_train,y_train,eta=
0.01
,n_iters=
5,t0=
5,t1=50)
:'''check'''
assert x_train.shape[0]
== y_train.shape[0]
,\ "the size must be valid"
assert n_iters>=1,\
"the valud must be >= 1"
defdj_sgd
(theta,x_b_i,y_i)
:return x_b_i*
(x_b_i.dot(theta)
- y_i)*2
.def
sgd(x_b,y,initial_theta,n_iters,t0=
5,t1=50)
:def
learning_rate
(t):
return t0 /
(t + t1)
theta = initial_theta
m =len(x_b)
for cur_iters in
range
(n_iters)
: indexes = np.random.permutation(m)
x_b_new = x_b[indexes]
y_train_new = y_train[indexes]
for i in
range
(m):
gradient = dj_sgd(theta,x_b_new[i]
,y_train_new[i]
) theta = theta - eta * gradient
return theta
x_b = np.hstack(
[np.ones(
(len
(x_train),1
)), x_train]
) initial_theta = np.zeros(x_b.shape[1]
) self._theta = sgd(x_b, y_train, initial_theta, eta, n_iters)
self.coef_ = self._theta[1:
] self.interception_ = self._theta[0]
return self
後一小節將介紹小批量梯度下降演算法和對梯度下降演算法的更多思 機器學習「傻瓜式」理解(7)梯度下降法(第二部分)
事實上,我們在實際的生產活動中,最經常使用的便是小批量梯度下降法,這種方法綜合了隨機梯度下降法和批量梯度下降法兩種演算法,一定程度上避免了他們的缺點,這種演算法實現的思路便是每次計算優化的方向既不是檢視所有的樣本也不是檢視單一的樣本,而是每次抽取k個樣本,把這k個樣本的梯度作為優化方向。這樣有兩個優...
機器學習(三) 梯度下降法
本部落格大部分參考了這篇博文 在微積分裡面,對多元函式的引數求 偏導數,把求得的各個引數的偏導數以向量的形式寫出來,就是梯度。比如函式f x,y 分別對x,y求偏導數,求得的梯度向量就是 f x f y 簡稱gr adf x,y 或者 f x,y 如果是3個引數的向量梯度,就是 f x f y,f ...
機器學習(二) 梯度下降法
前言 在上篇博文機器學習 一 中,最後我們提到,通過計算代價函式j 是否收斂於最小值來確定假設函式的引數 進而訓練出機器學習中的線性回歸演算法,那麼如何來找到使得j 最小話的引數 呢,本篇博文將介紹一種常用的方法,梯度下降法來確定引數 值。一 對於單特徵線性回歸,梯度下降法的演算法如下 repeat...