03线性回归简洁版
主要内容
- 生成数据集:使用给定的权重和偏置,以及一些噪声,生成模拟数据。
- 读取数据集:将数据打乱,并按批次读取数据。
- 初始化模型参数:随机初始化模型的权重和偏置,并启用自动求导。
- 定义模型:实现简单的线性回归模型。
- 定义损失函数:使用均方损失函数计算误差。
- 定义优化函数:实现小批量随机梯度下降算法。
- 模型训练:训练模型,更新参数,输出训练过程中每轮的损失以及最终的参数误差。
import numpy as np
import torch
from torch.utils import data# 生成数据集
def synthetic_data(w, b, num_examples):"""生成 y = Xw + b + 噪声"""# torch.normal: 返回一个从均值为0,标准差为1的正态分布中提取的随机数的张量# 生成形状为(num_examples, len(w))的矩阵X = torch.normal(0, 1, (num_examples, len(w)))# torch.matmul: 矩阵乘法y = torch.matmul(X, w) + b# 添加噪声:torch.normal(0, 0.01, y.shape)y += torch.normal(0, 0.01, y.shape)# reshape: 只改变张量的视图,不改变数据,将y转换为列向量return X, y.reshape((-1, 1))# 设定真实的权重和偏置
true_w = torch.tensor([2, -3.4])
true_b = 4.2
# 生成特征和标签
features, labels = synthetic_data(true_w, true_b, 1000)# 定义数据加载器
def load_array(data_arrays, batch_size, is_train=True):"""构造一个Pytorch数据迭代器"""dataset = data.TensorDataset(*data_arrays)# 使用DataLoader每次从dataset中抽选batch_size个样本# shuffle设定是否随机抽取return data.DataLoader(dataset, batch_size, shuffle=is_train)# 设置批量大小
batch_size = 10
data_iter = load_array((features, labels), batch_size)# "nn"是神经网络的缩写
from torch import nn# 定义模型
# Sequential类将多个层串联在一起
net = nn.Sequential(nn.Linear(2, 1))
# nn.Linear: 全连接层,输入特征数为2,输出特征数为1# 初始化模型参数
# normal: 生成符合正态分布的随机数,参数为均值0和标准差0.01
net[0].weight.data.normal_(0, 0.01)
# fill_: 将偏置初始化为0
net[0].bias.data.fill_(0)# 定义损失函数
# MSELoss: 计算均方误差,默认返回所有样本损失的平均值
loss = nn.MSELoss()# 实例化SGD优化器
trainer = torch.optim.SGD(net.parameters(), lr=0.03)#实例化SGD优化器时,需要指定要优化的参数和学习率(lr)
#这里的参数通过net.parameters()获取,学习率设置为0.03# 训练模型
num_epochs = 3
for epoch in range(num_epochs):for X, y in data_iter:# 计算模型输出和损失l = loss(net(X), y)# 梯度清零trainer.zero_grad()# 反向传播,计算梯度l.backward()# 更新模型参数trainer.step()# 每个epoch结束后计算整个数据集上的损失l = loss(net(features), labels)print(f'第{epoch + 1}轮,损失: {l:f}')# 打印生成数据集的真实参数和通过有限数据训练获得的模型参数的误差
w = net[0].weight.data
print('w的估计误差:', true_w - w.reshape(true_w.shape))
b = net[0].bias.data
print('b的估计误差:', true_b - b)# 示例输出:
# 第1轮,损失: 0.000246
# 第2轮,损失: 0.000103
# 第3轮,损失: 0.000103
# w的估计误差: tensor([ 0.0006, -0.0005])
# b的估计误差: tensor([0.0006])