#从零开始实现整个方法,包括数据流水线、模型、损失函数和小批量随机梯度下降优化器 from matplotlib import pyplot as plt import random#随机化,初始化权重 import torch import torchvision from d2l import torch as d2l #构造人造数据集 #指定w和b,y=Xw+b+c X随机数 w权重 b偏差 c随机噪音 def synthetic_data(w,b,num_examples): x=torch.normal(0,1,(num_examples,len(w)))#均值0,方差1,大小为n个样本,列数为w的长度 y=torch.matmul(x,w)+b#两个张量矩阵相乘 y+=torch.normal(0,0.01,y.shape)#加入噪音 return x,y.reshape((-1,1))#做成列向量返回,-1表示自动计算,未指定,1固定,列向量为1 true_w=torch.tensor((2,-3.4)) true_b=4.2 features,labels=synthetic_data(true_w,true_b,1000)#特征为x,标签为y #features中每一行都包含一个二维数据样本,labels中每一行都包含一维标签值(一个标量) print('features:',features[0],'\nlabels',labels[0]) d2l.set_figsize()#画板 d2l.plt.scatter(features[:,(1)].detach().numpy()#detach分离出来才能转到numpy中 ,labels.detach().numpy(),1); plt.show() #实现一个函数,读取小批量,定义一个data_iter函数,该函数接受批量大小、特征矩阵和标签向量作为·输入,生成大小为batch_size的小批量 def data_iter(batch_size,features,labels): num_examples=len(features) indices=list(range(num_examples))#样本标号 #这些样本是随机读取的,没有特定顺序 random.shuffle(indices)#随机打乱 for i in range(0,num_examples,batch_size): batch_indices=torch.tensor( indices[i:min(i+batch_size,num_examples)] ) yield features[batch_indices],labels[batch_indices] batch_size=10 for x,y in data_iter(batch_size,features,labels): print(x,'\n',y) break #以上给出样本标号,随机选取样本返回出来 #定义初始化模型参数 w=torch.normal(0,0.01,size=(2,1),requires_grad=True) b=torch.zeros(1,requires_grad=True) #定义模型 def linreg(x,w,b): #线性回归模型 return torch.matmul(x,w)+b #定义损失函数 def squares_loss(y_hat,y): #均方损失 return (y_hat-y.reshape(y_hat.shape))**2/2 #定义优化算法 def sgd(params,lr,batch_size):#参数,学习率, 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=squares_loss#均方损失 for epoch in range(num_epochs): for x,y in data_iter(batch_size,features,labels): l=loss(net(x,w,b),y)#x,y的小批量损失 #因为l形状是(‘batch_size',1),而不是一个标量,l中所有元素被加到 #并以此计算关于['w','b']的梯度 l.sum().backward()#求和后算梯度 sgd([w,b],lr,batch_size)#使用参数的梯度更新参数 with torch.no_grad(): train_l=loss(net(features,w,b),labels) print(f'epoch {epoch+1},loss{float(train_l.mean()):f}') print(f'w的估计误差:{true_w-w.reshape(true_w.shape)}') print(f'b的估计误差:{true_b-b}')
【深度学习-pytorch】线性回归从0开始实现
最新推荐文章于 2022-11-29 20:42:45 发布