4.5.0 头文件
import torch
from torch import nn
from d2l import torch as d2l
from matplotlib import pyplot as plt
4.5.1 制作数据集
# 训练集样本数、测试集样本数、样本维度、批量大小
n_train, n_test, num_inputs, batch_size = 20, 100, 200, 5
# 设置真实权重w,元素值全为0.01,设置真实偏移量b为0.05
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05
# 用数据集生成器训练集
train_data = d2l.synthetic_data(true_w, true_b, n_train)
# 将训练集打乱,然后按照批量大小进行切割和封装
train_iter = d2l.load_array(train_data, batch_size)
# 用数据集生成器生成测试集
test_data = d2l.synthetic_data(true_w, true_b, n_test)
# 将测试集按照批量大小进行切割和封装
test_iter = d2l.load_array(test_data, batch_size, is_train=False)
4.5.2 训练过程
def train_concise(wd):
# 定义网络模型,网络模型中只有一个线性层,输入特征的维度为num_inputs=200,只有一个输出
net = nn.Sequential(nn.Linear(num_inputs, 1))
for param in net.parameters():
# 用标准正态分布填充每一层的权重和偏移量
param.data.normal_()
# 定义均方误差损失函数
loss = nn.MSELoss(reduction='none')
# 定义训练轮数和学习率
num_epochs, lr = 100, 0.003
# 定义随机梯度下降优化器(偏置参数没有衰减)
trainer = torch.optim.SGD([{"params":net[0].weight,'weight_decay': wd}, {"params":net[0].bias}], lr=lr)
# 定义一个动画,用来将训练结果可视化
animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',xlim=[5, num_epochs], legend=['train', 'test'])
# 对于每一轮训练过程
for epoch in range(num_epochs):
# 对于,每一个批量的数据
for X, y in train_iter:
trainer.zero_grad()
# 计算预测标签和真实标签之间的损失
l = loss(net(X), y)
# 用优化器对权重和便宜进行优化
l.mean().backward()
trainer.step()
# 每隔5轮训练,将训练得到的模型在训练集和测试集上分别计算一次损失(训练损失、泛化损失)
if (epoch + 1) % 5 == 0:
animator.add(epoch + 1,(d2l.evaluate_loss(net, train_iter, loss),d2l.evaluate_loss(net, test_iter, loss)))
# 计算权重w的L2范数,即矩阵中各元素的平方和再开根号
print('w的L2范数:', net[0].weight.norm().item())
# 不使用L2正则项(不使用权重衰减)
# train_concise(0)
# 输出:
# w的L2范数: 13.763565063476562
# 使用L2正则项(使用权重衰减)
train_concise(3)
# 输出:
# w的L2范数: 0.37466463446617126
4.5.3可视化训练结果
plt.savefig('Output.png')
本小节完整代码如下
import torch
from torch import nn
from d2l import torch as d2l
from matplotlib import pyplot as plt
# ------------------------------制作数据集------------------------------------
# 训练集样本数、测试集样本数、样本维度、批量大小
n_train, n_test, num_inputs, batch_size = 20, 100, 200, 5
# 设置真实权重w,元素值全为0.01,设置真实偏移量b为0.05
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05
# 用数据集生成器训练集
train_data = d2l.synthetic_data(true_w, true_b, n_train)
# 将训练集打乱,然后按照批量大小进行切割和封装
train_iter = d2l.load_array(train_data, batch_size)
# 用数据集生成器生成测试集
test_data = d2l.synthetic_data(true_w, true_b, n_test)
# 将测试集按照批量大小进行切割和封装
test_iter = d2l.load_array(test_data, batch_size, is_train=False)
# ------------------------------训练过程------------------------------------
def train_concise(wd):
# 定义网络模型,网络模型中只有一个线性层,输入特征的维度为num_inputs=200,只有一个输出
net = nn.Sequential(nn.Linear(num_inputs, 1))
for param in net.parameters():
# 用标准正态分布填充每一层的权重和偏移量
param.data.normal_()
# 定义均方误差损失函数
loss = nn.MSELoss(reduction='none')
# 定义训练轮数和学习率
num_epochs, lr = 100, 0.003
# 定义随机梯度下降优化器(偏置参数没有衰减)
trainer = torch.optim.SGD([{"params":net[0].weight,'weight_decay': wd}, {"params":net[0].bias}], lr=lr)
# 定义一个动画,用来将训练结果可视化
animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',xlim=[5, num_epochs], legend=['train', 'test'])
# 对于每一轮训练过程
for epoch in range(num_epochs):
# 对于,每一个批量的数据
for X, y in train_iter:
trainer.zero_grad()
# 计算预测标签和真实标签之间的损失
l = loss(net(X), y)
# 用优化器对权重和便宜进行优化
l.mean().backward()
trainer.step()
# 每隔5轮训练,将训练得到的模型在训练集和测试集上分别计算一次损失(训练损失、泛化损失)
if (epoch + 1) % 5 == 0:
animator.add(epoch + 1,(d2l.evaluate_loss(net, train_iter, loss),d2l.evaluate_loss(net, test_iter, loss)))
# 计算权重w的L2范数,即矩阵中各元素的平方和再开根号
print('w的L2范数:', net[0].weight.norm().item())
# 不使用L2正则项(不使用权重衰减)
# train_concise(0)
# 输出:
# w的L2范数: 13.763565063476562
# 使用L2正则项(使用权重衰减)
train_concise(3)
# 输出:
# w的L2范数: 0.37466463446617126
# ------------------------------可视化训练结果------------------------------------
plt.savefig('Output.png')
浙公网安备 33010602011771号