深度学习第一站——基础回归任务

本文介绍了如何使用PyTorch库实现线性回归模型,包括数据生成、添加噪声、数据提供器的实现以及使用SGD进行梯度下降优化。作者还展示了损失函数的计算和模型参数的更新过程,以及模型预测与真实值的可视化。
摘要由CSDN通过智能技术生成
import torch
import matplotlib.pyplot as plt #画图
import random  #生成随机数

def create_data(w,b,data_num):  #生成数据  w是矩阵
    x = torch.normal(0,1,(data_num,len(w)))  # 生成自变量x,期望值0,方差为1,数量为data_num,长度和w一致
    y = torch.matmul(x,w) + b   #构造函数 y=wx+b

    noise = torch.normal(0,0.01,y.shape)  #增加噪声,与Y同型
    y += noise  #y = y+noise

    return x,y   #返回生成的x和y向量

num = 500 #创建500个数
true_w = torch.tensor([8.1,2,2,4])  #设定真实的w与b
true_b = torch.tensor(1.1)           #转为张量,才可在torch中运算

X,Y = create_data(true_w,true_b,num)  #根据真实的w和b生成一笔样本数据

plt.scatter(X[:,0],Y,1)  #画散点图  所有行的某一列做X
plt.show()


def data_provider(data,label,batchsize):   #每一次访问,就提供一笔数据  data是X,label是Y,batchsize是所有样本中一部分
    length = len(label)        #记录向量Y的行数
    indices = list(range(length))   #记录Y的下标
    random.shuffle(indices)   #打乱列表的元素,即打乱下标,以达到随机取Y的目的
    for each in range(0,length,batchsize):    #范围+步长
        get_indices = indices[each:each+batchsize]  #创建一个列表,装随机取的16个下标数
        get_data = data[get_indices]     #取16个下标对应的X值
        get_label = label[get_indices]   #取16g个X对应的Y值
        yield get_data,get_label  #有存档点的return,每一个新的调用,就从上次的结束处开始

batchsize = 16   #样本容量16

for batch_x,batch_y in data_provider(X,Y,batchsize):
    print(batch_x,batch_y)
    break   #停止这层循环

def fun(x, w, b):
    pred_y = torch.matmul(x,w) + b   #计算y=wx+b pred_y为预测的y
    return pred_y

def maeloss(pred_y,y):
    loss = torch.sum(abs(pred_y-y))/len(y)   #计算loss值  abs()求绝对值  torch.sum求和
    return loss

def sgd(paras, lr) : #梯度下降函数   #传入参数和学习率,更新参数para
    with torch.no_grad():    #接下来的计算  不算梯度(回传不用计算梯度)
        for para in paras:  #遍历所有参数
            para -=para.grad*lr
            para.grad.zero_()    #回传过程,要把所有参数的梯度归零

lr = 0.025  #学习率
w_0 = torch.normal(0, 0.01, true_w.shape, requires_grad=True)  #均值为0,方差0.01,和w同型,计算梯度
b_0 = torch.tensor(0.01,requires_grad=True)  #计算梯度

print(w_0, b_0)
epochs = 50  #设定训练轮次,50轮

for epoch in range(epochs):
    data_loss = 0
    for batch_x,batch_y in data_provider(X,Y,batchsize):
        pred = fun(batch_x,w_0,b_0)  #计算初始设定的y=(w_0)x+(b_0)
        loss = maeloss(pred,batch_y)  #计算loss
        loss.backward()   #梯度回传
        sgd([w_0, b_0 ],lr)
        data_loss +=loss
        print("epoch %03d: loss:%.6f"%(epoch,data_loss))  #epoch取三位整数,data_loss保留6位小数
print("原来的函数值",true_w,true_b)  #真实的w和b
print(w_0,b_0)   #迭代更新之后的w和b

idx = 0  #某列
plt.plot(X[:, idx].detach().numpy(), X[:,idx].detach().numpy()*w_0[idx].detach().numpy()+b_0.detach().numpy(), label="pred")
plt.scatter(X[:,idx], Y, 1, label="true")  #画真实值的散点图
plt.show()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

岸丶丶丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值