网站首页模板怎么做策划,如何做网络投票网站,sap软件,网页设计与制作黄俊峰目录
引言
LSTM的预测效果图
LSTM机制
了解LSTM的结构
忘记门
输入门
输出门
LSTM的变体
只有忘记门的LSTM单元
独立循环(IndRNN)单元
双向RNN结构(LSTM)
运行代码
代码讲解 引言
LSTM#xff08;Long Short-Term Memory#xff09;是一种常用的循环神经网络Long Short-Term Memory是一种常用的循环神经网络RNN模型用于处理序列数据具有记忆长短期的能力。在时间序列预测中LSTM既可以多元预测机制又可以作为单元预测机制使用。
作为多元预测机制LSTM可以处理多个相关变量的历史数据从而可以预测这些变量的未来值。具体地我们可以将多个变量的历史数据作为LSTM的输入将多个变量的未来值作为LSTM的输出。在训练过程中我们可以使用误差反向传播算法来更新LSTM的参数从而优化模型的预测性能。
作为单元预测机制LSTM可以预测单一变量的未来值例如股票价格、销售量等。在单元时间序列预测中我们需要对历史数据进行分析确定趋势、季节性和周期性等因素并使用这些因素来预测未来的值。LSTM可以通过学习历史数据中的模式和规律来预测未来的值。
LSTM作为多元预测机制和单元预测机制的优点是可以处理序列数据中的长期依赖关系从而可以捕捉到数据中的复杂模式和规律。它可以自适应地学习和调整模型参数从而提高模型的预测性能和泛化能力。
总的来说LSTM作为多元预测机制和单元预测机制的应用广泛可以用于预测股票价格、气象数据、交通流量等多个领域的数据。
(文末有复制粘贴即可运行的代码)
LSTM的预测效果图
这里先给大家展示一下LSTM的预测效果图(这里的预测指的是预测未知的数据并不是在测试集或者验证集上的预测)其中MAE误差为0.15,ME误差为-0.03。 其误差损失图为,其为MAE的误差图 LSTM机制
LSTM长短期记忆Long Short-Term Memory是一种用于处理序列数据的深度学习模型属于循环神经网络RNN的一种变体,其使用一种类似于搭桥术结构的RNN单元。相对于普通的RNNLSTM引入了门控机制能够更有效地处理长期依赖和短期记忆问题是RNN网络中最常使用的Cell之一。
了解LSTM的结构
LSTM通过刻意的设计来实现学习序列关系的同时又能够避免长期依赖的问题。它的结构示意图如下所示。 在LSTM的结构示意图中每一条黑线传输着一整个向量从一个节点的输出到其他节点的输入。其中“”号代表着运算操作(如矢量的和)而矩形代表着学习到的神经网络层。汇合在一起的线表示向量的连接分叉的线表示内容被复制然后分发到不同的位置。
如果上面的LSTM结构图你看着很难理解,但是其实LSTM的本质就是一个带有tanh激活函数的简单RNN如下图所示。 LSTM这种结构的原理是引入一个称为细胞状态的连接。这个状态细胞用来存放想要的记忆的东西(对应简单LSTM结构中的h只不过这里面不再只保存上一次状态了而是通过网络学习存放那些有用的状态)同时在加入三个门,分别是。 忘记门:决定什么时候将以前的状态忘记。 输入门决定什么时候将新的状态加进来。 输出门决定什么时候需要把状态和输入放在一起输出。
从字面上可以看出由于三个门的操作LSTM在状态的更新和状态是否要作为输入全部交给了神经网络的训练机制来选择。
下面分别来介绍一下三个门的结构和作用。
忘记门
下图所示为忘记门的操作忘记门决定模型会从细胞状态中丢弃什么信息。
忘记门会读取前一序列模型的输出和当前模型的输入来控制细胞状态中的每个数是否保留。
例如:在一个语言模型的例子中假设细胞状态会包含当前主语的性别于是根据这个状态便可以选择正确的代词。当我们看到新的主语时应该把新的主语在记忆中更新。忘记们的功能就是先去记忆中找到一千那个旧的主语(并没有真正执行忘记的操作只是找到而已。 在上图的LSTM的忘记门中代表忘记门的输出 α代表激活函数代表忘记门的权重代表当前模型的输入代表前一个序列模型的输出代表忘记门的偏置。
输入门
输入门可以分为两部分功能一部分是找到那些需要更新的细胞状态。另一部分是把需要更新的信息更新到细胞状态里 在上面输入门的结构中代表要更新的细胞状态α代表激活函数代表当前模型的输入代表前一个序列模型的输出代表计算的权重代表计算的偏置代表使用tanh所创建的新细胞状态代表计算的权重代表计算的偏置。
忘记门找到了需要忘掉的信息后在将它与旧状态相乘丢弃确定需要丢弃的信息。(如果需要丢弃对应位置权重设置为0)然后将结果加上 * 使细胞状态获得新的信息。这样就完成了细胞状态的更新如下图输入门的更新图所示。 再上图LSTM输入门的更新图中代表忘记门的输出结果 代表忘记门的输出结果代表前一个序列模型的细胞状态代表要更新的细胞状态代表使用tanh所创建的新细胞状态。
输出门
如下图LSTM的输出门结构图所示在输出门中通过一个激活函数层(实际使用的是Sigmoid激活函数)来确定哪个部分的信息将输出接着把细胞状态通过tanh进行处理(得到一个在-1~1的值)并将它和Sigmoid门的输出相乘得出最终想要输出的那个部分例如在语言模型中假设已经输入了一个代词便会计算出需要输出一个与该代词相关的信息(词向量) 在LSTM的输出门结构图中代表要输出的信息α代表激活函数代表计算 的权重代表计算的偏置代表更新后的细胞状态代表当前序列模型的输出结果。
LSTM的变体
只有忘记门的LSTM单元
只有忘记门的JANET)单元也是LSTM单元的一个变种发布于2018年。该单元结构源于一个大胆的猜测——当LSTM只有忘记门时会如何
实验表明只有忘记门的网络性能居然优于标准LSTM单元。同样该优化方式也可以被用于其他RNN结构。
如果大家想了解更多LSTM的变体可以查看一下其他相关资料例如该论文。
独立循环(IndRNN)单元
独立循环单元是一种新型的循环神经网络结构单元结构发布于2018年其效果和速度均优于LSTM的单元。
IndRNN单元不但可以有效解决传统RNN模型存在的梯度爆炸和梯度小时问题而且能够更好地学习样本中的长期依赖关系。
在搭建模型时 可以用堆叠、残差、全连接的方式使用IndRNN单元搭建更深的网络结构 将IndRNN单元配合ReLU等非饱和激活函数一起使用会使模型表现出更好的鲁棒性
双向RNN结构(LSTM)
双向RNN又称Bi-RNN是采用两个方向的RNN模型
RNN模型擅长的是对连续数据的处理既然是连续的数据那么模型不但可以学习它的正向特征而且可以学习它的反向特征这种将正向和反向结合的结构会比单向的循环网络有更高的拟合度。
双向RNN的处理过程就是在正向传播的基础上再进行一次反向传播。正向传播和反向传播都连接着一个输出层。这个结构提供给输出层输入序列中每一个点的完整的过去和未来的上下文信息。如图所示是一个沿着事件展开的双向循环神经网络(我们用LSTM举例实际可以是其他任何一个RNN结构) 双向RNN会比单项RNN多一个隐藏层6个独特的权值在每一个时步被重复利用6个权值分别对应输入到向前和向后隐含层隐含层到隐含层自身向前和向后隐含层到输出层。
有关双向RNN(LSTM)我会在后续文章中讲到这里只是大致介绍一下。
(在大多数应用中基于时间序列的分析和有关NLP中自动回答类的一些问题中一般是以双向LSTM配合单向LSTM或RNN横向扩展来实现效果非常好)
运行代码
下面的代码大家可以赋值到一个py文件中输入自己的文件预测文件即可运行这只是一个简单LSTM模型搭建,其可以搭配许多其他模块进行组合例如:注意力机制(TPA)、其他的网络结构(GRU)、双向的RNN结构等。
import time
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from matplotlib import pyplot as plt
from sklearn.preprocessing import MinMaxScalernp.random.seed(0)def calculate_mae(y_true, y_pred):# 平均绝对误差mae np.mean(np.abs(y_true - y_pred))return maetrue_data pd.read_csv(ETTh1-Test.csv) # 填你自己的数据地址target OT# 这里加一些数据的预处理, 最后需要的格式是pd.seriestrue_data np.array(true_data[OT])# 定义窗口大小
test_data_size 32
# 训练集和测试集的尺寸划分
test_size 0.15
train_size 0.85
# 标准化处理
scaler_train MinMaxScaler(feature_range(0, 1))
scaler_test MinMaxScaler(feature_range(0, 1))
train_data true_data[:int(train_size * len(true_data))]
test_data true_data[-int(test_size * len(true_data)):]
print(训练集尺寸:, len(train_data))
print(测试集尺寸:, len(test_data))
train_data_normalized scaler_train.fit_transform(train_data.reshape(-1, 1))
test_data_normalized scaler_test.fit_transform(test_data.reshape(-1, 1))
# 转化为深度学习模型需要的类型Tensor
train_data_normalized torch.FloatTensor(train_data_normalized).view(-1)
test_data_normalized torch.FloatTensor(test_data_normalized).view(-1)def create_inout_sequences(input_data, tw, pre_len):inout_seq []L len(input_data)for i in range(L - tw):train_seq input_data[i:i tw]if (i tw 4) len(input_data):breaktrain_label input_data[i tw:i tw pre_len]inout_seq.append((train_seq, train_label))return inout_seqpre_len 4
train_window 16
# 定义训练器的的输入
train_inout_seq create_inout_sequences(train_data_normalized, train_window, pre_len)class LSTM(nn.Module):def __init__(self, input_dim1, hidden_dim350, output_dim1):super(LSTM, self).__init__()self.hidden_dim hidden_dimself.lstm nn.LSTM(input_dim, hidden_dim, batch_firstTrue)self.fc nn.Linear(hidden_dim, output_dim)def forward(self, x):x x.unsqueeze(1)h0_lstm torch.zeros(1, self.hidden_dim).to(x.device)c0_lstm torch.zeros(1, self.hidden_dim).to(x.device)out, _ self.lstm(x, (h0_lstm, c0_lstm))out out[:, -1]out self.fc(out)return outlstm_model LSTM(input_dim1, output_dimpre_len, hidden_dimtrain_window)
loss_function nn.MSELoss()
optimizer torch.optim.Adam(lstm_model.parameters(), lr0.001)
epochs 10
Train True # 训练还是预测if Train:losss []lstm_model.train() # 训练模式start_time time.time() # 计算起始时间for i in range(epochs):for seq, labels in train_inout_seq:lstm_model.train()optimizer.zero_grad()y_pred lstm_model(seq)single_loss loss_function(y_pred, labels)single_loss.backward()optimizer.step()print(fepoch: {i:3} loss: {single_loss.item():10.8f})losss.append(single_loss.detach().numpy())torch.save(lstm_model.state_dict(), save_model.pth)print(f模型已保存,用时:{(time.time() - start_time) / 60:.4f} min)plt.plot(losss)# 设置图表标题和坐标轴标签plt.title(Training Error)plt.xlabel(Epoch)plt.ylabel(Error)# 保存图表到本地plt.savefig(training_error.png)
else:# 加载模型进行预测lstm_model.load_state_dict(torch.load(save_model.pth))lstm_model.eval() # 评估模式results []reals []losss []test_inout_seq create_inout_sequences(test_data_normalized, train_window, pre_len)for seq, labels in train_inout_seq:pred lstm_model(seq)[0].item()results.append(pred)mae calculate_mae(pred, labels.detach().numpy()) # MAE误差计算绝对值(预测值 - 真实值)reals.append(labels.detach().numpy())losss.append(mae)print(模型预测结果, results)print(预测误差MAE:, losss)plt.style.use(ggplot)# 创建折线图plt.plot(results, labelreal, colorblue) # 实际值plt.plot(reals, labelforecast, colorred, linestyle--) # 预测值# 增强视觉效果plt.grid(True)plt.title(real vs forecast)plt.xlabel(time)plt.ylabel(value)plt.legend()plt.savefig(test——results.png)
数据格式
运行上述代码需要只需要一列数据即可,并且最后数据需要是一个pd.series类型,大家可以在读取进来文件后面加一些数据的处理操作。 (需要注意的是大家的数据不要打乱时间顺序否则预测出来的结果可能不准)
代码讲解
在上面的运行代码中,主要填写的是在下面填上你的数据目录,
true_data pd.read_csv() # 填你自己的数据地址
这里是定义了test_data_size是指根据过去多少条数据来预测未来的预测值
test_size和train_size代表训练集和测试集的尺寸划分。
# 定义窗口大小
test_data_size 350
# 训练集和测试集的尺寸划分
test_size 0.15
train_size 0.85
这里定义了数据加载器的操作
def create_inout_sequences(input_data, tw):inout_seq []L len(input_data)for i in range(L - tw):train_seq input_data[i:i tw]if (i tw 4) len(input_data):breaktrain_label input_data[i tw:i tw 1]inout_seq.append((train_seq, train_label))return inout_seqtrain_window 350
# 定义训练器的的输入
train_inout_seq create_inout_sequences(train_data_normalized, train_window)
模型的本身其中包含一个LSTM层和一个全连接层进行结果的输出
class LSTM(nn.Module):def __init__(self, input_dim1, hidden_dim350, output_dim1):super(LSTM, self).__init__()self.hidden_dim hidden_dimself.lstm nn.LSTM(input_dim, hidden_dim, batch_firstTrue)self.fc nn.Linear(hidden_dim, output_dim)def forward(self, x):x x.unsqueeze(1)h0_lstm torch.zeros(1, self.hidden_dim).to(x.device)c0_lstm torch.zeros(1, self.hidden_dim).to(x.device)out, _ self.lstm(x, (h0_lstm, c0_lstm))out out[:, -1]out self.fc(out)return out
这里定义了模型损失函数和优化器,其中的Train代表着是否进行训练。
lstm_model LSTM()
loss_function nn.MSELoss()
optimizer torch.optim.Adam(lstm_model.parameters(), lr0.001)
epochs 20
Train False # 训练还是预测
当Train为True时则开始训练并在最好将模型保存到本地,训练好模型之后我门将Train设置为False则开始评估模式。
if Train:losss []lstm_model.train() # 训练模式for i in range(epochs):start_time time.time() # 计算起始时间for seq, labels in train_inout_seq:lstm_model.train()optimizer.zero_grad()y_pred lstm_model(seq)single_loss loss_function(y_pred, labels)losss.append(single_loss.detach().numpy())single_loss.backward()optimizer.step()if i % 1 1:print(fepoch: {i:3} loss: {single_loss.item():10.8f})torch.save(lstm_model.state_dict(), save_model.pth)print(f模型已保存,用时:{(time.time() - start_time) / 60:.4f} min)plt.plot(losss)# 设置图表标题和坐标轴标签plt.title(Training Error)plt.xlabel(Epoch)plt.ylabel(Error)# 保存图表到本地plt.savefig(training_error.png)
else:# 加载模型进行预测lstm_model.load_state_dict(torch.load(save_model.pth))lstm_model.eval() # 评估模式results []losss []test_inout_seq create_inout_sequences(test_data_normalized, train_window)for seq, labels in test_inout_seq:# 这里的pred lstm_model(seq)[0].item()是结果的输出这里只保存了输出的第一个值如果想拿出更多的预测值可以修改数字0用切片的方式pred lstm_model(seq)[0].item()results.append(pred)mae calculate_mae(pred, labels.detach().numpy()) # MAE误差计算绝对值(预测值 - 真实值)losss.append(mae)print(模型预测结果, results)print(预测误差MAE:, losss)
后期我也会讲一些最新的预测模型包括InformerTPA-LSTM,ARIMA,XGBOOST,Holt-winter移动平均法等等一系列关于时间序列预测的模型,包括深度学习和机器学习方向的模型我都会讲,你可以根据需求选取适合你自己的模型进行预测如果有需要可以个关注包括本次模型我自己的代码大家有需要我也会放出百度网盘下载链接
其它时间序列预测模型的讲解
--------------------------------------------------------MTS-Mixers---------------------------------------------------------
【全网首发】(MTS-Mixers)(Python)(Pytorch)最新由华为发布的时间序列预测模型实战案例(一)(包括代码讲解)实现企业级预测精度包括官方代码BUG修复Transform模型 --------------------------------------------------------Holt-Winters--------------------------------------------------------
时间序列预测模型实战案例(二)(Holt-Winter)(Python)结合K-折交叉验证进行时间序列预测实现企业级预测精度(包括运行代码以及代码讲解)
如果大家有不懂的也可以评论区留言一些报错什么的大家可以讨论讨论看到我也会给大家解答如何解决