赞
踩
import torch from torch import nn from d2l import torch as d2l import matplotlib.pyplot as plt T = 1000 # 总共产生1000个点 time = torch.arange(1, T + 1, dtype=torch.float32) x = torch.sin(0.01 * time) + torch.normal(mean=0, std=0.2, size=(T,)) d2l.plot(time, [x], 'time', 'x', xlim=[1, 1000], figsize=(6, 3)) plt.show() tau = 4 features = torch.zeros((T - tau, tau)) # torch.Size([996, 4]) for i in range(tau): # features 矩阵的每一行将包含时间序列中连续 tau 个时间步的数据 features[:, i] = x[i: T - tau + i] """ x = [x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, ...] features = [ [x0, x1, x2, x3], [x1, x2, x3, x4], [x2, x3, x4, x5], [x3, x4, x5, x6], [x4, x5, x6, x7], [x5, x6, x7, x8], ... ] """ labels = x[tau:].reshape((-1, 1)) batch_size, n_train = 16, 600 # 只有前n_train个样本用于训练 train_iter = d2l.load_array((features[:n_train], labels[:n_train]), batch_size, is_train=True) # 初始化网络权重的函数 def init_weights(m): if type(m) == nn.Linear: nn.init.xavier_uniform_(m.weight) # 一个简单的多层感知机 def get_net(): net = nn.Sequential(nn.Linear(4, 10), nn.ReLU(), nn.Linear(10, 1)) net.apply(init_weights) return net # 平方损失。注意:MSELoss计算平方误差时不带系数1/2 loss = nn.MSELoss(reduction='none') def train(net, train_iter, loss, epochs, lr): trainer = torch.optim.Adam(net.parameters(), lr) for epoch in range(epochs): 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}') net = get_net() train(net, train_iter, loss, 10, 0.01) # epoch 8, loss: 0.044640 # epoch 9, loss: 0.045863 # epoch 10, loss: 0.045066 # 单步预测 onestep_preds = net(features) #对输入特征 features 进行单步预测。 d2l.plot([time, time[tau:]], [x.detach().numpy(), onestep_preds.detach().numpy()], 'time', 'x', legend=['data', '1-step preds'], xlim=[1, 1000], figsize=(6, 3)) """ [time, time[tau:]]:表示 x 轴的数据。time 是完整的时间序列,time[tau:] 是从第 tau 个时间步开始的时间序列,长度为 T - tau。 [x.detach().numpy(), onestep_preds.detach().numpy()]: 表示 y 轴的数据。x 是实际的时间序列数据,onestep_preds 是神经网络的预测结果。 使用 detach().numpy() 将 PyTorch 张量转换为 NumPy 数组,以便绘图函数可以处理。 'time':x 轴的标签,表示时间。 'x':y 轴的标签,表示时间序列数据的值。 legend=['data', '1-step preds']:图例,分别标记实际数据和单步预测。 xlim=[1, 1000]:设置 x 轴的范围,从 1 到 1000。 figsize=(6, 3):设置图的大小,宽度为 6 英寸,高度为 3 英寸。 """ plt.show() # 多步预测 multistep_preds = torch.zeros(T) # 用于存储多步预测的结果 multistep_preds[: n_train + tau] = x[: n_train + tau] # 将 x 的前 n_train + tau 个元素复制到 multistep_preds 的对应位置。 # 这样做是为了在进行多步预测之前,保留训练集和前 tau 个时间步的数据。 for i in range(n_train + tau, T): # 从 n_train + tau 开始到 T,逐步进行预测。 multistep_preds[i] = net( multistep_preds[i - tau:i].reshape((1, -1))) d2l.plot([time, time[tau:], time[n_train + tau:]], [x.detach().numpy(), onestep_preds.detach().numpy(), multistep_preds[n_train + tau:].detach().numpy()], 'time', 'x', legend=['data', '1-step preds', 'multistep preds'], xlim=[1, 1000], figsize=(6, 3)) plt.show() # 生成特征矩阵进行多步预测 max_steps = 64 # 最大预测步数为64 features = torch.zeros((T - tau - max_steps + 1, tau + max_steps)) # tau 列是时间序列 x 的观测数据,而后 max_steps 列是基于前面列的预测结果。 # 列i(i<tau)是来自x的观测,其时间步从(i)到(i+T-tau-max_steps+1) for i in range(tau): features[:, i] = x[i: i + T - tau - max_steps + 1] # 列i(i>=tau)是来自(i-tau+1)步的预测,其时间步从(i)到(i+T-tau-max_steps+1) for i in range(tau, tau + max_steps): features[:, i] = net(features[:, i - tau:i]).reshape(-1) steps = (1, 4, 16, 64) d2l.plot([time[tau + i - 1: T - max_steps + i] for i in steps], [features[:, (tau + i - 1)].detach().numpy() for i in steps], 'time', 'x', legend=[f'{i}-step preds' for i in steps], xlim=[5, 1000], figsize=(6, 3)) plt.show() """ 1-step 预测:每一步预测只预测下一个时间步的数据。模型每次使用的是最近的观测数据进行预测。 4-step 预测:每一步预测预测接下来的四个时间步的数据。模型需要预测四步后的数据。 16-step 预测:每一步预测预测接下来的十六个时间步的数据。模型需要预测更远的未来数据。 64-step 预测:每一步预测预测接下来的六十四个时间步的数据。模型需要预测很远的未来数据。 """
单步预测:
多步预测:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。