当前位置: 首页 > news >正文

时间序列预测模型实战案例(七)(TPA-LSTM)结合TPA注意力机制的LSTM实现多元预测

论文地址->TPA-LSTM论文地址

项目地址-> TPA-LSTM时间序列预测实战案例

本文介绍

本文通过实战案例讲解TPA-LSTM实现多元时间序列预测,在本文中所提到的TPA和LSTM分别是注意力机制和深度学习模型,通过将其结合到一起实现时间序列的预测,本文利用有关油温的数据集来进行训练模型,同时将模型保存到本地,进行加载实现多步长预测,本文所利用的数据集也可以替换成你个人的数据集来进行预测(修改个人的数据集的地方本文也进行了标注),同时本文会对TPA和LSTM分别进行概念的讲解帮助大家理解其中的运行机制原理(包括个人总结已经论文内容)。

LSTM介绍

在开始实战讲解之前先来简单理解一下LSTM,其原理在我的另一篇博客中已经详细的讲解过了,这里只是简单的回顾,如果大家想要更深入的理解可以观看我的另一篇博客,地址如下->时间序列预测模型实战案例(三)(LSTM)(Python)(深度学习)时间序列预测(包括运行代码以及代码讲解)

LSTM的概念 

LSTM(长短期记忆,Long Short-Term Memory)是一种用于处理序列数据的深度学习模型,属于循环神经网络(RNN)的一种变体,其使用一种类似于搭桥术结构的RNN单元。相对于普通的RNN,LSTM引入了门控机制,能够更有效地处理长期依赖和短期记忆问题,是RNN网络中最常使用的Cell之一,LSTM的网络结构图如下图所示。

TPA机制介绍

本文主要介绍的是TPA注意力机制,LSTM在之前的文章中已经介绍过了,下面先来介绍一下其工作原理。

TPA的概念

TPA(Temporal Pattern Attention)注意力机制是一种用于处理时间序列数据的注意力机制。它的工作原理是在传统的注意力机制的基础上引入了时间模式的概念,以更好地捕捉时间序列中的重要模式和特征。

TPA的的工作步骤

TPA注意力机制的主要步骤如下:

1. 输入数据准备:给定一个时间序列数据,将其表示为X = {x1, x2, ..., xt},其中xi表示时间i处的观测值。

2. 特征提取:通过使用卷积神经网络,从时间序列中提取特征。这些特征可以是局部模式、全局趋势等。

3. 时间模式编码:将提取的特征序列传递给时间模式编码器。时间模式编码器通过学习时间序列中的重要模式和特征,生成一个编码向量序列。

4. 注意力计算:在时间模式编码器的输出上应用注意力机制。传统的注意力机制计算注意力权重,用于选择与当前时间步相关的信息。而TPA注意力机制通过计算注意力权重,选择与当前时间步相关的重要时间模式。

5. 上下文向量生成:根据注意力权重和时间模式编码器的输出,计算上下文向量。上下文向量是根据选择的重要时间模式加权求和的结果。

6. 预测生成:将上下文向量与其他信息(例如隐藏状态)进行拼接,然后通过适当的操作(如矩阵乘法)生成最终的预测结果。

如果大家觉得文字的描述不够直观,我们来看下图通过分析图片的形式来理解其工作原理。

上图显示了TPA注意力机制从输入到输出的过程工作流程,其中h_{t}表示时间步t处RNN的隐藏状态。有k个长度为w1d CNN(注意是1维的并不像图像处理的2维或三维)滤波器,用不同颜色的矩形表示。然后,每个滤波器在m个隐藏状态特征上进行卷积,并生成一个具有m行和k列的矩阵H^{C}。接下来,评分函数通过与当前隐藏状态ht进行比较,为H^{C}的每一行计算一个权重。然后,权重进行归一化,H^{C}的行按照对应的权重进行加权求和,生成V_{t }。最后,我们将V_{t }h_{t}进行拼接,并进行矩阵乘法生成h_{t}^{'}用于创建最终的预测值。 

个人总结->TPA注意力机制的关键创新点在于引入了时间模式编码和基于时间模式的注意力计算。这使得模型能够更好地理解和捕捉时间序列数据中的重要模式和特征,从而提高预测性能。 

实战讲解

讲过上文中的简单介绍,大家对于LSTM和TPA机制应该有了一个简单的了解,本文是实战案例讲解,主要部分还是代码部分的应用,所以下面来进行实战案例的讲解。

项目结构构成 

先来看一下我们的文件目录结构构成。

其中main.py文件为程序入口,dataset.py文件为数据处理的一些操作,tpa-lstm.pyp文件定义了我们的模型结构,util.py为定义的一些工具包,checkpoints为模型文件的保存文件夹,ETTh1.csv文件为数据集。 

项目完整代码

为了方便讲解我把上面提到的几个代码先放到这里,文章的开头已经提供下载地址给大家了,如果大家不愿意下载可以按照项目结构构成复制即可。

main.py文件如下

import lightning.pytorch as pl
import matplotlib.pyplot as plt
import pandas as pd
from lightning.pytorch.callbacks import ModelCheckpoint
from dataset import ElectricityDataModule
from tpa_lstm import TPALSTMdata_df = pd.read_csv('ETTh1.csv', index_col=['date'])
num_features = data_df.shape[1]data_splits = {"train": 0.7,"val": 0.15,"predict": 0.15
}pred_horizon = 4elec_dm = ElectricityDataModule(dataset_splits=data_splits,batch_size=128,window_size=24,pred_horizon=pred_horizon,data_style="custom"
)run_name = f"{pred_horizon}ts-kbest30"hid_size = 64
n_layers = 1
num_filters = 3name = f'{run_name}-TPA-LSTM'
checkpoint_loss_tpalstm = ModelCheckpoint(dirpath=f"checkpoints/{run_name}/TPA-LSTM",filename=name,save_top_k=1,monitor="val/loss",mode="min"
)tpalstm_trainer = pl.Trainer(max_epochs=10,# accelerator='gpu',callbacks=[checkpoint_loss_tpalstm],strategy='auto',devices=1,# logger=wandb_logger_tpalstm
)tpa_lstm = TPALSTM(input_size=num_features,hidden_size=hid_size,output_horizon=pred_horizon,num_filters=num_filters,obs_len=24,n_layers=n_layers,lr=1e-3
)tpalstm_trainer.fit(tpa_lstm, elec_dm)elec_dm.setup("predict")
run_to_load = run_name
model_path = f"checkpoints/{run_to_load}/TPA-LSTM/{name}.ckpt"
tpa_lstm = TPALSTM.load_from_checkpoint(model_path)pred_dl = elec_dm.predict_dataloader()
y_pred = tpalstm_trainer.predict(tpa_lstm, pred_dl)batch_idx = 0
start = 0
end = 5
for i, batch in enumerate(pred_dl):if start <= i <= end:inputs, labels = batchX, ytrue = inputs[batch_idx][:, -1], labels[batch_idx].squeeze()ypred = y_pred[i][batch_idx].squeeze()X = X.cpu().numpy()ytrue = ytrue.cpu().numpy()ypred = ypred.cpu().numpy()plt.figure(figsize=(8, 4))plt.plot(range(0, 24), X, label="Input")plt.scatter(range(24, 24 + pred_horizon), ytrue, color='cornflowerblue', label="True-Value")plt.scatter(range(24, 24 + pred_horizon), ypred, marker="x", color='green', label="TPA-LSTM pred")plt.legend(loc="lower left")plt.savefig("preds")plt.show()elif i > end:break

dataset.py文件如下 ->

import math
import pandas as pd
import torch
from torch.utils.data import Dataset, DataLoader
import lightning.pytorch as plclass ElectricityDataset(Dataset):def __init__(self,mode,split_ratios,window_size,pred_horizon,data_style,):self.w_size = window_sizeself.pred_horizon = pred_horizonif data_style == "pca":self.raw_dataset = pd.read_csv('ETTh1.csv',index_col=['date'])elif data_style == "kbest":self.raw_dataset = pd.read_csv('ETTh1.csv',index_col=['date'])elif data_style == "custom":self.raw_dataset = pd.read_csv('ETTh1.csv',index_col=['date'])else:print("Invalid dataset type")self.raw_dataset = Noneself.train_frac = split_ratios['train']self.val_frac = split_ratios['val']self.test_frac = split_ratios['predict']self.train_lim = math.floor(self.train_frac * self.raw_dataset.shape[0]) self.val_lim = math.floor(self.val_frac * self.raw_dataset.shape[0]) + self.train_limif mode == "train":self.dataset = self.raw_dataset[:self.train_lim]if mode == "val":self.dataset = self.raw_dataset[self.train_lim:self.val_lim]if mode == "predict":self.dataset = self.raw_dataset[self.val_lim:]self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")data_array = self.dataset.values
#         self.X = torch.tensor(self.dataset[:, :-1], dtype=torch.float32).to(self.device)self.X = torch.tensor(data_array, dtype=torch.float32).to(self.device)self.y = torch.tensor(data_array[:, -1], dtype=torch.float32) \.unsqueeze(1).to(self.device)def __getitem__(self, idx):return (self.X[idx:idx + self.w_size, :], self.y[idx + self.w_size: idx + self.w_size + self.pred_horizon])def __len__(self):# TODO Check this is correctreturn len(self.dataset) - (self.w_size + self.pred_horizon)def get_input_size(self):return self.dataset.shape[1]class ElectricityDataModule(pl.LightningDataModule):def __init__(self,dataset_splits,batch_size=64,window_size=24,pred_horizon=1,data_style="pca"):super().__init__()self.batch_size = batch_sizeself.dataset_splits = dataset_splitsself.window_size = window_sizeself.pred_horizon = pred_horizonself.data_style=data_styledef setup(self, stage):if stage == "fit":self.data_train = ElectricityDataset(mode="train",split_ratios=self.dataset_splits,window_size=self.window_size,pred_horizon=self.pred_horizon,data_style=self.data_style)self.data_val = ElectricityDataset(mode="val",split_ratios=self.dataset_splits,window_size=self.window_size,pred_horizon=self.pred_horizon,data_style=self.data_style)elif stage == "predict":self.data_pred = ElectricityDataset(mode="predict",split_ratios=self.dataset_splits,window_size=self.window_size,pred_horizon=self.pred_horizon,data_style=self.data_style)def train_dataloader(self):return DataLoader(self.data_train, batch_size=self.batch_size, shuffle=False)def val_dataloader(self):return DataLoader(self.data_val, batch_size=self.batch_size, shuffle=False)def predict_dataloader(self):return DataLoader(self.data_pred, batch_size=self.batch_size, shuffle=False)

tpa_lstm.py文件如下-> 

import torch
from torch import nn, optim
import lightning.pytorch as plfrom util import RMSE, RSE, CORRdevice = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")class TPALSTM(pl.LightningModule):def __init__(self, input_size, output_horizon, num_filters, hidden_size, obs_len, n_layers, lr=1e-3):super(TPALSTM, self).__init__()self.hidden = nn.Linear(input_size, 24)self.relu = nn.ReLU()self.lstm = nn.LSTM(input_size, hidden_size, n_layers, \bias=True, batch_first=True)  # output (batch_size, obs_len, hidden_size)self.hidden_size = hidden_sizeself.filter_num = num_filtersself.filter_size = 1 # Don't change this - otherwise CNN filters no longer 1Dself.output_horizon = output_horizonself.attention = TemporalPatternAttention(self.filter_size, \self.filter_num, obs_len - 1, hidden_size)self.mlp_out = nn.Sequential(nn.Linear(hidden_size, hidden_size // 2),self.relu,nn.Dropout(p=0.2),nn.Linear(hidden_size // 2, output_horizon))self.linear = nn.Linear(hidden_size, output_horizon)self.n_layers = n_layersself.lr = lrself.criterion = nn.MSELoss()self.save_hyperparameters()def forward(self, x):batch_size, obs_len, f_dim = x.size()H = torch.zeros(batch_size, obs_len - 1, self.hidden_size).to(device)ht = torch.zeros(self.n_layers, batch_size, self.hidden_size).to(device)ct = ht.clone()for t in range(obs_len):xt = x[:, t, :].view(batch_size, 1, -1)out, (ht, ct) = self.lstm(xt, (ht, ct))htt = ht.permute(1, 0, 2)htt = htt[:, -1, :]if t != obs_len - 1:H[:, t, :] = httH = self.relu(H)# reshape hidden states HH = H.view(-1, 1, obs_len - 1, self.hidden_size)new_ht = self.attention(H, htt)ypred = self.linear(new_ht).unsqueeze(-1)
#         ypred = self.mlp_out(new_ht).unsqueeze(-1)return ypreddef training_step(self, batch, batch_idx):inputs, label = batch outputs = self.forward(inputs)loss = self.criterion(outputs, label)corr = CORR(outputs, label)rse = RSE(outputs, label)self.log("train/loss", loss, prog_bar=True, on_epoch=True, on_step=False)self.log("train/corr", corr, prog_bar=True, on_epoch=True, on_step=False)self.log("train/rse", rse, prog_bar=True, on_epoch=True, on_step=False)return lossdef validation_step(self, batch, batch_idx):inputs, label = batch outputs = self.forward(inputs)loss = self.criterion(outputs, label)corr = CORR(outputs, label)rse = RSE(outputs, label)self.log("val/loss", loss, prog_bar=True, on_epoch=True, on_step=False)self.log("val/corr", corr, prog_bar=True, on_epoch=True, on_step=False)self.log("val/rse", rse, prog_bar=True, on_epoch=True, on_step=False)def predict_step(self, batch, batch_idx):inputs, label = batch pred = self.forward(inputs)return preddef configure_optimizers(self):optimiser = optim.Adam(self.parameters(),lr=self.lr,amsgrad=False,
#             weight_decay=1e-4,)return optimiserclass TemporalPatternAttention(nn.Module):def __init__(self, filter_size, filter_num, attn_len, attn_size):super(TemporalPatternAttention, self).__init__()self.filter_size = filter_sizeself.filter_num = filter_numself.feat_size = attn_size - self.filter_size + 1self.conv = nn.Conv2d(1, filter_num, (attn_len, filter_size))self.linear1 = nn.Linear(attn_size, filter_num)self.linear2 = nn.Linear(attn_size + self.filter_num, attn_size)self.relu = nn.ReLU()def forward(self, H, ht):_, channels, _, attn_size = H.size()new_ht = ht.view(-1, 1, attn_size)w = self.linear1(new_ht)  # batch_size, 1, filter_numconv_vecs = self.conv(H)conv_vecs = conv_vecs.view(-1, self.feat_size, self.filter_num)conv_vecs = self.relu(conv_vecs)# score functionw = w.expand(-1, self.feat_size, self.filter_num)s = torch.mul(conv_vecs, w).sum(dim=2)alpha = torch.sigmoid(s)new_alpha = alpha.view(-1, self.feat_size, 1).expand(-1, self.feat_size, self.filter_num)v = torch.mul(new_alpha, conv_vecs).sum(dim=1).view(-1, self.filter_num)concat = torch.cat([ht, v], dim=1)new_ht = self.linear2(concat)return new_ht

util.py文件如下-> 

#!/usr/bin/python 3.6
#-*-coding:utf-8-*-'''
Utility functions
'''
import torch 
import numpy as np
import os
import randomdef get_data_path():folder = os.path.dirname(__file__)return os.path.join(folder, "data")def RSE(ypred, ytrue):if isinstance(ypred, np.ndarray):rse = np.sqrt(np.square(ypred - ytrue).sum()) / \np.sqrt(np.square(ytrue - ytrue.mean()).sum())else:rse = torch.sqrt(torch.square(ypred - ytrue).sum()) / \torch.sqrt(torch.square(ytrue - ytrue.mean()).sum())return rsedef RMSE(ypred, ytrue):return torch.sqrt(torch.mean(torch.sum(torch.square(ypred - ytrue), dim=1)))def CORR(ypred, ytrue):if isinstance(ypred, np.ndarray):vx = ypred - np.mean(ypred)vy = ytrue - np.mean(ytrue)return np.sum(vx * vy) / (np.sqrt(np.sum(vx ** 2)) * np.sqrt(np.sum(vy ** 2)))else:vx = ypred - torch.mean(ypred)vy = ytrue - torch.mean(ytrue)return torch.sum(vx * vy) / (torch.sqrt(torch.sum(vx ** 2)) * torch.sqrt(torch.sum(vy ** 2)))def quantile_loss(ytrue, ypred, qs):'''Quantile loss version 2Args:ytrue (batch_size, output_horizon)ypred (batch_size, output_horizon, num_quantiles)'''L = np.zeros_like(ytrue)for i, q in enumerate(qs):yq = ypred[:, :, i]diff = yq - ytrueL += np.max(q * diff, (q - 1) * diff)return L.mean()def SMAPE(ytrue, ypred):ytrue = np.array(ytrue).ravel()ypred = np.array(ypred).ravel() + 1e-4mean_y = (ytrue + ypred) / 2.return np.mean(np.abs((ytrue - ypred) \/ mean_y))def MAPE(ytrue, ypred):ytrue = np.array(ytrue).ravel() + 1e-4ypred = np.array(ypred).ravel()return np.mean(np.abs((ytrue - ypred) \/ ytrue))def train_test_split(X, y, train_ratio=0.7):num_ts, num_periods, num_features = X.shapetrain_periods = int(num_periods * train_ratio)random.seed(2)Xtr = X[:, :train_periods, :]ytr = y[:, :train_periods]Xte = X[:, train_periods:, :]yte = y[:, train_periods:]return Xtr, ytr, Xte, yteclass StandardScaler:def fit_transform(self, y):self.mean = np.mean(y)self.std = np.std(y) + 1e-4return (y - self.mean) / self.stddef inverse_transform(self, y):return y * self.std + self.meandef transform(self, y):return (y - self.mean) / self.stdclass MaxScaler:def fit_transform(self, y):self.max = np.max(y)return y / self.maxdef inverse_transform(self, y):return y * self.maxdef transform(self, y):return y / self.maxclass MeanScaler:def fit_transform(self, y):self.mean = np.mean(y)return y / self.meandef inverse_transform(self, y):return y * self.meandef transform(self, y):return y / self.meanclass LogScaler:def fit_transform(self, y):return np.log1p(y)def inverse_transform(self, y):return np.expm1(y)def transform(self, y):return np.log1p(y)def gaussian_likelihood_loss(z, mu, sigma):'''Gaussian Liklihood LossArgs:z (tensor): true observations, shape (num_ts, num_periods)mu (tensor): mean, shape (num_ts, num_periods)sigma (tensor): standard deviation, shape (num_ts, num_periods)likelihood: (2 pi sigma^2)^(-1/2) exp(-(z - mu)^2 / (2 sigma^2))log likelihood:-1/2 * (log (2 pi) + 2 * log (sigma)) - (z - mu)^2 / (2 sigma^2)'''negative_likelihood = torch.log(sigma + 1) + (z - mu) ** 2 / (2 * sigma ** 2) + 6return negative_likelihood.mean()def negative_binomial_loss(ytrue, mu, alpha):'''Negative Binomial SampleArgs:ytrue (array like)mu (array like)alpha (array like)maximuze log l_{nb} = log Gamma(z + 1/alpha) - log Gamma(z + 1) - log Gamma(1 / alpha)- 1 / alpha * log (1 + alpha * mu) + z * log (alpha * mu / (1 + alpha * mu))minimize loss = - log l_{nb}Note: torch.lgamma: log Gamma function'''batch_size, seq_len = ytrue.size()likelihood = torch.lgamma(ytrue + 1. / alpha) - torch.lgamma(ytrue + 1) - torch.lgamma(1. / alpha) \- 1. / alpha * torch.log(1 + alpha * mu) \+ ytrue * torch.log(alpha * mu / (1 + alpha * mu))return - likelihood.mean()def batch_generator(X, y, num_obs_to_train, seq_len, batch_size):'''Args:X (array like): shape (num_samples, num_features, num_periods)y (array like): shape (num_samples, num_periods)num_obs_to_train (int):seq_len (int): sequence/encoder/decoder lengthbatch_size (int)'''num_ts, num_periods, _ = X.shapeif num_ts < batch_size:batch_size = num_tst = random.choice(range(num_obs_to_train, num_periods-seq_len))batch = random.sample(range(num_ts), batch_size)X_train_batch = X[batch, t-num_obs_to_train:t, :]y_train_batch = y[batch, t-num_obs_to_train:t]Xf = X[batch, t:t+seq_len]yf = y[batch, t:t+seq_len]return X_train_batch, y_train_batch, Xf, yf

项目网络结构

本项目的网络结构图如下所示在控制台输出了大家如果想要修改可以在其中的对应的位置添加或删除都可以。

代码讲解

训练部分

我们首先来看main.py文件我也只会讲解这一个文件,(因为代码很多,如果大家有需要我后期会出视频带着大家过一遍其中的代码),;

main.py文件的内容不是很多,首先最上面的模块导入部分,我不讲解了,前面有我应用的版本,大家如果有一些版本报错的话可以参考。

data_df = pd.read_csv('ETTh1.csv', index_col=['date'])
num_features = data_df.shape[1]

这两行代码就是数据的读取操作,以及获取数据的特征数,因为我们是多元预测,数据肯定不只一列,所以我们要告诉模型我们的输入有多少列模型好做多少列的预测。

data_splits = {"train": 0.7,"val": 0.15,"predict": 0.15
}

这几行是数据集的一个划分,大家应该都明白。这里训练集划分为模型的0.7、验证集为0.15、测试集为0.15。

pred_horizon = 4

这个参数就是你预测未来数据的长度,假设你数据集的时间是按照小时来划分,那么如果输入4就是未来四小时的一个情况。 

elec_dm = ElectricityDataModule(dataset_splits=data_splits,batch_size=128,window_size=24,pred_horizon=pred_horizon,data_style="custom"
)

这个部分是一个数据加载器定义的一个过程,其中我们的data_splits上面讲过了,batch_size就是你往模型里面一次输入的数据长度,window_size是你用多少条数据预测未来一条数据,pred_horizon上面也讲过了,custom是你数据加载器定义的形式这里大家不用理会。 

hid_size = 64
n_layers = 1
num_filters = 3

这三个参数是定义模型的参数,其中hid_size是隐藏层的单元数如果不理解可以看前面提到的LSTM讲解博客,n_layers是其中LSTM的层数,num_filters是TPA注意力机制中卷积的一个形状。 

name = f'{run_name}-TPA-LSTM'
checkpoint_loss_tpalstm = ModelCheckpoint(dirpath=f"checkpoints/{run_name}/TPA-LSTM",filename=name,save_top_k=1,monitor="val/loss",mode="min"
)

这一部分是模型保存部分不进行讲解了,大家有兴趣可以自己debug看看就是保存模型文件。

tpalstm_trainer = pl.Trainer(max_epochs=10,# accelerator='gpu',callbacks=[checkpoint_loss_tpalstm],strategy='auto',devices=1,# logger=wandb_logger_tpalstm
)

这一部分定义了一些训练中的参数,其中max_epochs就是训练10轮的意思。

tpa_lstm = TPALSTM(input_size=num_features,hidden_size=hid_size,output_horizon=pred_horizon,num_filters=num_filters,obs_len=24,n_layers=n_layers,lr=1e-3
)

这一部分就是定义的一些参数前面定义的全部输入到模型里面。

tpalstm_trainer.fit(tpa_lstm, elec_dm)

这个就是模型训练的操作,执行到这里模型就开始训练了。 

预测部分 

上一小节讲解的是训练的过程,现在开始详解预测的过程,代码也是在main.py文件中。

elec_dm.setup("predict")
run_to_load = run_name
model_path = f"checkpoints/{run_to_load}/TPA-LSTM/{name}.ckpt"
tpa_lstm = TPALSTM.load_from_checkpoint(model_path)

我们先选择预测模式,然后下载上一小节训练的模型,

pred_dl = elec_dm.predict_dataloader()
y_pred = tpalstm_trainer.predict(tpa_lstm, pred_dl)

这一部分就是进行预测,其中第一行为数据加载器,如果大家感兴趣可以看看dataset.py文件其中有注释。然后我们调用了前面加载的模型其中的predict方法进行预测 ,运行之后我们的预测结果就保存到了y_pred中了已经。

结果分析 

batch_idx = 0
start = 0
end = 5
for i, batch in enumerate(pred_dl):if start <= i <= end:inputs, labels = batchX, ytrue = inputs[batch_idx][:, -1], labels[batch_idx].squeeze()ypred = y_pred[i][batch_idx].squeeze()X = X.cpu().numpy()ytrue = ytrue.cpu().numpy()ypred = ypred.cpu().numpy()plt.figure(figsize=(8, 4))plt.plot(range(0, 24), X, label="Input")plt.scatter(range(24, 24 + pred_horizon), ytrue, color='cornflowerblue', label="True-Value")plt.scatter(range(24, 24 + pred_horizon), ypred, marker="x", color='green', label="TPA-LSTM pred")plt.legend(loc="lower left")plt.savefig("preds")plt.show()elif i > end:break

这一部分就是画图功能了,最后我们预测结果全部会以图片的形式输出出来,因为我输入的数据形状是7列这里就生成了七张图片,如下所示->

 总结

 到此本文就全部讲解结束了,希望能够帮助大家,最后推荐几篇我的其它时间序列实战案例

  其它时间序列预测模型的讲解!

时间序列预测模型实战案例(六)深入理解机器学习ARIMA包括差分和相关性分析

时间序列预测模型实战案例(五)基于双向LSTM横向搭配单向LSTM进行回归问题解决

时间序列预测模型实战案例(四)(Xgboost)(Python)(机器学习)图解机制原理实现时间序列预测和分类(附一键运行代码资源下载和代码讲解)

时间序列预测模型实战案例(三)(LSTM)(Python)(深度学习)时间序列预测(包括运行代码以及代码讲解)

【全网首发】(MTS-Mixers)(Python)(Pytorch)最新由华为发布的时间序列预测模型实战案例(一)(包括代码讲解)实现企业级预测精度包括官方代码BUG修复Transform模型

时间序列预测模型实战案例(二)(Holt-Winter)(Python)结合K-折交叉验证进行时间序列预测实现企业级预测精度(包括运行代码以及代码讲解)

如果大家有不懂的也可以评论区留言一些报错什么的大家可以讨论讨论看到我也会给大家解答如何解决!

相关文章:

时间序列预测模型实战案例(七)(TPA-LSTM)结合TPA注意力机制的LSTM实现多元预测

论文地址->TPA-LSTM论文地址 项目地址-> TPA-LSTM时间序列预测实战案例 本文介绍 本文通过实战案例讲解TPA-LSTM实现多元时间序列预测&#xff0c;在本文中所提到的TPA和LSTM分别是注意力机制和深度学习模型,通过将其结合到一起实现时间序列的预测&#xff0c;本文利用…...

Mysql多表设计

前言 多表查询中要给每一表起别名 tableA as 别名1 , tableB as 别名2 ; &#xff08;111111推荐&#xff09; tableA 别名1 , tableB 别名2 ; 例子&#xff1a; select emp.name , dept.name from tb_emp emp inner join tb_dept dept on emp.dept_id dept.id; 一对一 在任…...

第九章:最新版零基础学习 PYTHON 教程—Python 元组(第五节 -清除元组的5种方式方法)

有时,在处理记录数据时,我们可能会遇到需要执行数据记录清除的问题。元组是不可变的,无法修改,因此使这项工作变得困难。让我们讨论执行此任务的某些方法。 目录 方法 #1:使用 list() + clear() + tuple() 方法#2:使用 tuple() 重新初始化...

学习笔记4——JVM运行时数据区梳理

学习笔记系列开头惯例发布一些寻亲消息 链接&#xff1a;https://baobeihuijia.com/bbhj/contents/3/192489.html 类装载器classLoader&#xff1a; 将本地的字节码文件.class 加载到内存方法区中成为元数据模板&#xff08;两个class对象是否为同一个类要求&#xff1a;完整…...

Splunk 创建特色 dashboard 报表

1: 背景: 对原有的dashboard 进行增加点东西,特别是文字部分: 比如: 增加:“this is a guidline for how to use performance". 这段话,就不能写在title, 那样,这段文字,会出现在dashboard 的PDF 文件的分割线的上面,不符合要求。 2: 解决问题: 正确的做法是…...

如何在校园跑腿系统小程序中构建稳健的订单处理与分配系统?

1. 数据库设计 首先&#xff0c;设计订单数据结构。使用数据库&#xff08;例如MySQL、MongoDB等&#xff09;&#xff0c;创建订单表以存储订单相关信息&#xff0c;包括订单ID、用户信息、交付地址、订单状态等。 CREATE TABLE orders (order_id INT AUTO_INCREMENT PRIMAR…...

数据结构与算法—双链表

前言 前面有很详细的讲过线性表(顺序表和链表)&#xff0c;当时讲的链表以单链表为主&#xff0c;但在实际应用中双链表有很多应用场景&#xff0c;例如大家熟知的LinkedList。 双链表与单链表区别 单链表和双链表都是线性表的链式实现&#xff0c;它们的主要区别在于节点结构…...

linux继续循环案例测试ping网络,目录下的文件权限循环输出

第一&#xff1a;查看本机ip #ip addr 通过脚本访问本机ip1-100&#xff0c;是否可以ping通&#xff0c;并显示结果&#xff0c;上图 知识点 ping -c 数字1 -w 数字1&#xff0c;向目的ip发送1个数据包&#xff0c;等待1秒&#xff0c;无回复中止 &>/dev/null 知…...

关于SSP3D复现

关于SSP3D复现的问题 准备工作 下载Xshell和XFTP&#xff1a;家校免费版下载链接连接服务器&#xff08;可能需要与服务器处在相同网络下&#xff09;GitHub上下载源码&#xff1a;SSP3D 左上角新建会话&#xff0c;输入名称和主机 点击左侧菜单“用户身份验证”&#xff0c…...

在直播系统中使用RTSP协议传递视频

目录 概述 1、环境准备 2、拉流URL地址 3、导播软件取流 &#xff08;1&#xff09;OBS中拉取RTSP流 &#xff08;2&#xff09;芯象中拉取RTSP流 &#xff08;3&#xff09;vMix中拉取RTSP流 写在最后 概述 提到RTSP协议&#xff0c;很容易想到RTMP协议&#xff0c;它…...

Notion汉化

Notion真无语&#xff0c;汉化版都没有。真的无力吐槽。 2023.11.7汉化经历 教程链接&#xff1a;github Reamd7/notion-zh_CN at 2.4.20-handmade (github.com) 网页版&#xff1a; 油猴下载插件。 Notion中文汉化 浏览器插件下载 windows&#xff1a; github realse 这…...

echarts有背景的柱状图,鼠标滑过提示信息都是展示背景柱状图的值

// 上一篇文章介绍了如何实现有背景的柱状图&#xff0c;现在又遇到一个问题&#xff0c;鼠标滑过柱子&#xff0c;提示信息是背景柱子的值&#xff0c;解决方案&#xff0c;自定义tooltip的formatter&#xff0c;上代码tooltip: {//鼠标悬浮提示数据formatter: function (para…...

华为防火墙基本原理工作方法总结

防火墙只会对tcp首包syn建立会话表&#xff0c;其它丢掉&#xff0c;如synack&#xff0c;ack udp直接建立会话表 icmp只对首包请求包建立会话表&#xff0c;其它包&#xff0c;如应答的不会建立直接丢掉 防火墙状态查看&#xff1a; rule name trust_untrust source-zone tru…...

Spring Cloud之多级缓存

目录 传统缓存 多级缓存 JVM进程缓存 Caffeine 缓存驱逐策略 实现进程缓存 常用Lua语法 数据类型 变量声明 循环使用 定义函数 条件控制 安装OpenResty 实现Nginx业务逻辑编写 请求参数解析 实现lua访问tomcat JSON的序列化和反序列化 Tomcat的集群负载均衡 …...

融云荣登「2023 年度 PaaS 企业排行榜」

11 月 2 日&#xff0c;中国科学院旗下《互联网周刊》颁布“2023 年度 PaaS 企业排行榜”&#xff0c;融云荣登榜单。关注【融云全球互联网通信云】了解更多 根据中国信息通信研究院《云计算白皮书 2023》&#xff1a;2022 年&#xff0c;PaaS 增长强势&#xff0c;总收入 342 …...

YOLOv8轻量化模型:模型轻量化设计 | 轻量级可重参化EfficientRep| 来自YOLOv6思想

💡💡💡本文解决什么问题:在几乎不保证精度下降的前提下,轻量级模型创新设计 EfficientRep 在关键点检测任务中 | GFLOPs从9.6降低至8.5, mAP50从0.921下降至0.912,mAP50-95从0.697提升至0.779 YOLO轻量化模型专栏:http://t.csdnimg.cn/AeaEF 1.YOLOv6介绍 论文…...

【JavaSE】基础笔记 - 类和对象(下)

目录 1、this引用 1.1、为什么要有this引用 1.2、什么是this引用 1.3、 this引用的特性 2、 对象的构造及初始化 2.1、 如何初始化对象 2.2、构造方法 2.2.1、概念 2.2.2、特性 2.3、默认初始化 2.4、就地初始化 上篇&#xff1a;【JavaSE】基础笔记 - 类和对象&#…...

浅析刚入门Python初学者的注意事项

文章目录 一、注意你的Python版本1.print()函数2.raw_input()与input()3.比较符号&#xff0c;使用!替换<>4.repr函数5.exec()函数 二、新手常遇到的问题1、如何写多行程序&#xff1f;2、如何执行.py文件&#xff1f;3、and&#xff0c;or&#xff0c;not4、True和False…...

2023NOIP A层联测26 总结

T1 求 ∑ i 1 n ∑ j i n ( ⨁ k i j a k ) 2 \sum\limits_{i1}^n\sum\limits_{ji}^n\left(\bigoplus\limits_{ki}^{j}a_k\right)^2 i1∑n​ji∑n​(ki⨁j​ak​)2&#xff0c; n , a i ≤ 2 1 0 5 n,a_i\le2\times10^5 n,ai​≤2105。先转成前缀和&#xff0c;然后就没思…...

响应式编程-Project Reactor Mono 介绍

响应式编程-Project Reactor Mono 介绍 本文以Mono的角度来介绍Reactor编程&#xff0c;Flux的使用同理。 初体验 Web应用 controller 方法在Spring webmvc 和 Spring webFlux下Controller方法实现示例如下&#xff1a; Spring webmvc: GetMapping("/test1") …...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...