时间序列预测实战(二十四)PyTorch实现RNN进行多元和单元预测(附代码+数据集+完整解析)

时间序列预测(六)——循环神经网络(RNN) 前面有提到前馈神经网络,下图是两者的区别对比循环神经网络(Recurrent Neural Network,RNN)是一种专门用于处理序列数据的神经网络结构,它能够处理时间序列数据,并预测未来的数据变化趋势。RNN能够处理序列中的时间依赖性,因而非常适合时间序列预测。 阅读详情
AI摘要

本文介绍利用个人编写的架构进行RNN时间序列卷积建模,涵盖结果可视化等多种功能。阐述了RNN框架原理,介绍ETTh1.csv数据集,讲解参数,给出完整代码,展示训练模型和预测结果,包括未知数据、测试集等效果图,最后推荐时间序列专栏。

     


一、本文介绍

本篇文章给大家带来的是利用我个人编写的架构进行RNN时间序列卷积进行时间序列建模(专门为了时间序列领域新人编写的架构,简单且不同于市面上大家用GPT写的代码),包括结果可视化、支持单元预测、多元预测、模型拟合效果检测、预测未知数据、以及滚动长期预测功能。该结构是一个通用架构任何模型嵌入其中都可运行。下面来介绍一下RNN:循环神经网络(RNN)是深度学习中用于处理序列数据的一种基本网络结构。RNN的核心原理是它拥有一个循环结构,这使得网络能够保持一个内部的状态,从而捕捉到数据中随时间演变的信息。在RNN中,每个节点(或称为单元)在处理当前输入的同时,也会考虑前一时间步的隐藏状态。这种结构让RNN能够在时间序列分析、语言模型、文本生成等任务中建模数据中的时序依赖性,所以它可以用于时序预测,但是因为其存在导致梯度爆炸或者梯度消失的问题所以后来引出了LSTM,GRU等RNN模型。

  专栏目录:时间序列预测目录:深度学习、机器学习、融合模型、创新模型实战案例

专栏: 时间序列预测专栏:基础知识+数据分析+机器学习+深度学习+Transformer+创新模型

预测功能效果展示(不是测试集是预测未知数据,所以图中没有对比的数据)->

​

​

损失截图(损失这里我先展示一个训练过程中的后面会自动生成损失图像)-> 

根据损失来看模型的拟合效果还是很好的,但后面还是做了检验模型拟合效果的功能让大家真正的评估模型的效果。

​

测试集状况->

(从下面的图片可以看出模型在测试集的效果还可以,毕竟只是单一的RNN结构,为啥发单一因为我发现发高端或者融合的根本没人看) 

​

目录

一、本文介绍

二、RNN的框架原理

三、数据集介绍

四、参数讲解 

五、完整代码

六、训练模型 

七、预测结果

7.1 预测未知数据效果图

7.2 测试集效果图 

7.3 CSV文件生成效果图 

7.4 检验模型拟合效果图

八、全文总结


二、RNN的框架原理

循环神经网络(RNN)是一种专门用于处理序列数据的神经网络。它的主要思想是在处理序列的每个元素时,网络不仅考虑当前输入,还会考虑之前的信息。这使得RNN非常适合处理时间序列数据、语言模型等任务。

RNN的工作机制主要包括以下几点:

  1. 隐藏状态: RNN维护一个隐藏状态,它捕获到目前为止处理过的信息。
  2. 序列处理: 在处理序列的每个时间步时,RNN会更新其隐藏状态。
  3. 权重共享: 在不同时间步,RNN使用相同的权重,这减少了模型的复杂性并提高了训练效率。
  4. 输出: 根据任务的不同,RNN可以在每个时间步产生输出,或者仅在最后一个时间步产生输出。

总结来说,RNN之所以强大,是因为它能够利用序列数据的时间依赖性,通过维护一个在时间步之间传递的隐藏状态来实现这一点。这种结构使得RNN在处理诸如文本、语音等序列数据方面表现出色。然而,RNN也存在一定的局限性,比如难以处理长序列中的长期依赖问题,这通常通过引入LSTM或GRU等变体来解决。

下面的链接里包含了RNN系列的完整发展流程大家有兴趣的可以看看->

RNN发展流程:点击即可跳转

下面分享给大家两个LSTM和GRU的原理图吧,RNN实在没啥好说的,主要不发这些经典的文章还没人看。 

LSTM结构图-> 

GRU结构图-> 


三、数据集介绍

本文是实战讲解文章,上面主要是简单讲解了一下网络结构比较具体的流程还是很复杂的涉及到很多的数学计算,下面我们来讲一讲模型的实战内容,第一部分是我利用的数据集。

本文我们用到的数据集是ETTh1.csv,该数据集是一个用于时间序列预测的电力负荷数据集,它是 ETTh 数据集系列中的一个。ETTh 数据集系列通常用于测试和评估时间序列预测模型。以下是 ETTh1.csv 数据集的一些内容:

数据内容:该数据集通常包含有关电力系统的多种变量,如电力负荷、价格、天气情况等。这些变量可以用于预测未来的电力需求或价格。

时间范围和分辨率:数据通常按小时或天记录,涵盖了数月或数年的时间跨度。具体的时间范围和分辨率可能会根据数据集的版本而异。 

以下是该数据集的部分截图->

​


四、参数讲解 


    parser.add_argument('-model', type=str, default='RNN', help="模型持续更新")
    parser.add_argument('-window_size', type=int, default=126, help="时间窗口大小, window_size > pre_len")
    parser.add_argument('-pre_len', type=int, default=24, help="预测未来数据长度")
    # data
    parser.add_argument('-shuffle', action='store_true', default=True, help="是否打乱数据加载器中的数据顺序")
    parser.add_argument('-data_path', type=str, default='ETTh1-Test.csv', help="你的数据数据地址")
    parser.add_argument('-target', type=str, default='OT', help='你需要预测的特征列,这个值会最后保存在csv文件里')
    parser.add_argument('-input_size', type=int, default=7, help='你的特征个数不算时间那一列')
    parser.add_argument('-feature', type=str, default='M', help='[M, S, MS],多元预测多元,单元预测单元,多元预测单元')

    # learning
    parser.add_argument('-lr', type=float, default=0.001, help="学习率")
    parser.add_argument('-drop_out', type=float, default=0.05, help="随机丢弃概率,防止过拟合")
    parser.add_argument('-epochs', type=int, default=20, help="训练轮次")
    parser.add_argument('-batch_size', type=int, default=16, help="批次大小")
    parser.add_argument('-save_path', type=str, default='models')

    # model
    parser.add_argument('-hidden_size', type=int, default=64, help="隐藏层单元数")
    parser.add_argument('-kernel_sizes', type=int, default=3)
    parser.add_argument('-laryer_num', type=int, default=2)
    # device
    parser.add_argument('-use_gpu', type=bool, default=True)
    parser.add_argument('-device', type=int, default=0, help="只设置最多支持单个gpu训练")

    # option
    parser.add_argument('-train', type=bool, default=True)
    parser.add_argument('-test', type=bool, default=True)
    parser.add_argument('-predict', type=bool, default=True)
    parser.add_argument('-inspect_fit', type=bool, default=True)
    parser.add_argument('-lr-scheduler', type=bool, default=True)

为了大家方便理解,文章中的参数设置我都用的中文,所以大家应该能够更好的理解。下面我在进行一遍讲解。 

参数名称参数类型参数讲解
1modelstr模型名称
2window_sizeint时间窗口大小,用多少条数据去预测未来的数据

3

pre_lenint预测多少条未来的数据
4shufflestore_true是否打乱输入dataloader中的数据,不是数据的顺序

5

data_pathstr你输入数据的地址
6targetstr你想要预测的特征列

7

input_sizeint输入的特征数不包含时间那一列!!!

8

featurestr[M, S, MS],多元预测多元,单元预测单元,多元预测单元
9lrfloat学习率大小

10

drop_out

float丢弃概率
11epochsint训练轮次

12

batch_sizeint批次大小
13svae_pathstr模型的保存路径

14

hidden_sizeint隐藏层大小
15kernel_sizeint卷积核大小

16

layer_numintlstm层数
17use_gpubool是否使用GPU

18

deviceintGPU编号
19trainbool是否进行训练

20

predictbool是否进行预测

21

inspect_fitbool是否进行检验模型
22lr_schdulerbool是否使用学习率计划


五、完整代码

复制粘贴到一个文件下并且按照上面的从参数讲解配置好参数即可运行~(极其适合新手和刚入门的读者)

import argparse
import time

import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from matplotlib import pyplot as plt
from torch.nn.utils import weight_norm
from torch.utils.data import DataLoader
from torch.utils.data import Dataset
from tqdm import tqdm

# 随机数种子
np.random.seed(0)


class StandardScaler():
    def __init__(self):
        self.mean = 0.
        self.std = 1.

    def fit(self, data):
        self.mean = data.mean(0)
        self.std = data.std(0)

    def transform(self, data):
        mean = torch.from_numpy(self.mean).type_as(data).to(data.device) if torch.is_tensor(data) else self.mean
        std = torch.from_numpy(self.std).type_as(data).to(data.device) if torch.is_tensor(data) else self.std
        return (data - mean) / std

    def inverse_transform(self, data):
        mean = torch.from_numpy(self.mean).type_as(data).to(data.device) if torch.is_tensor(data) else self.mean
        std = torch.from_numpy(self.std).type_as(data).to(data.device) if torch.is_tensor(data) else self.std
        if data.shape[-1] != mean.shape[-1]:
            mean = mean[-1:]
            std = std[-1:]
        return (data * std) + mean


def plot_loss_data(data):
    # 使用Matplotlib绘制线图
    plt.figure()
    plt.figure(figsize=(10, 5))
    plt.plot(data, marker='o')

    # 添加标题
    plt.title("loss results Plot")

    # 显示图例
    plt.legend(["Loss"])

    plt.show()


class TimeSeriesDataset(Dataset):
    def __init__(self, sequences):
        self.sequences = sequences

    def __len__(self):
        return len(self.sequences)

    def __getitem__(self, index):
        sequence, label = self.sequences[index]
        return torch.Tensor(sequence), torch.Tensor(label)


def create_inout_sequences(input_data, tw, pre_len, config):
    # 创建时间序列数据专用的数据分割器
    inout_seq = []
    L = len(input_data)
    for i in range(L - tw):
        train_seq = input_data[i:i + tw]
        if (i + tw + pre_len) > len(input_data):
            break
        if config.feature == 'MS':
            train_label = input_data[:, -1:][i + tw:i + tw + pre_len]
        else:
            train_label = input_data[i + tw:i + tw + pre_len]
        inout_seq.append((train_seq, train_label))
    return inout_seq


def calculate_mae(y_true, y_pred):
    # 平均绝对误差
    mae = np.mean(np.abs(y_true - y_pred))
    return mae


def create_dataloader(config, device):
    print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>创建数据加载器<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
    df = pd.read_csv(config.data_path)  # 填你自己的数据地址,自动选取你最后一列数据为特征列 # 添加你想要预测的特征列
    pre_len = config.pre_len  # 预测未来数据的长度
    train_window = config.window_size  # 观测窗口

    # 将特征列移到末尾
    target_data = df[[config.target]]
    df = df.drop(config.target, axis=1)
    df = pd.concat((df, target_data), axis=1)

    cols_data = df.columns[1:]
    df_data = df[cols_data]

    # 这里加一些数据的预处理, 最后需要的格式是pd.series
    true_data = df_data.values

    # 定义标准化优化器
    # 定义标准化优化器
    scaler = StandardScaler()
    scaler.fit(true_data)

    train_data = true_data[int(0.3 * len(true_data)):]
    valid_data = true_data[int(0.15 * len(true_data)):int(0.30 * len(true_data))]
    test_data = true_data[:int(0.15 * len(true_data))]
    print("训练集尺寸:", len(train_data), "测试集尺寸:", len(test_data), "验证集尺寸:", len(valid_data))

    # 进行标准化处理
    train_data_normalized = scaler.transform(train_data)
    test_data_normalized = scaler.transform(test_data)
    valid_data_normalized = scaler.transform(valid_data)

    # 转化为深度学习模型需要的类型Tensor
    train_data_normalized = torch.FloatTensor(train_data_normalized).to(device)
    test_data_normalized = torch.FloatTensor(test_data_normalized).to(device)
    valid_data_normalized = torch.FloatTensor(valid_data_normalized).to(device)

    # 定义训练器的的输入
    train_inout_seq = create_inout_sequences(train_data_normalized, train_window, pre_len, config)
    test_inout_seq = create_inout_sequences(test_data_normalized, train_window, pre_len, config)
    valid_inout_seq = create_inout_sequences(valid_data_normalized, train_window, pre_len, config)

    # 创建数据集
    train_dataset = TimeSeriesDataset(train_inout_seq)
    test_dataset = TimeSeriesDataset(test_inout_seq)
    valid_dataset = TimeSeriesDataset(valid_inout_seq)

    # 创建 DataLoader
    train_loader = DataLoader(train_dataset, batch_size=args.batch_size, shuffle=True, drop_last=True)
    test_loader = DataLoader(test_dataset, batch_size=args.batch_size, shuffle=False, drop_last=True)
    valid_loader = DataLoader(valid_dataset, batch_size=args.batch_size, shuffle=False, drop_last=True)

    print("通过滑动窗口共有训练集数据:", len(train_inout_seq), "转化为批次数据:", len(train_loader))
    print("通过滑动窗口共有测试集数据:", len(test_inout_seq), "转化为批次数据:", len(test_loader))
    print("通过滑动窗口共有验证集数据:", len(valid_inout_seq), "转化为批次数据:", len(valid_loader))
    print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>创建数据加载器完成<<<<<<<<<<<<<<<<<<<<<<<<<<<")
    return train_loader, test_loader, valid_loader, scaler


class RNNs(nn.Module):
    """Model class to declare an rnn and define a forward pass of the model."""

    def __init__(self, input_size, output_size, hidden_size, num_layers, pred_len):

        """
         'rnn'
        """
        # inherit the nn.Module class via 'super'
        super(RNNs, self).__init__()

        # store stuff in the class
        self.pre_len = pred_len
        self.n_layers = num_layers
        self.hidden_size = hidden_size
        self.hidden = nn.Linear(input_size, self.hidden_size)
        self.relu = nn.ReLU()
        self.rnn = nn.RNN(self.hidden_size, self.hidden_size, num_layers, bias=True, batch_first=True)  # output (batch_size, obs_len, hidden_size)
        self.linear = nn.Linear(self.hidden_size, output_size)

    def forward(self, x):
        # rnn module expects data of shape [seq, batch_size, input_size]
        batch_size, obs_len, features_size = x.shape  # (batch_size, obs_len, features_size)
        xconcat = self.hidden(x)  # (batch_size, obs_len, hidden_size)
        H = torch.zeros(batch_size, obs_len - 1, self.hidden_size).to(device)  # (batch_size, obs_len-1, hidden_size)
        ht = torch.zeros(self.n_layers, batch_size, self.hidden_size).to(
            device)  # (num_layers, batch_size, hidden_size)
        for t in range(obs_len):
            xt = xconcat[:, t, :].view(batch_size, 1, -1)  # (batch_size, 1, hidden_size)
            out, ht = self.rnn(xt, ht)  # ht size (num_layers, batch_size, hidden_size)
            htt = ht[-1, :, :]  # (batch_size, hidden_size)
            if t != obs_len - 1:
                H[:, t, :] = htt
        H = self.relu(H)  # (batch_size, obs_len-1, hidden_size)
        x = self.linear(H)
        return x[:, -self.pre_len:, :]



def train(model, args, scaler, device):
    start_time = time.time()  # 计算起始时间
    model = model
    loss_function = nn.MSELoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=0.005)
    epochs = args.epochs
    model.train()  # 训练模式
    results_loss = []
    for i in tqdm(range(epochs)):
        losss = []
        for seq, labels in train_loader:
            optimizer.zero_grad()

            y_pred = model(seq)

            single_loss = loss_function(y_pred, labels)

            single_loss.backward()

            optimizer.step()
            losss.append(single_loss.detach().cpu().numpy())
        tqdm.write(f"\t Epoch {i + 1} / {epochs}, Loss: {sum(losss) / len(losss)}")
        results_loss.append(sum(losss) / len(losss))


        torch.save(model.state_dict(), 'save_model.pth')
        time.sleep(0.1)

    # valid_loss = valid(model, args, scaler, valid_loader)
    # 尚未引入学习率计划后期补上
    # 保存模型

    print(f">>>>>>>>>>>>>>>>>>>>>>模型已保存,用时:{(time.time() - start_time) / 60:.4f} min<<<<<<<<<<<<<<<<<<")
    plot_loss_data(results_loss)


def valid(model, args, scaler, valid_loader):
    lstm_model = model
    # 加载模型进行预测
    lstm_model.load_state_dict(torch.load('save_model.pth'))
    lstm_model.eval()  # 评估模式
    losss = []

    for seq, labels in valid_loader:
        pred = lstm_model(seq)
        mae = calculate_mae(pred.detach().numpy().cpu(), np.array(labels.detach().cpu()))  # MAE误差计算绝对值(预测值  - 真实值)
        losss.append(mae)

    print("验证集误差MAE:", losss)
    return sum(losss) / len(losss)


def test(model, args, test_loader, scaler):
    # 加载模型进行预测
    losss = []
    model = model
    model.load_state_dict(torch.load('save_model.pth'))
    model.eval()  # 评估模式
    results = []
    labels = []
    for seq, label in test_loader:
        pred = model(seq)
        mae = calculate_mae(pred.detach().cpu().numpy(),
                            np.array(label.detach().cpu()))  # MAE误差计算绝对值(预测值  - 真实值)
        losss.append(mae)
        pred = pred[:, 0, :]
        label = label[:, 0, :]
        pred = scaler.inverse_transform(pred.detach().cpu().numpy())
        label = scaler.inverse_transform(label.detach().cpu().numpy())
        for i in range(len(pred)):
            results.append(pred[i][-1])
            labels.append(label[i][-1])
    plt.figure(figsize=(10, 5))
    print("测试集误差MAE:", losss)
    # 绘制历史数据
    plt.plot(labels, label='TrueValue')

    # 绘制预测数据
    # 注意这里预测数据的起始x坐标是历史数据的最后一个点的x坐标
    plt.plot(results, label='Prediction')

    # 添加标题和图例
    plt.title("test state")
    plt.legend()
    plt.show()


# 检验模型拟合情况
def inspect_model_fit(model, args, train_loader, scaler):
    model = model
    model.load_state_dict(torch.load('save_model.pth'))
    model.eval()  # 评估模式
    results = []
    labels = []

    for seq, label in train_loader:
        pred = model(seq)[:, 0, :]
        label = label[:, 0, :]
        pred = scaler.inverse_transform(pred.detach().cpu().numpy())
        label = scaler.inverse_transform(label.detach().cpu().numpy())
        for i in range(len(pred)):
            results.append(pred[i][-1])
            labels.append(label[i][-1])
    plt.figure(figsize=(10, 5))
    # 绘制历史数据
    plt.plot(labels, label='History')

    # 绘制预测数据
    # 注意这里预测数据的起始x坐标是历史数据的最后一个点的x坐标
    plt.plot(results, label='Prediction')

    # 添加标题和图例
    plt.title("inspect model fit state")
    plt.legend()
    plt.show()


def predict(model, args, device, scaler):
    # 预测未知数据的功能
    df = pd.read_csv(args.data_path)
    df = df.iloc[:, 1:][-args.window_size:].values  # 转换为nadarry
    pre_data = scaler.transform(df)
    tensor_pred = torch.FloatTensor(pre_data).to(device)
    tensor_pred = tensor_pred.unsqueeze(0)  # 单次预测 , 滚动预测功能暂未开发后期补上
    model = model
    model.load_state_dict(torch.load('save_model.pth'))
    model.eval()  # 评估模式

    pred = model(tensor_pred)[0]

    pred = scaler.inverse_transform(pred.detach().cpu().numpy())

    # 假设 df 和 pred 是你的历史和预测数据

    # 计算历史数据的长度
    history_length = len(df[:, -1])

    # 为历史数据生成x轴坐标
    history_x = range(history_length)
    plt.figure(figsize=(10, 5))
    # 为预测数据生成x轴坐标
    # 开始于历史数据的最后一个点的x坐标
    prediction_x = range(history_length - 1, history_length + len(pred[:, -1]) - 1)

    # 绘制历史数据
    plt.plot(history_x, df[:, -1], label='History')

    # 绘制预测数据
    # 注意这里预测数据的起始x坐标是历史数据的最后一个点的x坐标
    plt.plot(prediction_x, pred[:, -1], marker='o', label='Prediction')
    plt.axvline(history_length - 1, color='red')  # 在图像的x位置处画一条红色竖线
    # 添加标题和图例
    plt.title("History and Prediction")
    plt.legend()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Time Series forecast')
    parser.add_argument('-model', type=str, default='RNN', help="模型持续更新")
    parser.add_argument('-window_size', type=int, default=126, help="时间窗口大小, window_size > pre_len")
    parser.add_argument('-pre_len', type=int, default=24, help="预测未来数据长度")
    # data
    parser.add_argument('-shuffle', action='store_true', default=True, help="是否打乱数据加载器中的数据顺序")
    parser.add_argument('-data_path', type=str, default='ETTh1-Test.csv', help="你的数据数据地址")
    parser.add_argument('-target', type=str, default='OT', help='你需要预测的特征列,这个值会最后保存在csv文件里')
    parser.add_argument('-input_size', type=int, default=7, help='你的特征个数不算时间那一列')
    parser.add_argument('-feature', type=str, default='MS', help='[M, S, MS],多元预测多元,单元预测单元,多元预测单元')
    parser.add_argument('-model_dim', type=list, default=[64, 128, 256], help='这个地方是这个TCN卷积的关键部分,它代表了TCN的层数我这里输'
                                                                              '入list中包含三个元素那么我的TCN就是三层,这个根据你的数据复杂度来设置'
                                                                              '层数越多对应数据越复杂但是不要超过5层')

    # learning
    parser.add_argument('-lr', type=float, default=0.001, help="学习率")
    parser.add_argument('-drop_out', type=float, default=0.05, help="随机丢弃概率,防止过拟合")
    parser.add_argument('-epochs', type=int, default=20, help="训练轮次")
    parser.add_argument('-batch_size', type=int, default=16, help="批次大小")
    parser.add_argument('-save_path', type=str, default='models')

    # model
    parser.add_argument('-hidden_size', type=int, default=128, help="隐藏层单元数")
    parser.add_argument('-kernel_sizes', type=int, default=3)
    parser.add_argument('-laryer_num', type=int, default=2)
    # device
    parser.add_argument('-use_gpu', type=bool, default=True)
    parser.add_argument('-device', type=int, default=0, help="只设置最多支持单个gpu训练")

    # option
    parser.add_argument('-train', type=bool, default=True)
    parser.add_argument('-test', type=bool, default=True)
    parser.add_argument('-predict', type=bool, default=True)
    parser.add_argument('-inspect_fit', type=bool, default=True)
    parser.add_argument('-lr-scheduler', type=bool, default=True)
    args = parser.parse_args()

    if isinstance(args.device, int) and args.use_gpu:
        device = torch.device("cuda:" + f'{args.device}')
    else:
        device = torch.device("cpu")
    print("使用设备:", device)
    train_loader, test_loader, valid_loader, scaler = create_dataloader(args, device)

    if args.feature == 'MS' or args.feature == 'S':
        args.output_size = 1
    else:
        args.output_size = args.input_size

    # 实例化模型
    try:
        print(f">>>>>>>>>>>>>>>>>>>>>>>>>开始初始化{args.model}模型<<<<<<<<<<<<<<<<<<<<<<<<<<<")
        model = RNNs(args.input_size, args.output_size, args.hidden_size, args.laryer_num, args.pre_len).to(device)
        print(f">>>>>>>>>>>>>>>>>>>>>>>>>开始初始化{args.model}模型成功<<<<<<<<<<<<<<<<<<<<<<<<<<<")
    except:
        print(f">>>>>>>>>>>>>>>>>>>>>>>>>开始初始化{args.model}模型失败<<<<<<<<<<<<<<<<<<<<<<<<<<<")

    # 训练模型
    if args.train:
        print(f">>>>>>>>>>>>>>>>>>>>>>>>>开始{args.model}模型训练<<<<<<<<<<<<<<<<<<<<<<<<<<<")
        train(model, args, scaler, device)
    if args.test:
        print(f">>>>>>>>>>>>>>>>>>>>>>>>>开始{args.model}模型测试<<<<<<<<<<<<<<<<<<<<<<<<<<<")
        test(model, args, test_loader, scaler)
    if args.inspect_fit:
        print(f">>>>>>>>>>>>>>>>>>>>>>>>>开始检验{args.model}模型拟合情况<<<<<<<<<<<<<<<<<<<<<<<<<<<")
        inspect_model_fit(model, args, train_loader, scaler)
    if args.predict:
        print(f">>>>>>>>>>>>>>>>>>>>>>>>>预测未来{args.pre_len}条数据<<<<<<<<<<<<<<<<<<<<<<<<<<<")
        predict(model, args, device, scaler)
    plt.show()


六、训练模型 

我们配置好所有参数之后就可以开始训练模型了,根据我前面讲解的参数部分进行配置,不懂得可以评论区留言。

​


七、预测结果

7.1 预测未知数据效果图

RNN的预测效果图(这里我只预测了未来24个时间段的值为未来一天的预测值)->

​


7.2 测试集效果图 

测试集上的表现->

​


7.3 CSV文件生成效果图 

同时我也可以将输出结果用csv文件保存,但是功能还没有做,我在另一篇informer的文章里实习了这个功能大家如果有需要可以评论区留言,有时间我会移植过来,最近一直在搞图像领域的文章因为时间序列看的人还是太少了。

另一篇文章链接->时间序列预测实战(十九)魔改Informer模型进行滚动长期预测(科研版本,结果可视化)

将滚动预测结果生成了csv文件方便大家对比和评估,以下是我生成的csv文件可以说是非常的直观。

​

 我们可以利用其进行画图从而评估结果-> 

​


7.4 检验模型拟合效果图

检验模型拟合情况->

(从下面的图片可以看出模型拟合的情况很好,估计是我发这么多里面拟合效果最好的了) 


八、全文总结

 到此本文的正式分享内容就结束了,在这里给大家推荐我的时间序列专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的模型进行补充,目前本专栏免费阅读(暂时,大家尽早关注不迷路~),如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

 专栏回顾: 时间序列预测专栏——持续复习各种顶会内容——科研必备

如果大家有不懂的也可以评论区留言一些报错什么的大家可以讨论讨论看到我也会给大家解答如何解决!最后希望大家工作顺利学业有成!

​

RNN-时间序列预测模型 RNN-应用场景 语音识别 音乐生成 情感分析:根据输入的评论,猜测评论的分数。 DNA序列分析 语言翻译等 带时间序列应用的场景 后面产生的结果,是受到前面结果的影响的。 区别于神经网络预测 神经网络的输入的特征都是固定不变的,强调特征的位置。 标准的神经网络是不适合用来处理带时间序列的模型的。 但是RNN 可以处理 RNN网络结构 将每一个时间状态 进行串联 后面的状态后受到前面状态的影响 单个单元 当前的x 和 前一个状态 a的t-1 tanh激活函数 学习非线性的部分 输出还乘以权重+偏置 阅读详情

相关推荐

AI:深度学习之循环神经网络(RNN)

循环神经网络(Recurrent Neural Network, RNN)是处理序列数据的“记忆大师”🧠。

Kant2048的博客 1534

Pytorch入门之RNN

看了花书上的RNN和莫凡python关于RNN的实战演练,现在来总结一下: 主要分4部分: 1、LSTM实现MNIST数据集分类 2、RNN实现三角函数的回归问题 3、LSTM实现三角函数的回归问题 4、LSTM实现周杰伦歌词读取 在4部分的实战之前,首先需要准备RNN基础知识: RNN,循环神经网络,是用于处理和离散时间序列有关的神经网络,相较于CNN,RNN加入了时间信息、还有记忆信息的特点。 RNN通过一种称之为隐藏状态来记忆当前时间步之前的信息,然后将它和当前时间步的输入..

Ton的博客 5173

【深度学习理论】(6) 循环神经网络 RNN

今天和各位分享一下处理序列数据的循环神经网络RNN的基本原理,并用 Pytorch 实现 RNN 层和 RNNCell 层。之前的博文中已经用过循环神经网络做过许多实战案例,感兴趣的可以看我这个专栏:https://blog.youkuaiyun.com/dgvv4/category_11712004.html在循环神经网络中,序列数据的 shape 通常是 [batch, seq_len, feature_len],其中 seq_len 代表特征的个数,feature_len 代表每个特征的表示方法。对于自然...

博观而约取,厚积而薄发 2827

【PyTorch】深度学习实践之 RNN基础篇——实现RNN

深度学习实践之 RNN基础篇——实现RNN,one-hot向量、LSTM,GRU

zoetu 1万+

RNN实现时间序列预测

在我们的示例中,样本数是数据集中的样本数量,时间步数是输入序列的长度(我们将使用3个时间步),特征数是每个时间步的特征数量(在我们的示例中,每个时间步只有一个特征)。接下来,我们定义了一个简单的RNN模型,并使用训练集对其进行训练。最后,我们使用训练好的模型进行预测,并将预测结果与目标序列进行可视化。在本文中,我们将使用RNN来实现时间序列预测,并提供相应的源代码示例。我们将使用一个简单的RNN模型,其中包含一个RNN层和一个全连接(Dense)层。训练完成后,我们可以使用训练好的模型来进行预测。

XlltEditor的博客 888

PyTorch中RNN模型深度解析与实战应用

input_size参数指定了每个时间步输入向量的特征数量,即输入张量最后一个维度的大小。这一参数必须与数据预处理阶段提取的特征维度严格一致,否则会导致运行时错误或语义偏差。例如,在自然语言处理任务中,若使用词嵌入层(),则input_size应等于嵌入向量的维度(如 300 维的 GloVe 向量);在时间序列预测中,若每一步观测包含温度、湿度、风速三项指标,则。

weixin_42511832的博客 1171

时间序列预测实战(二十五)PyTorch实现Seq2Seq进行多元和单元预测(附代码+数据集+完整解析)

本文给大家带来的时间序列模型是Seq2Seq,这个概念相信大家都不陌生了,网上的讲解已经满天飞了,但是本文给大家带来的是我在Seq2Seq思想上开发的一个模型和新的架构,架构前面的文章已经说过很多次了,其是专门为新手开发的,而且为了方便大家使用只定义了一个文件方便大家复制粘贴,架构功能包括:结果可视化、支持单元预测、多元预测、模型拟合效果检测、预测未知数据、以及滚动长期预测功能。Seq2Seq模型是一种处理序列数据的深度学习模型,广泛用于机器翻译、语音识别和文本摘要等任务(也能用于时间序列)。

Snu77的博客 9939

循环神经网络(RNN)实战代码解析

循环神经网络(RNN)是深度学习模型的一种,特别适用于处理序列数据。与传统的前馈神经网络不同,RNN在时间步之间拥有记忆能力,这意味着网络的输出不仅依赖于当前的输入,还取决于之前计算的历史状态。这种能力让RNN非常适合处理时间序列数据、自然语言处理、视频分析等领域中的任务。word2vec是一种利用神经网络训练词向量的模型,它可以通过上下文来学习单词的表示。

weixin_30481539的博客 416

循环神经网络RNN完全解析:从基础理论到PyTorch实战

在本文中,我们深入探讨了循环神经网络(RNN)及其高级变体,包括长短时记忆网络(LSTM)、门控循环单元(GRU)和双向循环神经网络(Bi-RNN)。文章详细介绍了RNN的基本概念、工作原理和应用场景,同时提供了使用PyTorch构建、训练和评估RNN模型的完整代码指南。

TechLead 2896

基于Apache MINA SSHD配置及应用

Apache MINA SSHD是一个基于Java的开源SSH服务器/客户端实现,支持SSH2协议,提供文件传输、shell访问等功能。该代码实现了一个SftpClientService服务类,封装了SFTP文件操作,包括读取文件(readOnce/readLines)和写入文件(writeOnce)等核心功能。通过SftpProperties配置类管理连接参数,并采用Builder模式创建SSH会话。主要特点包括:支持大文件分块传输、自动创建目录、严格的异常处理和...

流沙QuickSand 945

别再乱设阻尼了!Abaqus动力分析中瑞利阻尼的α和β到底怎么算?

本文深入解析Abaqus动力分析中瑞利阻尼参数α和β的科学计算方法,帮助工程师准确设置阻尼参数以提升仿真精度。详细介绍了基于模态阻尼比的经典计算方法和多模态优化法,并结合工程案例演示参数设置流程,避免常见的阻尼设置误区。

weixin_42634811的博客 732

人工智能算法工程师(中级)课程11-PyTorch神经网络之循环神经网络RNN与代码详解

本文详细介绍了循环神经网络(RNN)的原理、运行过程、类别、参数计算和应用场景,并通过PyTorch框架给出了一个完整的RNN模型实现。通过本文,读者可以了解到RNN在处理序列数据方面的优势,以及如何在实际应用中使用RNN。需要注意的是,实际应用中通常会使用PyTorch提供的内置RNN模块,如nn.RNNnn.LSTM和nn.GRU,这些模块提供了更高效、更灵活的实现。

微学AI的博客 1514

5分钟搞定!用ZLMediaKit+GB28181搭建低成本外网视频监控(含避坑指南)

本文详细介绍了如何利用开源ZLMediaKit流媒体服务器与国标GB28181协议,快速搭建低成本、可外网访问的企业级视频监控系统。文章提供了从服务端部署、设备配置到外网访问优化的完整实战指南,并重点分享了网络配置、性能调优及常见问题的避坑方案,帮助用户实现高清视频流的稳定推送与多格式播放。

bush的博客 333

PyTorch 深度学习实战(7):循环神经网络(RNN)与文本分类(基于本地头条数据集)

循环神经网络(RNN)是一种专门用于处理序列数据的神经网络结构。与传统的全连接神经网络不同,RNN 通过引入“记忆”机制,能够捕捉序列数据中的时间依赖关系,因此在 NLP、时间序列分析等领域有着广泛的应用。本文介绍了循环神经网络(RNN)的基本概念,并使用 PyTorch 实现了一个简单的中文文本分类模型。通过这个例子,我们学习了如何处理中文文本数据、构建 RNN 模型以及进行训练和评估。在下一篇文章中,我们将探讨 Transformer 模型及其在机器翻译中的应用。敬请期待!代码实例说明。

m0_60414444的博客 1446

期货套利策略(二)

接上一篇期货套利策略,随着对期货套利策略的深入了解,我发现套利策略不是那么好做的。下面将会讲碰到的一些问题。 上一篇文章中没有考虑滑点的问题,这里我们把滑点问题考虑进去。这里先说一些天勤api的买入点,天琴的买入点是当前K线的收盘价。碰到数据传输问题,还有计算等各方面问题,实际情况是无法在当前K线的收盘价买入的。这里我们把这方面问题考虑进去,利用api.wait_update()调到下一个k线数据...

qq_31611005的博客 1713

2026年全国青少年信息素养大赛算法应用主题赛(C++赛项复赛模拟卷1:文末附答案)

2026年全国青少年信息素养大赛算法应用主题赛(C++赛项复赛模拟卷1:文末附答案)

王老师青少年编程 1617

循环神经网络(RNN):时序数据的深度学习模型

循环神经网络(RNN)是深度学习领域处理序列数据的核心架构,通过独特的循环连接机制解决了传统神经网络无法捕捉时序依赖关系的局限性。RNN通过共享参数和隐藏状态记忆,能够有效处理变长序列输入,在自然语言处理、时间序列预测等领域展现出强大能力。尽管面临梯度消失/爆炸等挑战,但LSTM和GRU等门控变体的出现有效解决了这些问题,大幅提升了模型性能和训练稳定性。本文从数学原理、代码实现到高级变体全面解析RNN技术体系,通过可视化图表和实例对比,为读者提供了从理论到实践的完整学习路径,帮助理解这一时序数据建模的关键技

言不信者行不果,行不敏者言多滞. 1794

5、AIX系统硬件管理与故障诊断全解析

本文全面解析了AIX系统的硬件管理与故障诊断方法,涵盖系统管理服务(SMS)的使用、设备兼容性配置、设备配置数据库结构、常用命令如cfgmgr、lsattr、smitty devices的操作详解,并深入介绍了错误日志管理机制,包括errdemon、errpt、errlogger等命令的应用。通过实际案例分析和流程图展示,帮助系统管理员掌握从问题怀疑到诊断执行再到日志清理的完整流程,同时提供注意事项与最佳实践,助力AIX系统的稳定运行与高效维护。

y2z3a4b5c的博客 62

【NLP】循环神经网络--RNN学习.day3

循环神经网络(Recurrent Neural Network, RNN)是一种用于处理序列数据的深度学习模型。与传统的静态神经网络相比,RNN 可以有效处理输入数据的时间序列特性。这使得 RNN 在处理自然语言处理(NLP)、时间序列预测、音频处理等任务时非常有效。以下是对 RNN 的详细解释。

alb3117149013的博客 1406

基于Simulink的PMSM轮毂电机崎岖路面悬架协同控制仿真

本文完成了基于Simulink的PMSM轮毂电机崎岖路面悬架协同控制仿真,实现了:✅ 构建了四轮独立驱动+主动悬架高保真整车模型✅ 实现了Skyhook主动悬架控制✅ 设计了驱动-悬架状态共享与协同决策机制✅ 验证了5 m/s高速下连续颠簸路面稳定通过能力✅ 为高性能移动机器人提供一体化底盘解决方案。

xiaoheshang_123的博客 190

Halcon 形态学 开发案例 (开运算opening(先腐蚀再膨胀)、闭运算closing(先膨胀再腐蚀))

算子方法:功能:使用用户自定义的结构元素对区域进行开运算参数: Region(输入参数) :输入区域 StructElement(输入参数) :结构元素(区域) RegionOpening(输出参数) :开运算后的区域功能:使用圆形结构元素对区域进行开运算参数: Region(输入参数) :输入区域 RegionOpening(输出参数) :开运算后的区域 Radius(输入参数) :圆形结构元素的半径功能:使用矩形结构元素对区域进行开运算。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 1619

《PyTorch RNN实战全解析:从隐状态理解到序列建模的完整代码实现》

文章开篇从RNN的基本结构入手,重点阐释了隐状态(Hidden State)​ 作为网络记忆单元的关键作用,并详解了其处理序列数据的时序工作机制。随后,文章转向实战,逐步演示了如何使用PyTorch搭建一个完整的RNN模型:从导入必要的库、定义网络结构,到创建模拟训练数据、配置损失函数(如交叉熵损失)与优化器(如Adam或SGD)。文中提供了清晰的训练循环与测试流程代码,并汇总了可执行的完整实例。此外,文章通过模型损失曲线的图表输出与代码结构可视化,直观展示了训练动态与项目架构,帮助读者从理论理解平滑过渡到

跟我加入白帽大家庭,共捍亿万互联网用户安全! 822

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

RNN基本原理以及基于Pytorch实践

RNN神经网络和基于Pytorch的实践 本文主要讲述了RNN循环神经网络的基本原理和利用pytorch进行序列生成的实践,原理的部分主要参考 https://blog.youkuaiyun.com/HappyRocking/article/details/83657993,实践的部分主要参考的 是《深度学习原理和Pytorch实战》。在这里向作者表示感谢。 本文主要包含以下三个部分 ...

hei653779919的博客 5739

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

AI: 一文读懂循环神经网络(RNN)

摘要: 循环神经网络(RNN)是处理序列数据的核心模型,通过隐藏状态传递历史信息实现序列依赖建模。其核心结构在每个时间步接收当前输入和上一状态,通过时间展开形成链式结构。针对传统RNN的梯度消失问题,LSTM引入遗忘门、输入门和输出门增强长期记忆能力,GRU则通过简化门控结构提升效率。RNN在自然语言处理(文本生成、情感分析)、时间序列预测和语音识别等领域有广泛应用,但面临梯度不稳定和训练复杂度高的挑战。PyTorch等框架为RNN实现提供了便捷工具,LSTM等改进模型显著提升了序列建模性能。未来结合注意力

xyzroundo的专栏 1586

解锁时间序列的奥秘:循环神经网络(RNN)从零实现全攻略

循环神经网络(RNN)作为序列数据处理的核心工具,在自然语言处理、语音识别和时间序列预测等领域展现强大能力。本文从生物学启发的网络架构出发,深入解析梯度传播机制与门控创新原理,结合PyTorch与TensorFlow两大框架的代码实现,通过手写数字识别和文本生成案例揭示RNN的工程实践要点,并提供梯度优化策略与可视化方案。

领码SPARK - 以无代码之星火,燎原数字之未来! 1467

(全网最详细)基于Pytorch的LSTNet时间序列预测代码解读

全网最详细的LSTNet代码及算法原理解读

Yubo1214的博客 3448
上一篇: YOLOv8改进 | 注意力机制 | 添加TripletAttention三重注意力机制(附代码+机制原理+添加教程)
下一篇: 时间序列预测实战(二十五)PyTorch实现Seq2Seq进行多元和单元预测(附代码+数据集+完整解析)
Snu77
Snu77 优质创作者: 人工智能技术领域 优质创作者: 人工智能技术领域
博客等级 码龄5年 11万+粉丝 934原创
评论 53
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Snu77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值