从0开始学pytorch【1】--线性函数的梯度下降

从0开始学pytorch【1】--线性函数的梯度下降演示

故事背景

  在正式学习pytorch深度框架之前,假设你已经掌握了机器学习、深度学习的梯度下降算法基础理论,但是编程技术还不够熟练,于是本文将使用python演示如何利用梯度下降法求解一元线性回归中的参数。对于复杂的目标函数,无法求出显式解以及高维目标函数无法可视化。在知道样本数据下,于是通过梯度下降算法求解最优解(可能是局部最优解)。

y = w ∗ x + b y = w*x+b y=wx+b

其中的 w w w b b b就是我们要求解的参数。

生成数据

  假设500个样本来源于:
y = 5 ∗ x + 3 y = 5*x+3 y=5x+3
并且受到其他因素影响,这里设置标准高斯噪声,则生成样本数据:
y = 5 ∗ x + 3 + N ( 0 , 1 ) y = 5*x+3+N(0,1) y=5x+3+N(0,1)

import numpy as np

def function(b=3,size=500):
    x = np.random.uniform(1, 30, size)
    noise = np.random.normal(0, 1, size)
    y = 5 * x + b + noise
    list_1 = []
    for i, j in zip(x, y):
        list_1.append([i, j])
    return list_1

损失函数

  设置损失函数为均方误差MSE:

M S E = 1 n ∑ i = 1 n ( Y i − Y ^ i ) 2 Y i ^ = w ^ ∗ x i + b ^ \mathrm{MSE}=\frac{1}{n} \sum_{i=1}^n\left(Y_i-\hat{Y}_i\right)^2 \\ \hat{Y_i} = \hat{w}*x_i+\hat{b} MSE=n1i=1n(YiY^i)2Yi^=w^xi+b^

梯度更新1次

  梯度更新方法,lr为学习率:
w i + 1 = w i − l r ∗ ∂ M S E ∂ w w_{i+1} = w_i - lr *\frac{\partial MSE}{\partial w} wi+1=wilrwMSE

b i + 1 = b i − l r ∗ ∂ M S E ∂ b b_{i+1} = b_i - lr * \frac{\partial MSE}{\partial b} bi+1=bilrbMSE

# 梯度更新1次
def grad_step(c_w, c_b, lr, points):
    total_w_g,  total_b_g = 0, 0
    N = len(points)
    for point in points:
        x, y  = point[0], point[1]
        total_w_g += 2 * (y- (c_w * x + c_b) ) * (-x) / N
        total_b_g += 2 * (y- (c_w * x + c_b)) *(-1) / N
    c_w = c_w - lr * total_w_g
    c_b = c_b - lr * total_b_g
    return [c_w, c_b]

迭代

  在整个数据集上面循环time次,这里没有设置batch,即将整个样本理解为1个batch。

# 迭代
def diedai(i_w, i_b, lr, points,time):
    n_w, n_b = i_w, i_b
    for i in range(time):
        n_w, n_b = grad_step(n_w, n_b, lr, points)
    print('参数:', n_w, n_b )
    return [n_w, n_b]

主函数

  可以对比看迭代前后的损失,设置初始参数,并输出迭代后的参数估计值。

# 主函数

def main(i_w, i_b, lr, points, time):
    loss_i = copute_erro(i_w, i_b, points)
    print(f"初始状态损失:{loss_i}")
    
    ii_w, ii_b = diedai(i_w, i_b, lr, points, time)
    loss_e = copute_erro(ii_w, ii_b, points)
    print(f"结束状态损失:{loss_e}")

执行

  设置初始参数均为0,学习率为0.0001,迭代40000次,最后输出结果。

# 执行
if __name__ == "__main__":
    o_w = 0
    o_b = 0
    lr = 0.0001
    time = 40000
    
    points = function()

    main(o_w, o_b, lr, points, time)
'''
输出结果:
初始状态损失:8168.732799656018
参数: 5.0154640678882005 2.771481630325438
结束状态损失:1.0200946795304344
'''

  参数估计值 w w w, b b b分别为5.015464和2.77148,这总体设置的5和3很接近。前提是我们并不知道参数真实值为5和3,于是就用参数估计值5.015464和2.77148去替代总体参数。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高山莫衣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值