Pytorch 的 LSTM 模型的示例教程

作者:许野平 时间:2021-08-01 22:28:41 

1. 代码

完整的源代码:

import torch
from torch import nn
# 定义一个LSTM模型
class LSTM(nn.Module):
   def __init__(self, input_size, hidden_size, num_layers, output_size):
       super(LSTM, self).__init__()
       self.hidden_size = hidden_size
       self.num_layers = num_layers
       self.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, c0为全0向量
       h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
       c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
       # 将输入x和隐藏状态(h0, c0)传入LSTM网络
       out, _ = self.lstm(x, (h0, c0))
       # 取最后一个时间步的输出作为LSTM网络的输出
       out = self.fc(out[:, -1, :])
       return out
# 定义LSTM超参数
input_size = 10   # 输入特征维度
hidden_size = 32  # 隐藏单元数量
num_layers = 2    # LSTM层数
output_size = 2   # 输出类别数量
# 构建一个随机输入x和对应标签y
x = torch.randn(64, 5, 10)  # [batch_size, sequence_length, input_size]
y = torch.randint(0, 2, (64,))  # 二分类任务,标签为0或1
# 创建LSTM模型,并将输入x传入模型计算预测输出
lstm = LSTM(input_size, hidden_size, num_layers, output_size)
pred = lstm(x)  # [batch_size, output_size]
# 定义损失函数和优化器,并进行模型训练
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(lstm.parameters(), lr=1e-3)
num_epochs = 100
for epoch in range(num_epochs):
   # 前向传播计算损失函数值
   pred = lstm(x)  # 在每个epoch中重新计算预测输出
   loss = criterion(pred.squeeze(), y)
   # 反向传播更新模型参数
   optimizer.zero_grad()
   loss.backward()
   optimizer.step()
   # 输出每个epoch的训练损失
   print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")

2. 模型结构分析

# 定义一个LSTM模型
class LSTM(nn.Module):
   def __init__(self, input_size, hidden_size, num_layers, output_size):
       super(LSTM, self).__init__()
       self.hidden_size = hidden_size
       self.num_layers = num_layers
       self.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, c0为全0向量
       h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
       c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
       # 将输入x和隐藏状态(h0, c0)传入LSTM网络
       out, _ = self.lstm(x, (h0, c0))
       # 取最后一个时间步的输出作为LSTM网络的输出
       out = self.fc(out[:, -1, :])
       return out

上述代码定义了一个LSTM类,这个类可以用于完成一个基于LSTM的序列模型的搭建。

在初始化函数中,输入的参数分别是输入数据的特征维度(input_size),隐藏层的大小(hidden_size),LSTM层数(num_layers)以及输出数据的维度(output_size)。这里使用batch_first=True表示输入数据的第一个维度是batch size,第二个维度是时间步长和特征维度。

在forward函数中,首先初始化了LSTM网络的隐藏状态为全0向量,并且将其移动到与输入数据相同的设备上。然后调用了nn.LSTM函数进行前向传播操作,并且通过fc层将最后一个时间步的输出映射为输出的数据,最后进行了返回。

3. 代码详解

# 将输入x和隐藏状态(h0, c0)传入LSTM网络
       out, _ = self.lstm(x, (h0, c0))

这行代码是利用 PyTorch 自带的 LSTM 模块处理输入张量 x(形状为 [batch_size, sequence_length, input_size])并得到 LSTM 层的输出 out 和最终状态。其中,h0 是 LSTM 层的初始隐藏状态,c0 是 LSTM 层的初始细胞状态。

在代码中,调用了 self.lstm(x, (h0, c0)) 函数,该函数的返回值有两个:第一个返回值是 LSTM 层的输出 out,其包含了所有时间步上的隐状态;第二个返回值是一个元组,包含了最后一个时间步的隐藏状态和细胞状态,但我们用“_”丢弃了它。

因为对于许多深度学习任务来说,只需要输出序列的最后一个时间步的隐藏状态,而不需要每个时间步上的隐藏状态。因此,这里我们只保留 LSTM 层的输出 out,而忽略了 LSTM 层最后时间步的状态。

最后,out 的形状为 [batch_size, sequence_length, hidden_size],其中 hidden_size 是 LSTM 层输出的隐藏状态的维度大小。

x = torch.randn(64, 5, 10)

这行代码创建了一个形状为 (64, 5, 10) 的张量 x,它包含 64 个样本,每个样本具有 5 个特征维度和 10 个时间步。该张量的值是由均值为 0,标准差为 1 的正态分布随机生成的。

torch.randn() 是 PyTorch 中生成服从标准正态分布的随机数的函数。它的输入是张量的形状,输出是符合正态分布的张量。在本例中,形状为 (64, 5, 10) 表示该张量包含 64 个样本,每个样本包含 5 个特征维度和 10 个时间步,每个元素都是服从标准正态分布的随机数。这种方式生成的随机数可以用于初始化模型参数、生成噪音数据等许多深度学习应用场景。

y = torch.randint(0, 2, (64,))  # 二分类任务,标签为0或1

y = torch.randint(0, 2, (64,)) 是使用 PyTorch 库中的 randint() 函数来生成一个64个元素的张量 y,张量的每个元素都是从区间 [0, 2) 中随机生成的整数。

具体而言,torch.randint() 函数包含三个参数,分别是 low、high 和 size。其中,low 和 high 分别表示随机生成整数的区间为 [low, high),而 size 参数指定了生成的张量的形状。

在上述代码中,size=(64,) 表示生成的张量 y 的形状为 64x1,即一个包含 64 个元素的一维张量,并且每个元素的值都在 [0, 2) 中随机生成。这种形式的张量通常用于分类问题中的标签向量。在该任务中,一个标签通常由一个整数表示,因此可以采用使用 randint() 函数生成一个长度为标签类别数的一维张量,其每个元素的取值为 0 或 1,表示对应类别是否被选中。

# 创建LSTM模型,并将输入x传入模型计算预测输出
lstm = LSTM(input_size, hidden_size, num_layers, output_size)
pred = lstm(x)  # [batch_size, output_size]

通过定义的LSTM类创建了一个LSTM模型,并将输入x传入模型进行前向计算,得到了一个预测输出pred,其形状为[64, output_size],其中output_size是在LSTM初始化函数中指定的输出数据的维度。

这段代码演示了如何使用已经构建好的代码搭建并训练一个基于LSTM的序列模型,并且展示了其中的一些关键步骤,包括数据输入、模型创建以及前向计算。

来源:https://blog.csdn.net/quicmous/article/details/130914649

标签:Pytorch,LSTM,模型
0
投稿

猜你喜欢

  • python基础之while循环语句的使用

    2021-03-16 16:54:20
  • js验证表单(form)中的单选(radio)值

    2008-03-18 13:23:00
  • python实现计数排序与桶排序实例代码

    2023-12-28 11:32:37
  • mysql使用LOAD语句批量录入数据方法

    2010-03-09 16:31:00
  • python 基础学习第二弹 类属性和实例属性

    2023-08-02 04:07:44
  • 使用Python快乐学数学Github万星神器Manim简介

    2022-07-03 04:28:00
  • Python+Pygame实战之疯狂吃水果游戏的实现

    2021-09-17 11:37:58
  • js控制table合并具体实现

    2023-08-05 11:20:12
  • python魔法方法-自定义序列详解

    2022-10-08 08:56:12
  • Django集成MongoDB实现过程解析

    2022-07-10 03:32:35
  • 如何用ASP实现文章点击数?

    2008-08-11 21:17:00
  • mysql中limit的用法深入分析

    2024-01-21 17:28:17
  • 利用Python实现某OA系统的自动定位功能

    2021-05-26 02:27:46
  • MySQL查询条件常见用法详解

    2024-01-16 10:10:22
  • 详解如何利用Python绘制科赫曲线

    2023-05-02 15:26:42
  • javascript中if和switch,==和===详解

    2024-04-22 13:23:28
  • SQL Server 数据库管理常用的SQL和T-SQL语句

    2024-01-27 22:01:09
  • Python使用win32com.client的方法示例

    2021-03-22 14:32:48
  • VS2019 自定义项目模板的实现方法

    2022-05-08 21:14:23
  • 浅谈JavaScript中的“!!”作用

    2024-05-05 09:04:53
  • asp之家 网络编程 m.aspxhome.com