使用PyTorch训练LSTM预测模型

news/2024/11/29 7:57:51/

大家好,长短期记忆网络(LSTM)是RNN的一种变体,RNN由于梯度消失的原因只能有短期记忆,LSTM网络通过精妙的门控制将短期记忆与长期记忆结合起来,并且一定程度上解决了梯度消失的问题。本文将参照notebook演示如何训练一个长短期记忆网络模型,并且快速对比它与其他模型的性能。

获取数据

选取一个数据流:

import matplotlib.pyplot as plt
from microprediction import MicroReader# 初始化MicroReader
reader = MicroReader()# 获取一个数据流名称的列表
stream_names = reader.get_stream_names()# 从列表中选择第一个数据流
stream = stream_names[50]# 或者硬连接它...
stream = 'yarx_vlty_2_mo.json'# 获取历史数据(返回一个值的列表)
history = reader.get_lagged_values(name=stream)# 绘制历史数据
plt.plot(history[:30])
plt.xlabel("Time")
plt.ylabel("Value")
plt.title(f"Historical Data for '{stream}'")
plt.show()

整理训练数据

现在需要将它变成PyTorch的回归数据格式,这是我们需要的模板代码,建议保存备用。

import numpy as np
import torchdef create_sequences(data, seq_length):xs, ys = [], []for i in range(len(data) - seq_length - 1):x = data[i:(i + seq_length)]y = data[i + seq_length]xs.append(x)ys.append(y)return np.array(xs), np.array(ys)

这个函数的目的是为了生成用于训练和测试时间序列预测模型的输入-输出对,输入-输出对是通过在时间序列数据上滑动一个给定长度(seq_length)的窗口来创建的。对于每次迭代,它通过从索引i到索引i+seq_length切片数据来创建一个输入序列x,然后通过选择索引i+seq_length处的数据点来创建相应的目标值y

分离和转换

PyTorch需要张量格式,而不是numpy,因此进行转换:

# 将数据分成训练集和测试集
train_size = int(len(y) * 0.8)
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]# 转换为PyTorch张量
X_train = torch.from_numpy(X_train).float()
y_train = torch.from_numpy(y_train).float()
X_test = torch.from_numpy(X_test).float()
y_test = torch.from_numpy(y_test).float()

定义模型

这段代码定义了一个名为LSTM的PyTorch自定义nn.Module类,它代表了时间序列预测的长短期记忆(LSTM)神经网络模型。

import torch.nn as nnclass LSTM(nn.Module):def __init__(self, input_size, hidden_size, num_layers, output_size):super(LSTM, self).__init__()self.hidden_size = hidden_sizeself.num_layers = num_layersself.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)self.fc = nn.Linear(hidden_size, output_size)def forward(self, x):h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size)c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size)out, _ = self.lstm(x, (h0, c0))out = self.fc(out[:, -1, :])return out
  • input_size:每个时间步骤的输入特征数。

  • hidden_size:每个LSTM层中的隐藏单元数。

  • num_layers:堆叠的LSTM层数。

  • output_size:输出的大小(例如,预测值的数量)。

由于有单变量目标,使用的代码如下:

# 初始化LSTM模型
input_size = 1
hidden_size = 50
num_layers = 1
output_size = 1
model = LSTM(input_size, hidden_size, num_layers, output_size)
# 设置训练参数
learning_rate = 0.01
num_epochs = 100# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)# 训练模型
for epoch in range(num_epochs):outputs = model(X_train.unsqueeze(-1)).squeeze()  # Add .squeeze() hereoptimizer.zero_grad()loss = criterion(outputs, y_train)loss.backward()optimizer.step()if (epoch + 1) % 10 == 0:print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")

X_train.unsqueeze(-1)将一个额外的维度添加到X_train张量中,使其具有形状(batchsequencefeature),因为LSTM模型期望以这种格式输入张量。

model(X_train.unsqueeze(-1))将重塑后的X_train张量通过LSTM模型,生成输出预测。输出张量的形状为(batchoutput_size)。在这里squeeze()会从输出张量中删除任何大小为1的维度,从而简化后续计算。

optimizer.zero_grad()在开始新的优化迭代之前重置了模型参数的梯度,因为在PyTorch中默认情况下梯度会累积,如果不将其清零,则会导致在后续迭代中出现不正确的梯度计算。

测试

由于只需要计算,所以不需要梯度,在本文的实例中,测试损失为0.0092。让我们将其与学习时的训练损失进行比较:


Epoch [10/100], Loss: 0.0283
Epoch [20/100], Loss: 0.0184
Epoch [30/100], Loss: 0.0163
Epoch [40/100], Loss: 0.0132
Epoch [50/100], Loss: 0.0104
Epoch [60/100], Loss: 0.0101
Epoch [70/100], Loss: 0.0097
Epoch [80/100], Loss: 0.0094
Epoch [90/100], Loss: 0.0090
Epoch [100/100], Loss: 0.0086

比较的结果显示,thinking_fast_and_slow模型不如我们训练的LSTM。


http://www.ppmy.cn/news/869203.html

相关文章

Spring IOC - Bean的扫描

Component及其衍生注解:Configuration、Controller、Service、Repository标记的类,被Spring IOC扫描到后,即可被容器管理起来。其原理基本涵盖在AnnotationConfigApplicationContext构造函数体的三行代码里。 public AnnotationConfigApplic…

信用卡号

一个信用卡号必须是13到16位的整数。它的开头必须是: 4,指Visa卡 5,指Master卡 37,指American Express卡 6,指Discover卡1)从右到左对每个偶数位字翻倍。如果对某个数字翻倍之后的结果是一个两位数,那么就将…

01、识别信用卡卡号

import numpy as np import cv2 as cv import matplotlib.pyplot as plt import myutils #一、绘制图像 def img_show(img_name,img):cv.imshow(img_name,img)cv.waitKey(0)cv.destroyAllWindows()#二、模板操作 #1、读取模板图像 template cv.imread(./images/ocr_a_referenc…

国际信用卡

国际信用卡是一种银行联合国际信用卡组织签发给那些资信良好的人士并可以在全球范围内进行透支消费的卡片,同时该卡也被用于在国际网络上确认用户的身份。 国际发卡组织是一个由全世界银行参与的非营利的国际性组织,会员由银行等金融机构组成&#xff0…

美国visa虚拟信用卡

转载自[url]http://xinlanzero.iteye.com/blog/1141845[/url] 1 http://www.simon.com虚 拟卡20$起的22$.美国等借记卡就可以购买.带名字地址等等资料.激活PP.EBAY都是即时的. 2 http://www-card.com 以 色列网站.虚拟卡特便宜.20$只需要22$.支持所有国家的卡. 3激活美国PP的…

验证6种信用卡卡号的代码

验证6种信用卡卡号的代码 作者:BEUS 日期:2006-08-25 字体大小: 小 中 大 可以验证的信用卡种类有: V - Visa M - MasterCard A - American Express D - Diners ClubDiscover - DiscoverJCB - JCB 以下为ASP代码: Function ValidateCreditCard(ByRef pS…

信用卡卡号验证算法

How to check digits in credit card validation 文章来源:http://platon.sk/article.php?38 Author: Hal Stiles | Section: Dev Resources | Date: 2005-06-25 This document outlines procedures and algorithms for Verifying the accuracy and validity of …

VISA操作

VISA操作 VISA操作表 操作表: 1、VISA资源模板: viClose(vi):关闭特定的对话通道。 viGetAttribute(vi,attribute,attrState):获取资源属性状态值。 viSetAtt…