循环神经网络-单变量序列预测详解(pytorch)

参考博客

文章目录

      • (1)导入所需要的包
      • (2)读取数据并展示
      • (3)数据预处理
      • (4)划分训练集和测试集
      • (5)构建RNN回归模型
      • (6)构造训练函数
      • (7)对整个数据集进行预测
      • (8)可视化展示
      • (9)MSE为评价指标

(1)导入所需要的包

import torch
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler

(2)读取数据并展示

data_csv =pd.read_csv("data/data.csv", usecols=[1])
plt.plot(data_csv)
print(data_csv.shape)

在这里插入图片描述

(3)数据预处理

缺失值,转化成numpy.ndarray类型,转化成float类型,归一化处理

data_csv = data_csv.dropna()
dataset = data_csv.values
dataset = dataset.astype("float32")
scaler = MinMaxScaler()
dataset = scaler.fit_transform(dataset)

(4)划分训练集和测试集

用30个预测一个
1-30:31
2-31:32

94-143:144
需要注意a = [dataset[i: (i + look_back)]],而不是a = dataset[i: (i + look_back)]

look_back = 30
def create_dataset(dataset, look_back):dataX, dataY = [], []for i in range(len(dataset) - look_back):a = [dataset[i: (i + look_back)]]dataX.append(a)dataY.append(dataset[i + look_back])return np.array(dataX), np.array(dataY)dataX, dataY = create_dataset(dataset, look_back)
dataX.shape,dataY.shape,type(dataX),type(dataY),dataX.dtype,dataY.dtype

在这里插入图片描述对于 dataX,它的形状为 (114, 1, 30, 1)。其中 114 表示样本数量,1 表示特征数量,30 表示历史时间步的数量,1 表示每个时间步的特征数量。

输出部分dataX和dataY的值

print(dataX[:2],dataY[:2])

在这里插入图片描述

数据集搭好之后,对数据集进行7:3的划分

train_size=int(len(dataX)*0.7)
test_size=len(dataX)-train_sizetrain_x=dataX[:train_size]
train_y=dataY[:train_size]test_x=dataX[train_size:]
test_y=dataY[train_size:]print(train_size)

在这里插入图片描述

train_x=torch.from_numpy(train_x)
train_x=train_x.squeeze(3)
train_y=torch.from_numpy(train_y)test_x=torch.from_numpy(test_x)
test_y=torch.from_numpy(test_y)
print(train_x.shape,test_x.shape)

在这里插入图片描述
对以上代码进行解释:

  • numpy.ndarray类型的转化成Tensor类型
  • 即将 NumPy 数组 train_x 转换为 PyTorch 张量
  • 转换之后神经网络才能计算
  • sequeeze(3)是将train_x从([79,1,30,1])变为([79,1,30])
  • test_x不需要sequeeze(3)的原因是:在pytorch中,卷积池化等操作需要输入的是四维张量(样本数,时间步长,特征数,1 )**(有待考究)**test在后面没用到

(5)构建RNN回归模型

class rnn_reg(torch.nn.Module):def __init__(self,input_size,hidden_size,out_size=1,num_layers=2)->None:super(rnn_reg,self).__init__()self.rnn=torch.nn.RNN(input_size,hidden_size,num_layers)self.reg=torch.nn.Linear(hidden_size,out_size)def forward(self,x):x,_=self.rnn(x)seq,batch_size,hidden_size=x.shapex=x.reshape(seq*batch_size,hidden_size)x=self.reg(x)x.reshape(seq,batch_size,-1)return xnet=rnn_reg(look_back,16)
criterion=torch.nn.MSELoss()
optimizer=torch.optim.Adam(net.parameters(),lr=1e-2)

对以上代码进行解释:

  • rnn_reg 的子类,继承torch.nn.Module,用于创建自定义的神经网络模型

  • __ init__是rnn_reg 类构造函数,用于初始化模型的参数
    在这里插入图片描述

  • super(rnn_reg, self).__init__(): 调用父类 torch.nn.Module 的构造函数

  • self.rnn = torch.nn.RNN(input_size, hidden_size, num_layers): 创建了一个 RNN 层。input_size 表示输入特征的维度,hidden_size 表示隐藏状态的维度,num_layers 表示 RNN 的层数。

  • self.reg = torch.nn.Linear(hidden_size, out_size): 创建了一个线性层(全连接层),用于将 RNN 的隐藏状态映射到输出特征维度。

  • def forward(self, x): 这是 rnn_reg 类的前向传播方法。它接受输入 x,并定义了模型的前向计算过程。
    -在这里插入图片描述

  • x, _ = self.rnn(x): 将输入 x 传递给 RNN 层进行前向计算。_ 表示隐藏状态,由于这里不需要使用隐藏状态,所以用下划线 _ 进行占位。

  • seq, batch_size, hidden_size = x.shape: 获取 RNN 输出 x 的形状信息,其中 seq 表示序列长度,batch_size 表示批次大小,hidden_size 表示隐藏状态的维度。

  • x = x.reshape(seq * batch_size, hidden_size): 将 x 重塑为形状 (seq * batch_size, hidden_size),以便通过线性层进行映射。

  • x = self.reg(x): 将重塑后的 x 传递给线性层 self.reg 进行映射操作。

  • x.reshape(seq, batch_size, -1): 将输出 x 重塑为形状 (seq, batch_size, -1),以便与输入保持相同的维度。

  • return x: 返回最终的输出 x。

  • net = rnn_reg(look_back, 16): 创建了一个 rnn_reg 类的实例 net。look_back 表示输入特征的维度,16 表示隐藏状态的维度。

  • criterion = torch.nn.MSELoss(): 定义了损失函数,使用均方误差(MSE)作为损失函数。

  • optimizer = torch.optim.Adam(net.parameters(), lr=1e-2): 定义了优化器,使用 Adam 优化算法来更新模型的参数,学习率为 1e-2。

输出一下设置的模型内的一些层数的维度:

for param_tensor in net.state_dict():print(param_tensor,'\t',net.state_dict()[param_tensor].size())

在这里插入图片描述

(6)构造训练函数

设置训练1000次,每100次输出一次损失

running_loss=0.0
for epoch in range(1000):var_x=train_xvar_y=train_yout=net(var_x)loss=criterion(out,var_y)running_loss+=loss.item()optimizer.zero_grad()loss.backward()optimizer.step()if(epoch+1)%100==0:print('Epoch:{},loss:{:.5f}'.format(epoch+1,running_loss/100))running_loss=0.0

在这里插入图片描述
对以上代码进行解释:

  • running_loss,用于记录每个训练周期的累计损失。
  • out=net(var_x)这个out就是红框标出的需要预测的预测值,即将输入数据 var_x 通过神经网络模型 net 进行前向传播,得到输出 out。
    在这里插入图片描述
  • loss = criterion(out, var_y): 计算模型输出 out 和目标标签 var_y 之间的损失,使用预先定义的损失函数 criterion(在代码中是均方误差)。
  • loss.item() 方法用于获取 loss 的数值(标量),然后将其加到 running_loss 上。
  • optimizer.zero_grad(): 清空优化器中之前的梯度信息,以便进行下一次的反向传播。
  • loss.backward(): 执行反向传播,计算损失函数关于模型参数的梯度。
  • optimizer.step(): 这行代码根据计算得到的梯度更新模型参数,使用优化器中定义的Adam优化算法
  • print输出平均损失

(7)对整个数据集进行预测

net = net.eval() # 转换成测试模式
data_x = dataX.reshape(-1, 1, look_back)
data_x = torch.from_numpy(data_x).to(torch.float32)
var_data = data_x
pred_test = net(var_data) # 测试集的预测结果
pred_test = pred_test.view(-1).data.numpy()

对上述代码解释:
在这里插入图片描述
在这里插入图片描述

  • data_x = torch.from_numpy(data_x).to(torch.float32): 这行代码将 NumPy 数组 data_x 转换为 PyTorch 的 Tensor 对象,并将数据类型设置为 torch.float32。这是为了与神经网络模型的数据类型匹配。
  • pred_test = pred_test.view(-1).data.numpy(): 这行代码对预测结果进行处理,首先使用 view(-1) 将输出结果展平为一维张量,然后使用 data.numpy() 将结果转换为 NumPy 数组,以便后续的分析和可视化。

(8)可视化展示

这里因为用30个预测1个,所以dataset进行了切片(总共114)

plt.plot(pred_test, 'deeppink', label='prediction')
plt.plot(dataset[look_back:], 'green', label='real')
plt.legend(loc='best')

在这里插入图片描述

(9)MSE为评价指标

这里因为用30个预测1个,所以计算MSE的也不包括前30个数据,否则没法去计算

from sklearn.metrics import mean_squared_error
MSE = mean_squared_error(dataset[look_back:], pred_test)
print(MSE)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/417354.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++总结笔记

1. 简介 1、面向对象程序设计 面向对象的四大特性 1)封装 2)继承 3)多态 4)抽象 2、标准库 标准C由三个部分组成 1)核心语言:提供了所有的构件块 2)C标准库:提供了大量的函…

【漏洞复现】Hikvision SPON IP网络对讲广播系统命令执行漏洞(CVE-2023-6895)

文章目录 前言声明一、系统简介二、漏洞描述三、影响版本四、漏洞复现五、修复建议 前言 Hikvision Intercom Broadcasting System是中国海康威视(Hikvision)公司的一个对讲广播系统。 声明 请勿利用文章内的相关技术从事非法测试,由于传播…

Klocwork—符合功能安全要求的自动化静态测试工具

产品概述 Klocwork是Perforce公司产品,主要用于C、C、C#、Java、 python和Kotlin代码的自动化静态分析工作,可以提供编码规则检查、代码质量度量、测试结果管理等功能。Klocwork可以扩展到大多数规模的项目,与大型复杂环境、各种开发工具集成…

通过semanage管理SELinux

1.简介 semanage命令是用来查询与修改SELinux默认目录的安全上下文。 SELinux的策略与规则管理相关命令:seinfo命令、sesearch命令、getsebool命令、setsebool命令、semanage命令。 2.操作 如不知怎么操作,可以 --help 查看使用方法 大概的意思&…

C++实战:类的包含编译模型

文章目录 一、实战概述二、实战步骤(一)C普通类的包含编译模型1、创建普通类定义文件2、创建普通类实现文件3、创建主程序文件4、运行主程序,查看结果 (二)C模板类的包含编译模型1、创建模板类定义文件2、创建模板类实…

【C++入门到精通】智能指针 shared_ptr 简介及C++模拟实现 [ C++入门 ]

阅读导航 引言一、简介二、成员函数三、使用示例四、C模拟实现五、std::shared_ptr的线程安全问题六、总结温馨提示 引言 在 C 动态内存管理中,除了 auto_ptr 和 unique_ptr 之外,还有一种智能指针 shared_ptr,它可以让多个指针共享同一个动…

伊恩·斯图尔特《改变世界的17个方程》傅里叶变换笔记

主要是课堂的补充(yysy,我觉得课堂的教育模式真有够无聊的,PPT、写作业、考试,感受不到知识的魅力。 它告诉我们什么? 空间和时间中的任何模式都可以被看作不同频率的正弦模式的叠加。 为什么重要? 频率分量…

投标文件-优化--word快捷键设置

大纲导航快捷键的设置 “导航窗格”功能是指的如上图所示的功能,在写标书的时候,时刻需要关注你的目录大纲级别是否设置正确,文章层级目录是否正确,每次都是需要“视图--导航窗格”点,把人烦的不行,如何优化…

WordPress怎么去除jquery和CSS静态文件链接中的版本号?附2种方法

我们很多WordPress网站默认情况下所加载的jquery和CSS静态文件链接中都会带有相应的版本号,比如boke112百科使用的YIA主题,加载CSS文件时就会在链接地址后面加上?ver2.7,即是style.css?ver2.7 除了CSS文件会加上版本号外,加载主…

含并行连结的网络(GoogLeNet)

目录 1.GoogLeNet 2.代码 1.GoogLeNet inception不改变高宽,只改变通道数。GoogLeNet也大量使用1*1卷积,把它当作全连接用。 V3耗内存比较多,计算比较慢,但是精度比较准确。 2.代码 import torch from torch import nn from t…

探索设计模式的魅力:一篇文章让你彻底搞懂建造者模式

建造者模式(Builder Pattern)是一种创建型设计模式,旨在将一个复杂对象的创建过程与其表示分离,使得同样的构建过程可以创建不同的表示形式。 主要角色: 产品(Product):表示正在构建…

vue2+webpack升级vue3+vite,报错Cannot read properties of null (reading ‘isCE‘)

同学们可以私信我加入学习群! 正文开始 前言问题分析解决总结 前言 系列文章:vue2webpack升级vue3vite,修改插件兼容性bug 前面的文章主要是介绍,在升级初始阶段遇到的一些显而易见的兼容性问题和bug。随着项目迭代的不断深入&a…