利用样本学习误差更新参数的3种策略
- BGD(Batch gradient descent)批量梯度下降法:每次迭代使用所有的样本
- SGD(Stochastic gradientdescent)随机梯度下降法:每次迭代使用一个样本
- MBGD(Mini-batch gradient descent)小批量梯度下降:每次迭代使用b个样本,介于 BGD 和 SGD 之间,1 < b < N (样本总量)
BGD.py
"""
BGD(Batch gradient descent)批量梯度下降法:每次迭代使用所有的样本
"""
# 用y = Θ1*x1 + Θ2*x2来拟合下面的输入和输出
# input1 1 2 5 4
# input2 4 5 1 2
# output 19 26 19 20
input_x = [[1, 4], [2, 5], [5, 1], [4, 2]] # 输入
y = [19, 26, 19, 20]
theta = [1, 1] # θ参数初始化
loss = 10 # loss先定义一个数,为了进入循环迭代
step_size = 0.01 # 步长
eps = 0.0001 # 精度要求
max_iters = 10000 # 最大迭代次数
error = 0 # 损失值
iter_count = 0 # 当前迭代次数
err1 = [0, 0, 0, 0] # 求Θ1梯度的中间变量1
err2 = [0, 0, 0, 0] # 求Θ2梯度的中间变量2
while loss > eps and iter_count < max_iters: # 迭代条件
loss = 0
err1sum = 0
err2sum = 0
for i in range(4): # 每次迭代所有的样本都进行训练
pred_y = theta[0] * input_x[i][0] + theta[1] * input_x[i][1] # 预测值
err1[i] = (pred_y - y[i]) * input_x[i][0]
err1sum = err1sum + err1[i]
err2[i] = (pred_y - y[i]) * input_x[i][1]
err2sum = err2sum + err2[i]
theta[0] = theta[0] - step_size * err1sum / 4 # 计算所有error求平均,用来更新Θ
theta[1] = theta[1] - step_size * err2sum / 4
for i in range(4):
pred_y = theta[0] * input_x[i][0] + theta[1] * input_x[i][1] # 预测值
error = (1 / (2 * 4)) * (pred_y - y[i]) ** 2 # 损失值
loss = loss + error # 总损失值
iter_count += 1
print("iters_count", iter_count)
print('theta: ', theta)
print('final loss: ', loss)
print('iters: ', iter_count)
SGD.py
import random
"""
SGD(Stochastic gradientdescent)随机梯度下降法:每次迭代使用一个样本
"""
# 用y = Θ1*x1 + Θ2*x2来拟合下面的输入和输出
# input1 1 2 5 4
# input2 4 5 1 2
# output 19 26 19 20
input_x = [[1, 4], [2, 5], [5, 1], [4, 2]] # 输入
y = [19, 26, 19, 20] # 输出
theta = [1, 1] # θ参数初始化
loss = 10 # loss先定义一个数,为了进入循环迭代
step_size = 0.01 # 步长
eps = 0.0001 # 精度要求
max_iters = 10000 # 最大迭代次数
error = 0 # 损失值
iter_count = 0 # 当前迭代次数
while loss > eps and iter_count < max_iters: # 迭代条件
loss = 0
i = random.randint(0, 4) # 每次迭代在input_x中随机选取一个样本进行权重的更新
pred_y = theta[0] * input_x[i][0] + theta[1] * input_x[i][1] # 预测值
# 梯度下降
theta[0] = theta[0] - step_size * (pred_y - y[i]) * input_x[i][0] # 只用1个样本的error来更新Θ
theta[1] = theta[1] - step_size * (pred_y - y[i]) * input_x[i][1]
for i in range(4):
pred_y = theta[0] * input_x[i][0] + theta[1] * input_x[i][1] # 预测值
error = 0.5 * (pred_y - y[i]) ** 2
loss = loss + error
iter_count += 1
print('iters_count', iter_count)
print('theta: ', theta)
print('final loss: ', loss)
print('iters: ', iter_count)
MBGD.py
import random
"""
MBGD(Mini-batch gradient descent)小批量梯度下降:每次迭代使用b组样本
由于单个样本的训练可能会带来很多噪声,使得SGD并不是每次迭代都向着整体最优化方向,因此在刚开始训练时可能收敛得很快,但是训练一段时间后就会变得很慢。
在此基础上又提出了小批量梯度下降法,它是每次从样本中随机抽取一小批(b个)进行训练,而不是一个。
"""
# 用y = Θ1*x1 + Θ2*x2来拟合下面的输入和输出
# input1 1 2 5 4
# input2 4 5 1 2
# output 19 26 19 20
input_x = [[1, 4], [2, 5], [5, 1], [4, 2]] # 输入
y = [19, 26, 19, 20] # 输出
theta = [1, 1] # θ参数初始化
loss = 10 # loss先定义一个数,为了进入循环迭代
step_size = 0.01 # 步长
eps = 0.0001 # 精度要求
max_iters = 10000 # 最大迭代次数
error = 0 # 损失值
iter_count = 0 # 当前迭代次数
while loss > eps and iter_count < max_iters: # 迭代条件
loss = 0
# 这里每次批量选取的是2组样本进行更新,另一个点是随机点+1的相邻点
i = random.randint(0, 4) # 随机抽取一组样本
j = (i + 1) % 4 # 抽取另一组样本,j=i+1
# MBGD 其实代码部分可以写的和 BGD 一样,名字也差不多,只是从整体中取一部分,介于 SGD 和 MBGD 之间
pred_y0 = theta[0] * input_x[i][0] + theta[1] * input_x[i][1] # 预测值1
pred_y1 = theta[0] * input_x[j][0] + theta[1] * input_x[j][1] # 预测值2
theta[0] = theta[0] - step_size * (1 / 2) * ((pred_y0 - y[i]) * input_x[i][0] + (pred_y1 - y[j]) * input_x[j][0]) # 对应5式
theta[1] = theta[1] - step_size * (1 / 2) * ((pred_y0 - y[i]) * input_x[i][1] + (pred_y1 - y[j]) * input_x[j][1]) # 对应5式
for i in range(4):
pred_y = theta[0] * input_x[i][0] + theta[1] * input_x[i][1] # 总预测值
error = (1 / (2 * 2)) * (pred_y - y[i]) ** 2 # 损失值
loss = loss + error # 总损失值
iter_count += 1
print('iters_count', iter_count)
print('theta: ', theta)
print('final loss: ', loss)
print('iters: ', iter_count)