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}')
07-19
415
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
07-12
946
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)