偽代碼:
批量梯度下降法(Batch Gradient Descent):
Repeat until convergence{}
隨機(jī)梯度下降法(Stochastic Batch Gradient Descent):
Loop{
????for i = 1 to m,,{
????????????
????????????}
}
小批量梯度下降(Mini Batch Gradient Descent):
Repeat{
????for i = 1, 11, 21, 31, ... , 991 m,拗馒,{
????????????
????????????}
}
python代碼:
隨機(jī)梯度下降:
import numpy as np
# 構(gòu)造訓(xùn)練數(shù)據(jù)集
x_train = np.array([[2, 0., 3], [3, 1., 3], [0, 2., 3], [4, 3., 2], [1, 4., 4]])
# 構(gòu)建一個(gè)權(quán)重作為數(shù)據(jù)集的真正的權(quán)重路星,theta1主要是用來構(gòu)建y_train,然后通過模型計(jì)算
# 擬合的theta诱桂,這樣可以比較兩者之間的差異洋丐,驗(yàn)證模型。
theta1 = np.array([[2 ,3, 4]]).T
# 構(gòu)建標(biāo)簽數(shù)據(jù)集,y=t1*x1+t2*x2+t3*x3+b即y=向量x_train乘向量theta+b, 這里b=2
y_train = (x_train.dot(theta1) + np.array([[2],[2],[2],[2],[2]])).ravel()
# 構(gòu)建一個(gè)5行1列的單位矩陣x0访诱,然它和x_train組合垫挨,形成[x0, x1, x2, x3],x0=1的數(shù)據(jù)形式触菜,
# 這樣可以將y=t1*x1+t2*x2+t3*x3+b寫為y=b*x0+t1*x1+t2*x2+t3*x3即y=向量x_train乘向
# 量theta其中theta應(yīng)該為[b, *, * , *]九榔,則要擬合的theta應(yīng)該是[2,2,3,4],這個(gè)值可以
# 和算出來的theta相比較涡相,看模型的是否達(dá)到預(yù)期
x0 = np.ones((5, 1))
input_data = np.hstack([x0, x_train])
m, n = input_data.shape
# 設(shè)置兩個(gè)終止條件
loop_max = 10000000
epsilon = 1e-6
# 初始化theta(權(quán)重)
np.random.seed(0)
theta = np.random.rand(n).T # 隨機(jī)生成10以內(nèi)的哲泊,n維1列的矩陣
# 初始化步長(zhǎng)/學(xué)習(xí)率
alpha = 0.000001
# 初始化迭代誤差(用于計(jì)算梯度兩次迭代的差)
error = np.zeros(n)
# 初始化偏導(dǎo)數(shù)矩陣
diff = np.zeros(n)
# 初始化循環(huán)次數(shù)
count = 0
while count < loop_max:
count += 1 # 沒運(yùn)行一次count加1,以此來總共記錄運(yùn)行的次數(shù)
# 計(jì)算梯度
for i in range(m):
# 計(jì)算每個(gè)維度theta的梯度催蝗,并運(yùn)用一個(gè)梯度去更新它
diff = input_data[i].dot(theta)-y_train[i]
theta = theta - alpha * diff*(input_data[i])
# else中將前一個(gè)theta賦值給error,theta - error便表示前后兩個(gè)梯度的變化切威,當(dāng)梯度
#變化很小(在接收的范圍內(nèi))時(shí)丙号,便停止迭代先朦。
if np.linalg.norm(theta - error) < epsilon: # 判斷theta與零向量的距離是否在誤差內(nèi)
break
else:
error = theta
print(theta)
??真實(shí)的theta為[2, 2, 3, 4],計(jì)算結(jié)果如下圖1
批量梯度下降:
import numpy as np
# 構(gòu)造訓(xùn)練數(shù)據(jù)集
x_train = np.array([[2, 0., 3], [3, 1., 3], [0, 2., 3], [4, 3., 2], [1, 4., 4]])
m = len(x_train)
x0 = np.full((m, 1), 1)
# 構(gòu)造一個(gè)每個(gè)數(shù)據(jù)第一維特征都是1的矩陣
input_data = np.hstack([x0, x_train])
m, n = input_data.shape
theta1 = np.array([[2 ,3, 4]]).T
# 構(gòu)建標(biāo)簽數(shù)據(jù)集犬缨,后面的np.random.randn是將數(shù)據(jù)加一點(diǎn)噪聲喳魏,以便模擬數(shù)據(jù)集。
#y_train = (input_data.dot(np.array([1, 2, 3, 4]).T)).T
y_train = x_train.dot(theta1) + np.array([[2],[2],[2],[2],[2]])
# 設(shè)置兩個(gè)終止條件
loop_max = 1000000
epsilon = 1e-5
# 初始theta
np.random.seed(0) # 設(shè)置隨機(jī)種子
theta = np.random.randn(n,1) # 隨機(jī)取一個(gè)1維列向量初始化theta
# 初始化步長(zhǎng)/學(xué)習(xí)率
alpha = 0.00001
# 初始化誤差怀薛,每個(gè)維度的theta都應(yīng)該有一個(gè)誤差刺彩,所以誤差是一個(gè)4維。
error = np.zeros((n, 1)) # 列向量
# 初始化偏導(dǎo)數(shù)
diff = np.zeros((input_data.shape[1], 1 ))
# 初始化循環(huán)次數(shù)
count = 0
while count < loop_max:
count += 1
sum_m = np.zeros((n, 1))
for i in range(m):
for j in range(input_data.shape[1]):
# 計(jì)算每個(gè)維度的theta
diff[j] = (input_data[i].dot(theta)-y_train[i])*input_data[i, j]
# 求每個(gè)維度的梯度的累加和
sum_m = sum_m + diff
# 利用這個(gè)累加和更新梯度
theta = theta - alpha * sum_m
# else中將前一個(gè)theta賦值給error,theta - error便表示前后兩個(gè)梯度的變化,當(dāng)梯度
#變化很写淳蟆(在接收的范圍內(nèi))時(shí)嗡害,便停止迭代。
if np.linalg.norm(theta - error) < epsilon:
break
else:
error = theta
print(theta)
??真實(shí)的theta為[2, 2, 3, 4]畦攘,計(jì)算結(jié)果如下圖2:
小批量梯度下降:
import numpy as np
# 構(gòu)造訓(xùn)練數(shù)據(jù)集
x_train = np.array([[2, 0., 3], [3, 1., 3], [0, 2., 3], [4, 3., 2], [1, 4., 4]])
m = len(x_train)
x0 = np.full((m, 1), 1)
# 構(gòu)造一個(gè)每個(gè)數(shù)據(jù)第一維特征都是1的矩陣
input_data = np.hstack([x0, x_train])
m, n = input_data.shape
theta1 = np.array([[2 ,3, 4]]).T
# 構(gòu)建標(biāo)簽數(shù)據(jù)集霸妹,后面的np.random.randn是將數(shù)據(jù)加一點(diǎn)噪聲,以便模擬數(shù)據(jù)集念搬。
#y_train = (input_data.dot(np.array([1, 2, 3, 4]).T)).T
y_train = x_train.dot(theta1) + np.array([[2],[2],[2],[2],[2]])
# 設(shè)置兩個(gè)終止條件
loop_max = 1000000
epsilon = 1e-5
# 初始theta
np.random.seed(0) # 設(shè)置隨機(jī)種子
theta = np.random.randn(n,1) # 隨機(jī)取一個(gè)1維列向量初始化theta
# 初始化步長(zhǎng)/學(xué)習(xí)率
alpha = 0.00001
# 初始化誤差抑堡,每個(gè)維度的theta都應(yīng)該有一個(gè)誤差,所以誤差是一個(gè)4維朗徊。
error = np.zeros((n, 1)) # 列向量
# 初始化偏導(dǎo)數(shù)
diff = np.zeros((input_data.shape[1], 1 ))
# 初始化循環(huán)次數(shù)
count = 0
# 設(shè)置小批量的樣本數(shù)
minibatch_size= 2
while count < loop_max:
count += 1
sum_m = np.zeros((n, 1))
for i in range(1, m, minibatch_size):
for j in range(i - 1, i + minibatch_size - 1, 1):
# 計(jì)算每個(gè)維度的theta
diff[j] = (input_data[i].dot(theta)-y_train[i])*input_data[i, j]
# 求每個(gè)維度的梯度的累加和
sum_m = sum_m + diff
# 利用這個(gè)累加和更新梯度
theta = theta - alpha * (1.0 / minibatch_size)* sum_m
# else中將前一個(gè)theta賦值給error,theta - error便表示前后兩個(gè)梯度的變化首妖,當(dāng)梯度
#變化很小(在接收的范圍內(nèi))時(shí)爷恳,便停止迭代有缆。
if np.linalg.norm(theta - error) < epsilon:
break
else:
error = theta
print(theta)