3.3.0 头文件
import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2l
from torch import nn
3.3.1 Dataloader的详细使用说明
from torch.utils.data import TensorDataset
import torch
from torch.utils.data import DataLoader
# 定义a为特征集合
a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 定义b为标签集合
b = torch.tensor([44, 55, 66, 44, 55, 66, 44, 55, 66, 44, 55, 66])
# 将数据集按照特征和数据的对应关系进行封装
train_ids = TensorDataset(a, b)
# 输出其中的一部分特征以及其对应的标签
print(train_ids[0:2])
# 输出:(第一个tensor为特征,第二个tensor为标签)
# (tensor([[1, 2, 3],
# [4, 5, 6]]), tensor([44, 55]))
# 循环度取特征以及对应的标签
for x_train, y_label in train_ids:
print(x_train, y_label)
# 输出:
# tensor([1, 2, 3]) tensor(44)
# tensor([4, 5, 6]) tensor(55)
# tensor([7, 8, 9]) tensor(66)
# tensor([1, 2, 3]) tensor(44)
# tensor([4, 5, 6]) tensor(55)
# tensor([7, 8, 9]) tensor(66)
# tensor([1, 2, 3]) tensor(44)
# tensor([4, 5, 6]) tensor(55)
# tensor([7, 8, 9]) tensor(66)
# tensor([1, 2, 3]) tensor(44)
# tensor([4, 5, 6]) tensor(55)
# tensor([7, 8, 9]) tensor(66)
# 将数据集按照批量大小进行切割和封装
train_loader = DataLoader(dataset=train_ids, batch_size=4, shuffle=True)
# 将数据(特征和对应的标签)按照批量大小读取出来
for i, data in enumerate(train_loader, 1): # 注意enumerate返回值有两个,一个是序号,一个是数据(包含训练数据和标签)
x_data, label = data
print(' batch:{0} x_data:{1} label: {2}'.format(i, x_data, label))
# 输出:
# batch:1 x_data:tensor([[7, 8, 9],
# [7, 8, 9],
# [4, 5, 6],
# [4, 5, 6]]) label: tensor([66, 66, 55, 55])
#
# batch:2 x_data:tensor([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9],
# [1, 2, 3]]) label: tensor([44, 55, 66, 44])
#
# batch:3 x_data:tensor([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9],
# [1, 2, 3]]) label: tensor([44, 55, 66, 44])
3.3.2 制作线性回归模型数据集
# 定义真实的权重参数
true_w = torch.tensor([2, -3.4])
# 定义真实的偏移量
true_b = 4.2
# 生成数据集,features为特征集合,labels为标签集合,数据集大小为1000
features, labels = d2l.synthetic_data(true_w, true_b, 1000)
3.3.3 读取线性回归模型数据集
# data_arrays:特征集合和标签集合组成的元组,形式为(特征集合,标签集合)
# batch_size:批量大小
# is_train:是否打乱
def load_array(data_arrays, batch_size, is_train=True): #@save
"""构造一个PyTorch数据迭代器"""
# 将数据集按照特征和数据的对应关系进行封装
dataset = data.TensorDataset(*data_arrays)
# 将数据集打乱,然后按照批量大小进行切割和封装,
return data.DataLoader(dataset, batch_size, shuffle=is_train)
# 定义批量大小
batch_size = 10
# 获取经过按照批量大小进行切割和封装过的数据集,可迭代读取,每次迭代读取出一个批量的数据(特征+对应的标签)
data_iter = load_array((features, labels), batch_size)
3.3.4 定义网络模型
# 模型中只有一个全连接层,全连接层的输入为两个维度,输出为一个维度,即两个输入一个输出的模型
net = nn.Sequential(nn.Linear(2, 1))
3.3.5 初始化模型参数
# 将模型第一层的权重按照均值为0,方差为0.01的正态分布来随机初始化
net[0].weight.data.normal_(0, 0.01)
print(net[0].weight.data.normal_(0, 0.01))
# 输出:
# tensor([[ 0.0189, -0.0105]])
# 将模型第一层的偏移量初始化为0
net[0].bias.data.fill_(0)
print(net[0].bias.data.fill_(0))
# 输出:
# tensor([0.])
3.3.6 定义损失函数
# 定义均方损失函数
loss = nn.MSELoss()
3.3.7 定义优化器
# 定义随机梯度下降算法
trainer = torch.optim.SGD(net.parameters(), lr=0.03)
3.3.8 训练过程
# 设置训练轮数
num_epochs = 3
for epoch in range(num_epochs):
# 每一轮的训练过程
for X, y in data_iter:
# X代表一个批量的特征集合,y代表对应的标签集合
# 计算模型预测标签和真实标签之间的均方损失
l = loss(net(X) ,y)
# 使用优化器进行优化,并更新权重和偏移量
trainer.zero_grad()
l.backward()
trainer.step()
# 用经过一轮训练之后得到的权重和偏移量来计算在整个数据集上预测标签和真实标签之间的损失
l = loss(net(features), labels)
# 打印本次的损失均值
print(f'epoch {epoch + 1}, loss {l:f}')
# 输出:
# epoch 1, loss 0.000497
# epoch 2, loss 0.000104
# epoch 3, loss 0.000104
本小节完整代码如下
import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2l
from torch import nn
# ------------------------------制作线性回归模型数据集------------------------------------
# 定义真实的权重参数
true_w = torch.tensor([2, -3.4])
# 定义真实的偏移量
true_b = 4.2
# 生成数据集,features为特征集合,labels为标签集合,数据集大小为1000
features, labels = d2l.synthetic_data(true_w, true_b, 1000)
# ------------------------------DataLoader的详细使用说明------------------------------------
from torch.utils.data import TensorDataset
import torch
from torch.utils.data import DataLoader
# 定义a为特征集合
a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 定义b为标签集合
b = torch.tensor([44, 55, 66, 44, 55, 66, 44, 55, 66, 44, 55, 66])
# 将数据集按照特征和数据的对应关系进行封装
train_ids = TensorDataset(a, b)
# 输出其中的一部分特征以及其对应的标签
print(train_ids[0:2])
# 输出:(第一个tensor为特征,第二个tensor为标签)
# (tensor([[1, 2, 3],
# [4, 5, 6]]), tensor([44, 55]))
# 循环度取特征以及对应的标签
for x_train, y_label in train_ids:
print(x_train, y_label)
# 输出:
# tensor([1, 2, 3]) tensor(44)
# tensor([4, 5, 6]) tensor(55)
# tensor([7, 8, 9]) tensor(66)
# tensor([1, 2, 3]) tensor(44)
# tensor([4, 5, 6]) tensor(55)
# tensor([7, 8, 9]) tensor(66)
# tensor([1, 2, 3]) tensor(44)
# tensor([4, 5, 6]) tensor(55)
# tensor([7, 8, 9]) tensor(66)
# tensor([1, 2, 3]) tensor(44)
# tensor([4, 5, 6]) tensor(55)
# tensor([7, 8, 9]) tensor(66)
# 将数据集按照批量大小进行切割和封装
train_loader = DataLoader(dataset=train_ids, batch_size=4, shuffle=True)
# 将数据(特征和对应的标签)按照批量大小读取出来
for i, data in enumerate(train_loader, 1): # 注意enumerate返回值有两个,一个是序号,一个是数据(包含训练数据和标签)
x_data, label = data
print(' batch:{0} x_data:{1} label: {2}'.format(i, x_data, label))
# 输出:
# batch:1 x_data:tensor([[7, 8, 9],
# [7, 8, 9],
# [4, 5, 6],
# [4, 5, 6]]) label: tensor([66, 66, 55, 55])
#
# batch:2 x_data:tensor([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9],
# [1, 2, 3]]) label: tensor([44, 55, 66, 44])
#
# batch:3 x_data:tensor([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9],
# [1, 2, 3]]) label: tensor([44, 55, 66, 44])
# ------------------------------读取线性回归模型数据集------------------------------------
# data_arrays:特征集合和标签集合组成的元组,形式为(特征集合,标签集合)
# batch_size:批量大小
# is_train:是否打乱
def load_array(data_arrays, batch_size, is_train=True): #@save
"""构造一个PyTorch数据迭代器"""
# 将数据集按照特征和数据的对应关系进行封装
dataset = data.TensorDataset(*data_arrays)
# 将数据集打乱,然后按照批量大小进行切割和封装,
return data.DataLoader(dataset, batch_size, shuffle=is_train)
# 定义批量大小
batch_size = 10
# 获取经过按照批量大小进行切割和封装过的数据集,可迭代读取,每次迭代读取出一个批量的数据(特征+对应的标签)
data_iter = load_array((features, labels), batch_size)
# ------------------------------定义网络模型------------------------------------
# 模型中只有一个全连接层,全连接层的输入为两个维度,输出为一个维度,即两个输入一个输出的模型
net = nn.Sequential(nn.Linear(2, 1))
# ------------------------------初始化模型参数------------------------------------
# 将模型第一层的权重按照均值为0,方差为0.01的正态分布来随机初始化
net[0].weight.data.normal_(0, 0.01)
print(net[0].weight.data.normal_(0, 0.01))
# 输出:
# tensor([[ 0.0189, -0.0105]])
# 将模型第一层的偏移量初始化为0
net[0].bias.data.fill_(0)
print(net[0].bias.data.fill_(0))
# 输出:
# tensor([0.])
# ------------------------------定义损失函数------------------------------------
# 定义均方损失函数
loss = nn.MSELoss()
# ------------------------------定义优化器------------------------------------
# 定义随机梯度下降算法
trainer = torch.optim.SGD(net.parameters(), lr=0.03)
# ------------------------------训练过程------------------------------------
# 设置训练轮数
num_epochs = 3
for epoch in range(num_epochs):
# 每一轮的训练过程
for X, y in data_iter:
# X代表一个批量的特征集合,y代表对应的标签集合
# 计算模型预测标签和真实标签之间的均方损失
l = loss(net(X) ,y)
# 使用优化器进行优化,并更新权重和偏移量
trainer.zero_grad()
l.backward()
trainer.step()
# 用经过一轮训练之后得到的权重和偏移量来计算在整个数据集上预测标签和真实标签之间的损失
l = loss(net(features), labels)
# 打印本次的损失均值
print(f'epoch {epoch + 1}, loss {l:f}')
# 输出:
# epoch 1, loss 0.000497
# epoch 2, loss 0.000104
# epoch 3, loss 0.000104
浙公网安备 33010602011771号