整理自:《动手学深度学习》
线性模型 y = Xw + b, x是二维的
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
features,labels = d2l.synthetic_data(true_w,true_b,1000)
2. 读取数据集
使用PyTorch提供 的torch.utils.data.Dataset类和torch.utils.data.DataLoader类小批次的读入数据,省去了一些繁琐代码的书写。
dataset类用于包装张量,将多个张量打包在一起
dataloader类用于小批次取数据。
def load_array(data_arrays, batch_size, is_train=True):
"""数据迭代器"""
dataset = data.TensorDataset(*data_arrays) #传入一个张量列表的地址
return data.DataLoader(dataset, batch_size, shuffle=is_train) # 批次大小=10, 是否乱序取数据
batch_size = 10
data_iter = load_array((features,labels),batch_size)
3. 定义模型
Sequential类 将多个层串联在⼀起
from torch import nn
net = nn.Sequential(
nn.Linear(2,1)
)
4. 模型初始化参数
net [ 0 ] 选择模型中的第⼀个层,然后使用 weight.data 和 bias.data来访问参数
还可以使⽤替换⽅法normal_() 和fill_() 来重写参数值。函数后面的下划线表示原地操作
net[0].weight.data.normal_(0,0.01) # 正态分布随机值
net[0].bias.data.fill_(0) # 全部置零
5. 定义损失函数
loss = nn.MSELoss() # 均方损失函数
6. 定义优化算法
小批次梯度下降
trainer = torch.optim.SGD(net.parameters(), lr=0.003) # 超参数lr(学习率)
7. 开始训练
for epoch in range(5):
for X,y in data_iter:
l = loss(net(X), y)
trainer.zero_grad() # 梯度置零 # 以下三步常常一起出现
l.backward() # 反向求导
trainer.step() # 更新参数theta
print(f'epoch:{epoch+1},loss:{loss(net(features), labels)}')
epoch:1,loss:9.910147 epoch:2,loss:2.899162 epoch:3,loss:0.849399 epoch:4,loss:0.249149 epoch:5,loss:0.073238
8. 训练结果误差
w = net[0].weight.data
print(f'w的误差:{true_w-w.reshape(true_w.shape)}')
b = net[0].bias.data
print(f'b的误差:{true_b-b}')
w的误差:tensor([-0.0007, -0.0002]) b的误差:tensor([-0.0003])