线性回归与梯度下降的代码实现

import random
import torch
from d2l import torch as d2l
import matplotlib.pyplot as plt

# 构造数据集
def syn_data(w,b,num_examples):
    x=torch.normal(0,1,(num_examples,len(w)))#均值为0,方差为一的随机数
    y=torch.matmul(x,w)+b
    y+=torch.normal(0,0.01,y.shape)
    return x,y.reshape(-1,1)  #转换成1列,-1是无效参数
true_w=torch.tensor([2,-3.4])
true_b=4.2
features,labels=syn_data(true_w,true_b,1000)
d2l.set_figsize()
d2l.plt.scatter(features[:,(1)].detach().numpy(),labels.detach().numpy(),1)#第一列,转到numpy
plt.show()

# 读取小批量
def data_iter(batch_size,features,labels): #接收批量大小、特征与标签
    num_examples = len(features)  #样本数
    indices=list(range(num_examples))#生成每个样本的标号,range(0,n-1
    random.shuffle(indices)#打乱标签
    for i in range(0,num_examples,batch_size): #从0开始到num,每次步长为batchsize
        batch_indices=torch.tensor(indices[i:min(i+batch_size,num_examples)])#批量标号为从i到I+batchsize,如果最后一步超出总长,则取总长)
        yield features[batch_indices],labels[batch_indices]#每次遍历会产生基于标号的特征和标签(x,y),标号即样本顺序

batch_size=10

for x,y in  data_iter(batch_size,features,labels):
    print(x,'\n',y)
    break

#定义模型
w=torch.normal(0,0.1,size=(2,1),requires_grad=True)#w初始化,均值为1,方差为0.1的正态分布
# print(w)
b=torch.zeros(1,requires_grad=True)#值为0
#对w,b进行更新,所以requires——grad=true

def linreg(x,w,b):
    return torch.matmul(x,w)+b

# 定义损失函数-使用均方误差
def squared_loss(y_hat,y):#y_hat 预测值
    return (y_hat-y.reshape(y_hat.shape))**2/2

# 随机梯度下降
def sgd(params,lr,batch_size):#params包含w,b所有参数,lr学习率
    # 更新的时候不参与梯度计算
    with torch.no_grad():
        for param in params:#对于参数的每一个w,b参数
            param-=lr*param.grad/batch_size#损失函数求均值
            param.grad.zero_()#梯度清零


# 训练过程:
lr=0.03#学习率
num_epochs=3#训练轮数
net=linreg#模型
loss=squared_loss#损失

for epoch in range(num_epochs):#每一轮
    for x,y in data_iter(batch_size,features,labels):#拿出批量大小的x,y
        l=loss(net(x,w,b),y) #x,w,b放进net里预测,与y做损失,l是批量大小的向量
        l.sum().backward()#损失求和算梯度
        sgd([w,b],lr,batch_size)#梯度更新
    with torch.no_grad():#扫完一遍数据后,进行评价,torch默认自带计算梯度,所以不需要的时候,with no——grad,节约内存
        train_1=loss(net(features,w,b),labels)
        print(f'epoch{epoch+1},loss{float(train_1.mean()):f}')

print(f'w的误差:{true_w-w.reshape(true_w.shape)}')
print(f'b的误差:{true_b-b}')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

在读研究僧-深度学习

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

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

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

打赏作者

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

抵扣说明:

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

余额充值