深度学习入门:线性回归的简洁实现-代码拆解(源自李沐课程)

9 阅读4分钟

导入处理数据集的模块

创建真实的权重和偏置,并生成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,表示训练集 功能:

  1. 将传入的参数解包,变成features和labels两个独立的参数,把它们打包成一个数据集,把特征值和标签组成一一对应的样本对。
  2. 返回数据加载器函数,接收一个数据集,变成批量数据并把训练集随机打乱
#把一堆原始数据变成一个按批次自动供应的数据加载器,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))                     #验证是否能取出第一批数据

初始化神经网络模块

  1. 导入pytorch的神经网络模块
  2. 输入两个特征值,用y=Xw+b计算,输出1个特征值的线性回归预测值,用sequential容器打包,把多个层按顺序包装起来
  3. 取出容器第一层的权重参数,返回参数的原始张量,把所有权重从正态分布中随机抽样
  4. 取出函数第一层的偏置参数,返回参数的原始张量,将所有偏置值原地改为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

损失函数和训练集

  1. 定义均方误差损失函数,并命名为loss
  2. 将需要被训练的参数weight和bias变成列表,学习率为0.03,传入梯度优化函数,生成训练集
loss = nn.MSELoss()    #定义均方误差损失函数
trainer = torch.optim.SGD(net.parameters(),lr=0.03)    #net.parameters()需要被训练的参数weight和bias,变成列表

按批次执行线性回归模型

  1. 从数据供应器中取出一小批数据
  2. 将预测特征矩阵和预测结果传入损失函数,计算小批量的均方误差
  3. 把优化器里的所有参数梯度都清0
  4. 根据损失值,自动计算模型对所有参数的新梯度
  5. 让优化器根据计算出的梯度,对模型所有参数执行一次更新
  6. 重复以上过程,将整个数据集扫描多次

损失函数和输出

  1. 对所有数据计算预测值之间的损失函数
  2. 把每一轮的平均损失打印出来,观察模型的学习情况
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}')      #把每一轮的平均损失打印出来,观察模型是否越学越好