本代码基于《动手学深度学习》Pytorch版,第三章线性回归网络,第三节线性回归的简单实现。对代码进行修改,增加注释,供学习使用。
导入相关库
import torch
生成带有噪声的线性模型数据集
def generateDataset(w, b, n):
x = torch.normal(0, 1, (n, len(w)))
y = torch.matmul(x, w) + b
y += torch.normal(0, 0.01, y.shape)
return x, y.reshape((-1, 1))
定义随机小批量特征及样本的数据集
def readDataset(dataset, n, shuffle = True):
data = torch.utils.data.TensorDataset(*dataset)
# TensorDataset数据集类,将多个张量组合成一个数据集,以便在训练神经网络时使用
return torch.utils.data.DataLoader(data, n, shuffle = shuffle)
# DataLoader将数据集分成批次并在训练神经网络时提供数据,可自动处理批次(batch)的创建、打乱顺序(如果需要)等
# shuffle:是否在每个训练周期开始时打乱数据顺序,true即训练时打乱数据,而评估时保持原始顺序
# 在Python中,使用*作为前缀可将元组或列表中的元素解包并作为单独的参数传递给函数
建线性神经网络层
net = torch.nn.Sequential(torch.nn.Linear(2, 1))
# torch.nn.Sequential神经网络模块,将多个神经网络层按顺序连接起来,形成一个序列化的神经网络,将需连接的神经网络层作为参数传递即可
# torch.nn.Linear线性层类,将输入张量的每个元素乘以权重矩阵并加上偏置向量
初始化神经网络层参数
net[0].weight.data.normal_(0, 0.01)
net[0].bias.data.fill_(0)
# net[0]表示net中的第一个神经网络层
# weight权重,data表示权重的数据,normal_()表示将权重初始化为正态分布
# bias偏置,data表示偏置的数据,fill_()表示将偏置填充为0
定义损失函数
loss = torch.nn.MSELoss()
# torch.nn.MSELoss损失函数,计算输入和目标之间的均方误差(Mean Squared Error,MSE),将输入和目标作为参数传递即可
定义优化算法
trainer = torch.optim.SGD(net.parameters(), lr = 0.03)
# torch.optim.SGD优化器,实现随机梯度下降(Stochastic Gradient Descent,SGD)算法,将模型参数和学习率作为参数传递即可
# .parameters()返回模型中所有可训练参数(权重和偏置)的迭代器
实现
true_w = torch.tensor([2, -3.4])
true_b = 4.2
x, y = generateDataset(true_w, true_b, 1000)
n = 10
dataset = readDataset((x, y), n)
niterate = 3
for iterate in range(niterate):
for feature, label in dataset:
l = loss(net(feature), label)
trainer.zero_grad()
l.backward()
trainer.step()
# .step()优化器的一个方法,根据计算出的梯度更新模型的参数
# trainer.zero_grad()清空梯度,loss.backward()反向传播梯度,trainer.step()更新参数
# 在调用trainer.step()之前,必先调用trainer.zero_grad()清空梯度,否则梯度会累积,导致参数更新不正确
l = loss(net(x), y)
print(f'iterate {iterate + 1}, loss {l : f}')
运行结果
tensor([0.])
iterate 1, loss 0.000250
iterate 2, loss 0.000101
iterate 3, loss 0.000102