1. 说明
我们希望构建一个神经网络,这个神经网络可以在接受4个值来预测随后的第5个值,达到预测序列的作用。
- [ x 1 , x 2 , x 3 , x 4 ] [x_1,x_2,x_3,x_4] [x1,x2,x3,x4] -> [ x 5 ] [x_5] [x5]
- [ x 2 , x 3 , x 4 , x 5 ] [x_2,x_3,x_4,x_5] [x2,x3,x4,x5] -> [ x 6 ] [x_6] [x6]
-
[
x
3
,
x
4
,
x
5
,
x
6
]
[x_3,x_4,x_5,x_6]
[x3,x4,x5,x6] ->
[
x
7
]
[x_7]
[x7]
2. 代码
# -*- coding: utf-8 -*-
# @Project: zc
# @Author: ZhangChu
# @File name: sinx_test
# @Create time: 2022/1/12 21:32
# 1. 导入相关数据库
import torch
import matplotlib.pyplot as plt
from d2l import torch as d2l
from torch import nn
# 2.定义原始数据值
T = 1000
x = torch.arange(1, T + 1, dtype=torch.float32)
cos_x = torch.sin(x * 0.01) + torch.normal(0, 0.2, (T,))
d2l.plot(x, [cos_x], xlabel="x", ylabel="y", xlim=[1, 1000], figsize=(6, 3))
# plt.show()
# 3. 定义训练样本(features,label)
# (features=[x_1,x_2,x_3,x_4],labels=[x_5])
tau = 4
# features.shape =(994,4)
features = torch.zeros((T - tau, tau))
for i in range(tau):
# 按列填充值;
# cos_x[0:996]赋值features给第0列
# cos_x[1:997]赋值features给第1列
# cos_x[2:998]赋值features给第2列
# cos_x[3:999]赋值features给第3列
features[:, i] = cos_x[i:T - tau + i]
# 将 cos_x[4:]以后的值作为标签
# 因为我们将使用 [x_1,x_2,x_3,x_4] 去预测 [x_5]
labels = cos_x[tau:].reshape((-1, 1))
# 这样就可以得到每4个数据配1个标签的数据对(features,labels)=([1,2,3,4],[5])
batch_size, n_train = 16, 600
# 4.定义训练迭代器
# features[996,4];labels[996,1],取前600个转换成训练对
# (list_features,list_labels) -> datasets -> dataloader
train_iter = d2l.load_array((features[:n_train], labels[:n_train]),
batch_size, is_train=True)
# 5.神经网络权重初始化
# 全连接层的权重初始化,方便网络训练
def init_weights(m):
if type(m) == nn.Linear:
nn.init.xavier_uniform_(m.weight)
# 6.全连接层神经网络搭建
def get_net():
net = nn.Sequential(nn.Linear(4, 10),
nn.ReLU(),
nn.Linear(10, 1))
net.apply(init_weights)
return net
# 7.定义损失函数
loss = nn.MSELoss(reduction='none')
# 8.网络训练
def train(net, train_iter, loss, epochs, lr):
"""
神经网络训练
:param net: 神经网络定义
:param train_iter: 定义训练迭代器
:param loss: 损失函数
:param epochs: 训练次数
:param lr: 学习率
:return:
"""
# 定义优化器,传入网络参数和学习率
trainer = torch.optim.Adam(net.parameters(), lr)
# 开始训练
for epoch in range(epochs):
# 从训练集中拿到 x,y
for X, y in train_iter:
# 优化器梯度清零
trainer.zero_grad()
# 计算损失
l = loss(net(X), y)
# 损失梯度回传
l.sum().backward()
# 优化器更新
trainer.step()
print(f'epoch{epoch + 1};'
f'loss:{d2l.evaluate_loss(net, train_iter, loss):f}')
# 9.获取神经网络
net = get_net()
# 10.开始训练
train(net, train_iter, loss, 5, 0.01)
# 11.开始预测
onestep_preds = net(features)
# 12.将原始数据和预测数据显示出来
d2l.plot([x, x[tau:]],
[cos_x.detach().numpy(), onestep_preds.detach().numpy()], 'x',
'y', legend=['data', '1-step preds'], xlim=[1, 1000],
figsize=(6, 3))
plt.show()