6. 用深度学习框架来简洁地实现 线性回归模型

1. 生成数据集

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

# 通过 d2l中的函数 来生成features和labels
features,labels = d2l.synthetic_data(true_w,true_b,1000)

2. 调用框架中现有的API来读取数据

def load_array(data_arrays,batch_size,is_train=True):
    '''构造一个pytorch数据迭代器'''
    # TensorDataset基于一系列张量构建数据集
    # 这些张量的形状可以不尽相同,但第一个维度必须具有相同大小。如下,是把features和labels的每一行对应起来
    # * :表示对元组拆包解开入参,也可以传入features,labels
    # 实例化 TensorDataset 时传入的就是一系列张量:TensorDataset(tensor_1, tensor_2, ..., tensor_n)
    dataset = data.TensorDataset(*data_arrays) 
    # 每次从dataset数据集中随机挑选batch_size个数据
    # shuffle=is_train 随机打乱顺序
    return data.DataLoader(dataset,batch_size,shuffle=is_train) # 返回的是随机挑选的数据:特征和标签

batch_size=10
# 把真实数据features和labels做成tuple,传入到函数
data_iter = load_array((features,labels),batch_size)

# iter()转成iterator迭代器,通过next()函数得到X和y
next(iter(data_iter))

6. 用深度学习框架来简洁地实现 线性回归模型_第1张图片

3. 使用框架与预定义好的层

from torch import nn  # 'nn'是神经网络的缩写
 
# 线性回归就是一个单层的神经网络,但是为了规范引入了Sequential 容器,可以把Sequential理解为list of layers
net = nn.Sequential(nn.Linear(2,1)) # 指定输入维度是2(输入的特征数为2),输出维度是1

关于nn.Linear的解释 链接

关于Sequential的解释 链接

4. 初始化模型参数权重和偏差(w和b)

# 通过net[0]访问到layer,通过weight访问到权重w,data是访问到w中的数据,normal_则是是用正态分布,替换掉data的值
# 正态分布 均值为0 标准差为0.01
net[0].weight.data.normal_(0,0.01)  # PyTorch权重初始化
net[0].bias.data.fill_(0) # 对偏差进行初始化

5. 定义损失函数

# 计算均方误差使用的是 MSELoss 类,也称为平方范数
loss = nn.MSELoss() # 可以向loss函数传递两个参数,第一个是预测值,第二个是真实值

6. 随机梯度下降

# 实例化 SGD实例
# 用全部样本梯度的均值更新可学习参数
# net.parameters()包括network中的所有参数,包括w和b
# trainer 优化器
# net.parameters() 括w和b
trainer = torch.optim.SGD(net.parameters(), lr = 0.03)

torch.optim.SGD的参数详解

7. 训练过程

# 训练过程代码与从零开始实现所做的非常相似

num_epochs = 3
for epoch in range(num_epochs):
    for X,y in data_iter: # 从data_iter中一次一次拿出mini_batch
        l = loss(net(X),y)  # 放进net中,因为net本身带了模型参数w和b,传入X,得到预测的y
        # 再和真实的y做loss
        trainer.zero_grad() # 先把优化器梯度清零,因为每一遍都会得到梯度,如果不清零,会累积梯度
        l.backward() # pytorch已经做了l.sum(),这个sum是在nn.MSELoss()中做的 
        # 就可以直接l.backward()进行反向传播
        
        trainer.step() # 有了梯度之后,可以调用优化器trainer的step函数,来进行模型参数的更新
    # 最后每扫完一遍数据,就传入真实的features得到预测的labels,去和真实的labels做loss损失
    # 可以看出 预测值和真实值之间的差距
    l = loss(net(features),labels)
    print(f'epoch{epoch+1},loss{l:f}')

在这里插入图片描述

你可能感兴趣的:(深度学习,深度学习,线性回归,人工智能)