Pytorch实现LSTM案例总结学习

目录
  • 前言
  • 模型构建部分主要工作
    • 1、构建网络层、前向传播forward()
    • 2、实例化网络,定义损失函数和优化器
    • 3、训练模型、反向传播backward()
    • 4、测试模型

前言

关键步骤主要分为数据准备和模型构建两大部分,其中,

数据准备主要工作:

  • 1、训练集和测试集的划分
  • 2、训练数据的归一化
  • 3、规范输入数据的格式

模型构建部分主要工作

1、构建网络层、前向传播forward()

class LSTM(nn.Module):#注意Module首字母需要大写
    def __init__(self, input_size=1, hidden_layer_size=100, output_size=1):
        super().__init__()
        self.hidden_layer_size = hidden_layer_size

        # 创建LSTM层和linear层,LSTM层提取特征,linear层用作最后的预测
        # LSTM算法接受三个输入:先前的隐藏状态,先前的单元状态和当前输入。
        self.lstm = nn.LSTM(input_size, hidden_layer_size)
        self.linear = nn.Linear(hidden_layer_size, output_size)

        #初始化隐含状态及细胞状态C,hidden_cell变量包含先前的隐藏状态和单元状态
        self.hidden_cell = (torch.zeros(1, 1, self.hidden_layer_size),
                            torch.zeros(1, 1, self.hidden_layer_size))
                            # 为什么的第二个参数也是1
                            # 第二个参数代表的应该是batch_size吧
                            # 是因为之前对数据已经进行过切分了吗?????

    def forward(self, input_seq):
    	#lstm的输出是当前时间步的隐藏状态ht和单元状态ct以及输出lstm_out
        lstm_out, self.hidden_cell = self.lstm(input_seq.view(len(input_seq), 1, -1), self.hidden_cell)
        #按照lstm的格式修改input_seq的形状,作为linear层的输入
        predictions = self.linear(lstm_out.view(len(input_seq), -1))
        #返回predictions的最后一个元素
        return predictions[-1]

定义好每层之后,最后还需要通过前向传播的方式把这些串起来,这就涉及如何定义forward函数。

forward函数的任务需要把输入层、网络层、输出层链接起来,实现信息的前向传导。

forward该函数的参数一般为输入数据,返回值是输出数据。

2、实例化网络,定义损失函数和优化器

#创建LSTM()类的对象,定义损失函数和优化器
model = LSTM()
loss_function = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)#建立优化器实例
print(model)

3、训练模型、反向传播backward()

epochs = 150
for i in range(epochs):
    for seq, labels in train_inout_seq:
        #清除网络先前的梯度值
        optimizer.zero_grad()
        #初始化隐藏层数据
        model.hidden_cell = (torch.zeros(1, 1, model.hidden_layer_size),
                             torch.zeros(1, 1, model.hidden_layer_size))
        #实例化模型
        y_pred = model(seq)

        #计算损失,反向传播梯度以及更新模型参数
        #训练过程中,正向传播生成网络的输出,计算输出和实际值之间的损失值
        single_loss = loss_function(y_pred, labels)
        single_loss.backward()#调用backward()自动生成梯度
        optimizer.step()#使用optimizer.step()执行优化器,把梯度传播回每个网络

    # 查看模型训练的结果
    if i%25 == 1:
        print(f'epoch:{i:3} loss:{single_loss.item():10.8f}')
print(f'epoch:{i:3} loss:{single_loss.item():10.10f}')

训练模型时需要使模型处于训练模式,即调用model.train()。

缺省情况下梯度是累加的,需要手工把梯度初始化或者清零,调用optimizer.zero_grad()。

在训练过程中正向传播生成网络的输出,计算输出与实际值之间的损失值。调用loss.backward()自动生成反向传播梯度,然后使用optimizer.step()执行优化器,把梯度传播回每个网络。

实现梯度反向传播的方法主要是复合函数的链式法则。Pytorch提供了自动反向传播的功能,使用nn工具箱,无需自己编写反向传播,直接让损失函数调用backward()即可。

反向传播中,优化器十分重要,这类优化算法通过使用参数的梯度值更新参数。

4、测试模型

fut_pred = 12
test_inputs = train_data_normalized[-train_window:].tolist()#首先打印出数据列表的最后12个值
print(test_inputs)

#更改模型为测试或者验证模式
model.eval()#把training属性设置为false,使模型处于测试或验证状态
for i in range(fut_pred):
    seq = torch.FloatTensor(test_inputs[-train_window:])
    with torch.no_grad():
        model.hidden = (torch.zeros(1, 1, model.hidden_layer_size),
                        torch.zeros(1, 1, model.hidden_layer_size))
        test_inputs.append(model(seq).item())
#打印最后的12个预测值
print(test_inputs[fut_pred:])
#由于对训练集数据进行了标准化,因此预测数据也是标准化了的
#需要将归一化的预测值转换为实际的预测值。通过inverse_transform实现
actual_predictions = scaler.inverse_transform(np.array(test_inputs[train_window:]).reshape(-1, 1))
print(actual_predictions)

全部代码如下:

import torch
import torch.nn as nn
import torch.nn.functional
import seaborn as sns
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
"""
导入数据
"""
flight_data = sns.load_dataset("flights")
print(flight_data.head())
print(flight_data.shape)

#绘制每月乘客的出行频率
fig_size = plt.rcParams['figure.figsize']
fig_size[0] = 15
fig_size[1] = 5
plt.rcParams['figure.figsize'] = fig_size
plt.title('Month vs Passenger')
plt.ylabel('Total Passengers')
plt.xlabel('Months')
plt.grid(True)
plt.autoscale(axis='x',tight=True)
plt.plot(flight_data['passengers'])
plt.show()

"""
数据预处理
"""
flight_data.columns#显示数据集中 列的数据类型
all_data = flight_data['passengers'].values.astype(float)#将passengers列的数据类型改为float
#划分测试集和训练集
test_data_size = 12
train_data = all_data[:-test_data_size]#除了最后12个数据,其他全取
test_data = all_data[-test_data_size:]#取最后12个数据
print(len(train_data))
print(len(test_data))

#最大最小缩放器进行归一化,减小误差,注意,数据标准化只应用于训练数据而不应用于测试数据
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(-1, 1))
train_data_normalized = scaler.fit_transform(train_data.reshape(-1, 1))
#查看归一化之后的前5条数据和后5条数据
print(train_data_normalized[:5])
print(train_data_normalized[-5:])
#将数据集转换为tensor,因为PyTorch模型是使用tensor进行训练的,并将训练数据转换为输入序列和相应的标签
train_data_normalized = torch.FloatTensor(train_data_normalized).view(-1)
#view相当于numpy中的resize,参数代表数组不同维的维度;
#参数为-1表示,这个维的维度由机器自行推断,如果没有-1,那么view中的所有参数就要和tensor中的元素总个数一致

#定义create_inout_sequences函数,接收原始输入数据,并返回一个元组列表。
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]
        train_label = input_data[i+tw:i+tw+1]#预测time_step之后的第一个数值
        inout_seq.append((train_seq, train_label))#inout_seq内的数据不断更新,但是总量只有tw+1个
    return inout_seq
train_window = 12#设置训练输入的序列长度为12,类似于time_step = 12
train_inout_seq = create_inout_sequences(train_data_normalized, train_window)
print(train_inout_seq[:5])#产看数据集改造结果
"""
注意:
create_inout_sequences返回的元组列表由一个个序列组成,
每一个序列有13个数据,分别是设置的12个数据(train_window)+ 第13个数据(label)
第一个序列由前12个数据组成,第13个数据是第一个序列的标签。
同样,第二个序列从第二个数据开始,到第13个数据结束,而第14个数据是第二个序列的标签,依此类推。
"""

"""
创建LSTM模型
参数说明:
1、input_size:对应的及特征数量,此案例中为1,即passengers
2、output_size:预测变量的个数,及数据标签的个数
2、hidden_layer_size:隐藏层的特征数,也就是隐藏层的神经元个数
"""
class LSTM(nn.Module):#注意Module首字母需要大写
    def __init__(self, input_size=1, hidden_layer_size=100, output_size=1):
        super().__init__()
        self.hidden_layer_size = hidden_layer_size

        # 创建LSTM层和linear层,LSTM层提取特征,linear层用作最后的预测
        ##LSTM算法接受三个输入:先前的隐藏状态,先前的单元状态和当前输入。
        self.lstm = nn.LSTM(input_size, hidden_layer_size)
        self.linear = nn.Linear(hidden_layer_size, output_size)

        #初始化隐含状态及细胞状态C,hidden_cell变量包含先前的隐藏状态和单元状态
        self.hidden_cell = (torch.zeros(1, 1, self.hidden_layer_size),
                            torch.zeros(1, 1, self.hidden_layer_size))
                            # 为什么的第二个参数也是1
                            # 第二个参数代表的应该是batch_size吧
                            # 是因为之前对数据已经进行过切分了吗?????

    def forward(self, input_seq):
        lstm_out, self.hidden_cell = self.lstm(input_seq.view(len(input_seq), 1, -1), self.hidden_cell)
        #lstm的输出是当前时间步的隐藏状态ht和单元状态ct以及输出lstm_out
        #按照lstm的格式修改input_seq的形状,作为linear层的输入
        predictions = self.linear(lstm_out.view(len(input_seq), -1))
        return predictions[-1]#返回predictions的最后一个元素
"""
forward方法:LSTM层的输入与输出:out, (ht,Ct)=lstm(input,(h0,C0)),其中
一、输入格式:lstm(input,(h0, C0))
1、input为(seq_len,batch,input_size)格式的tensor,seq_len即为time_step
2、h0为(num_layers * num_directions, batch, hidden_size)格式的tensor,隐藏状态的初始状态
3、C0为(seq_len, batch, input_size)格式的tensor,细胞初始状态
二、输出格式:output,(ht,Ct)
1、output为(seq_len, batch, num_directions*hidden_size)格式的tensor,包含输出特征h_t(源于LSTM每个t的最后一层)
2、ht为(num_layers * num_directions, batch, hidden_size)格式的tensor,
3、Ct为(num_layers * num_directions, batch, hidden_size)格式的tensor,
"""

#创建LSTM()类的对象,定义损失函数和优化器
model = LSTM()
loss_function = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)#建立优化器实例
print(model)

"""
模型训练
batch-size是指1次迭代所使用的样本量;
epoch是指把所有训练数据完整的过一遍;
由于默认情况下权重是在PyTorch神经网络中随机初始化的,因此可能会获得不同的值。
"""
epochs = 150
for i in range(epochs):
    for seq, labels in train_inout_seq:
        #清除网络先前的梯度值
        optimizer.zero_grad()#训练模型时需要使模型处于训练模式,即调用model.train()。缺省情况下梯度是累加的,需要手工把梯度初始化或者清零,调用optimizer.zero_grad()
        #初始化隐藏层数据
        model.hidden_cell = (torch.zeros(1, 1, model.hidden_layer_size),
                             torch.zeros(1, 1, model.hidden_layer_size))
        #实例化模型
        y_pred = model(seq)
        #计算损失,反向传播梯度以及更新模型参数
        single_loss = loss_function(y_pred, labels)#训练过程中,正向传播生成网络的输出,计算输出和实际值之间的损失值
        single_loss.backward()#调用loss.backward()自动生成梯度,
        optimizer.step()#使用optimizer.step()执行优化器,把梯度传播回每个网络

    # 查看模型训练的结果
    if i%25 == 1:
        print(f'epoch:{i:3} loss:{single_loss.item():10.8f}')
print(f'epoch:{i:3} loss:{single_loss.item():10.10f}')

"""
预测
注意,test_input中包含12个数据,
在for循环中,12个数据将用于对测试集的第一个数据进行预测,然后将预测值附加到test_inputs列表中。
在第二次迭代中,最后12个数据将再次用作输入,并进行新的预测,然后 将第二次预测的新值再次添加到列表中。
由于测试集中有12个元素,因此该循环将执行12次。
循环结束后,test_inputs列表将包含24个数据,其中,最后12个数据将是测试集的预测值。
"""
fut_pred = 12
test_inputs = train_data_normalized[-train_window:].tolist()#首先打印出数据列表的最后12个值
print(test_inputs)

#更改模型为测试或者验证模式
model.eval()#把training属性设置为false,使模型处于测试或验证状态
for i in range(fut_pred):
    seq = torch.FloatTensor(test_inputs[-train_window:])
    with torch.no_grad():
        model.hidden = (torch.zeros(1, 1, model.hidden_layer_size),
                        torch.zeros(1, 1, model.hidden_layer_size))
        test_inputs.append(model(seq).item())
#打印最后的12个预测值
print(test_inputs[fut_pred:])
#由于对训练集数据进行了标准化,因此预测数据也是标准化了的
#需要将归一化的预测值转换为实际的预测值。通过inverse_transform实现
actual_predictions = scaler.inverse_transform(np.array(test_inputs[train_window:]).reshape(-1, 1))
print(actual_predictions)

"""
根据实际值,绘制预测值
"""
x = np.arange(132, 132+fut_pred, 1)
plt.title('Month vs Passenger')
plt.ylabel('Total Passengers')
plt.xlabel('Months')
plt.grid(True)
plt.autoscale(axis='x', tight=True)
plt.plot(flight_data['passengers'])
plt.plot(x, actual_predictions)
plt.show()
#绘制最近12个月的实际和预测乘客数量,以更大的尺度观测数据
plt.title('Month vs Passenger')
plt.ylabel('Total Passengers')
plt.xlabel('Months')
plt.grid(True)
plt.autoscale(axis='x', tight=True)
plt.plot(flight_data['passengers'][-train_window:])
plt.plot(x, actual_predictions)
plt.show()

到此这篇关于Pytorch实现LSTM案例总结学习的文章就介绍到这了,更多相关Pytorch实现LSTM内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • PyTorch搭建LSTM实现多变量时序负荷预测

    目录 I. 前言 II. 数据处理 III. LSTM模型 IV. 训练 V. 测试 VI. 源码及数据 I. 前言 在前面的一篇文章PyTorch搭建LSTM实现时间序列预测(负荷预测)中,我们利用LSTM实现了负荷预测,但我们只是简单利用负荷预测负荷,并没有利用到其他一些环境变量,比如温度.湿度等. 本篇文章主要考虑用PyTorch搭建LSTM实现多变量时间序列预测. 系列文章: PyTorch搭建LSTM实现多变量多步长时序负荷预测 PyTorch深度学习LSTM从input输入到Line

  • PyTorch搭建LSTM实现时间序列负荷预测

    目录 I. 前言 II. 数据处理 III. LSTM模型 IV. 训练 V. 测试 VI. 源码及数据 I. 前言 在上一篇文章深入理解PyTorch中LSTM的输入和输出(从input输入到Linear输出)中,我详细地解释了如何利用PyTorch来搭建一个LSTM模型,本篇文章的主要目的是搭建一个LSTM模型用于时间序列预测. 系列文章: PyTorch搭建LSTM实现多变量多步长时序负荷预测 PyTorch搭建LSTM实现多变量时序负荷预测 PyTorch深度学习LSTM从input输入

  • Pytorch-LSTM输入输出参数方式

    目录 1.Pytorch中的LSTM中输入输出参数 2.输入数据(以batch_first=True,单层单向为例) 3.输入数据(以batch_first=True,双层双向) Pytorch-LSTM函数参数解释 图解 torch.nn.LSTM函数 图解LSTM函数 1.Pytorch中的LSTM中输入输出参数 nn.lstm是继承nn.RNNBase,初始化的定义如下: class RNNBase(Module): ... def __init__(self, mode, input_s

  • PyTorch搭建双向LSTM实现时间序列负荷预测

    目录 I. 前言 II. 原理 Inputs Outputs batch_first 输出提取 III. 训练和预测 IV. 源码及数据 I. 前言 前面几篇文章中介绍的都是单向LSTM,这篇文章讲一下双向LSTM. 系列文章: PyTorch搭建LSTM实现多变量多步长时序负荷预测 PyTorch搭建LSTM实现多变量时序负荷预测 PyTorch深度学习LSTM从input输入到Linear输出 PyTorch搭建LSTM实现时间序列负荷预测 II. 原理 关于LSTM的输入输出在深入理解Py

  • PyTorch训练LSTM时loss.backward()报错的解决方案

    训练用PyTorch编写的LSTM或RNN时,在loss.backward()上报错: RuntimeError: Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time. 千万别改成loss.backward(retain_graph=Tru

  • Pytorch 如何实现LSTM时间序列预测

    开发环境说明: Python 35 Pytorch 0.2 CPU/GPU均可 1.LSTM简介 人类在进行学习时,往往不总是零开始,学习物理你会有数学基础.学习英语你会有中文基础等等. 于是对于机器而言,神经网络的学习亦可不再从零开始,于是出现了Transfer Learning,就是把一个领域已训练好的网络用于初始化另一个领域的任务,例如会下棋的神经网络可以用于打德州扑克. 我们这讲的是另一种不从零开始学习的神经网络--循环神经网络(Recurrent Neural Network, RNN

  • Pytorch实现LSTM案例总结学习

    目录 前言 模型构建部分主要工作 1.构建网络层.前向传播forward() 2.实例化网络,定义损失函数和优化器 3.训练模型.反向传播backward() 4.测试模型 前言 关键步骤主要分为数据准备和模型构建两大部分,其中, 数据准备主要工作: 1.训练集和测试集的划分 2.训练数据的归一化 3.规范输入数据的格式 模型构建部分主要工作 1.构建网络层.前向传播forward() class LSTM(nn.Module):#注意Module首字母需要大写 def __init__(sel

  • 深入学习PyTorch中LSTM的输入和输出

    目录 LSTM参数 Inputs Outputs 案例 LSTM参数 官方文档给出的解释为: 总共有七个参数,其中只有前三个是必须的.由于大家普遍使用PyTorch的DataLoader来形成批量数据,因此batch_first也比较重要.LSTM的两个常见的应用场景为文本处理和时序预测,因此下面对每个参数我都会从这两个方面来进行具体解释. input_size:在文本处理中,由于一个单词没法参与运算,因此我们得通过Word2Vec来对单词进行嵌入表示,将每一个单词表示成一个向量,此时input

  • PyTorch搭建LSTM实现多变量多步长时序负荷预测

    目录 I. 前言 II. 数据处理 III. LSTM模型 IV. 训练和预测 V. 源码及数据 I. 前言 在前面的两篇文章PyTorch搭建LSTM实现时间序列预测(负荷预测)和PyTorch搭建LSTM实现多变量时间序列预测(负荷预测)中,我们利用LSTM分别实现了单变量单步长时间序列预测和多变量单步长时间序列预测. 本篇文章主要考虑用PyTorch搭建LSTM实现多变量多步长时间序列预测. 系列文章: PyTorch搭建双向LSTM实现时间序列负荷预测 PyTorch搭建LSTM实现多变

  • pytorch 利用lstm做mnist手写数字识别分类的实例

    代码如下,U我认为对于新手来说最重要的是学会rnn读取数据的格式. # -*- coding: utf-8 -*- """ Created on Tue Oct 9 08:53:25 2018 @author: www """ import sys sys.path.append('..') import torch import datetime from torch.autograd import Variable from torch im

  • Pytorch实现LSTM和GRU示例

    为了解决传统RNN无法长时依赖问题,RNN的两个变体LSTM和GRU被引入. LSTM Long Short Term Memory,称为长短期记忆网络,意思就是长的短时记忆,其解决的仍然是短时记忆问题,这种短时记忆比较长,能一定程度上解决长时依赖. 上图为LSTM的抽象结构,LSTM由3个门来控制,分别是输入门.遗忘门和输出门.输入门控制网络的输入,遗忘门控制着记忆单元,输出门控制着网络的输出.最为重要的就是遗忘门,可以决定哪些记忆被保留,由于遗忘门的作用,使得LSTM具有长时记忆的功能.对于

  • 基于pytorch的lstm参数使用详解

    lstm(*input, **kwargs) 将多层长短时记忆(LSTM)神经网络应用于输入序列. 参数: input_size:输入'x'中预期特性的数量 hidden_size:隐藏状态'h'中的特性数量 num_layers:循环层的数量.例如,设置' ' num_layers=2 ' '意味着将两个LSTM堆叠在一起,形成一个'堆叠的LSTM ',第二个LSTM接收第一个LSTM的输出并计算最终结果.默认值:1 bias:如果' False',则该层不使用偏置权重' b_ih '和' b

  • pytorch SENet实现案例

    我就废话不多说了,大家还是直接看代码吧~ from torch import nn class SELayer(nn.Module): def __init__(self, channel, reduction=16): super(SELayer, self).__init__() //返回1X1大小的特征图,通道数不变 self.avg_pool = nn.AdaptiveAvgPool2d(1) self.fc = nn.Sequential( nn.Linear(channel, cha

  • Pytorch模型定义与深度学习自查手册

    目录 定义神经网络 权重初始化 方法1:net.apply(weights_init) 方法2:在网络初始化的时候进行参数初始化 常用的操作 利用nn.Parameter()设计新的层 nn.Flatten nn.Sequential 常用的层 全连接层nn.Linear() torch.nn.Dropout 卷积torch.nn.ConvNd() 池化 最大池化torch.nn.MaxPoolNd() 均值池化torch.nn.AvgPoolNd() 反池化 最大值反池化nn.MaxUnpoo

随机推荐