导入处理数据集的模块
创建真实的权重和偏置,并生成1000条带噪声的模拟数据
import numpy as np
import torch
from torch.utils import data #导入专门处理数据的模块
from d2l import torch as d2l
true_w = torch.tensor([2,-3.4]) #真实的权重
true_b = 4.2 #真实的偏置
features,labels = d2l.synthetic_data(true_w,true_b,1000) #就是调用 d2l 工具包,直接生成1000条带噪声的模拟数据,y=Xw+b
定义数据加载器函数
输入:features和labels组成的元组,批量数据的大小以及默认参数is_train,表示训练集 功能:
- 将传入的参数解包,变成features和labels两个独立的参数,把它们打包成一个数据集,把特征值和标签组成一一对应的样本对。
- 返回数据加载器函数,接收一个数据集,变成批量数据并把训练集随机打乱
#把一堆原始数据变成一个按批次自动供应的数据加载器,data_arrays输入的数据,features和labels
def load_array(data_arrays,batch_size,is_train = True): #is_train=True,要加载训练集,False测试集
dataset = data.TensorDataset(*data_arrays)
#* 表示解包操作,变成features,labels独立的参数
#把多个张量打包成一个数据集,把特征和标签组成一一对应的样本对
return data.DataLoader(dataset,batch_size,shuffle = is_train) #data.DataLoader数据加载器,接收一个数据集,变成一批一批的数据
#shuffle=is_train,若True,加载训练集,随机打乱;若False,加载测试集,不打乱
batch_size = 10
data_iter = load_array((features,labels),batch_size) #(features,labels)元组,load_array创建一个训练集加载器,把数据随机打乱,data_iter数据供应器,产出一批(X,y)
next(iter(data_iter)) #验证是否能取出第一批数据
初始化神经网络模块
- 导入pytorch的神经网络模块
- 输入两个特征值,用y=Xw+b计算,输出1个特征值的线性回归预测值,用sequential容器打包,把多个层按顺序包装起来
- 取出容器第一层的权重参数,返回参数的原始张量,把所有权重从正态分布中随机抽样
- 取出函数第一层的偏置参数,返回参数的原始张量,将所有偏置值原地改为0
from torch import nn #导入pytorch的神经网络模块
net = nn.Sequential(nn.Linear(2,1)) #nn.linear(2,1)输入两个特征值,输出1个特征值的线性层,用sequential()容器包装,把多个层按顺序包装起来
#y = Xw+b生成预测值
net[0].weight.data.normal_(0,0.01) #net[0]取出容器的第一层,.weight权重参数,.data返回参数的原始张量可直接修改数值,normal(0,0.01)原地修改,把所有权重从正态分布中随机抽样
net[0].bias.data.fill_(0) #.bias偏置参数,.fill_(0)原地修改偏置值为0
损失函数和训练集
- 定义均方误差损失函数,并命名为loss
- 将需要被训练的参数weight和bias变成列表,学习率为0.03,传入梯度优化函数,生成训练集
loss = nn.MSELoss() #定义均方误差损失函数
trainer = torch.optim.SGD(net.parameters(),lr=0.03) #net.parameters()需要被训练的参数weight和bias,变成列表
按批次执行线性回归模型
- 从数据供应器中取出一小批数据
- 将预测特征矩阵和预测结果传入损失函数,计算小批量的均方误差
- 把优化器里的所有参数梯度都清0
- 根据损失值,自动计算模型对所有参数的新梯度
- 让优化器根据计算出的梯度,对模型所有参数执行一次更新
- 重复以上过程,将整个数据集扫描多次
损失函数和输出
- 对所有数据计算预测值之间的损失函数
- 把每一轮的平均损失打印出来,观察模型的学习情况
num_epochs = 3 #把整个数据集扫描三遍
for epoch in range(num_epochs):
for X,y in data_iter: #从数据供应器里面一次取出一小批数据
l = loss(net(X),y) #用net预测数据,计算均方误差损失,小批量
trainer.zero_grad() #把优化器里的所有参数梯度都清0
l.backward() #根据损失l,自动计算损失对模型所有参数的新梯度
trainer.step() #让优化器根据刚才计算出的梯度,对模型所有参数执行一次更新
l = loss(net(features),labels) #计算预测值之间的损失函数,对所有数据
print(f'epoch {epoch+1},loss {l:f}') #把每一轮的平均损失打印出来,观察模型是否越学越好