BGD,SGD,MBGD 梯度下降法

利用样本学习误差更新参数的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)

你可能感兴趣的:(BGD,SGD,MBGD 梯度下降法)