【深度学习】LSTM、BiLSTM详解

文章目录

  • [1. LSTM简介:](#1. LSTM简介:)
  • [2. LSTM结构图:](#2. LSTM结构图:)
  • [3. 单层LSTM详解](#3. 单层LSTM详解)
  • [4. 双层LSTM详解](#4. 双层LSTM详解)
  • [5. BiLSTM](#5. BiLSTM)
  • [6. Pytorch实现LSTM示例](#6. Pytorch实现LSTM示例)
  • [7. nn.LSTM参数详解](#7. nn.LSTM参数详解)

1. LSTM简介:

LSTM是一种循环神经网络,它可以处理和预测时间序列中间隔和延迟相对较长的重要事件。LSTM通过使用门控单元来控制信息的流动,从而缓解RNN中的梯度消失和梯度爆炸的问题。LSTM的核心是三个门:输入门遗忘门输出门

遗忘门: 遗忘门的作用是决定哪些信息从记忆单元中遗忘,它使用sigmoid激活函数,可以输出在0到1之间的值,可以理解为保留信息的比例。
输入门: 作用是决定哪些新信息被存储在记忆单元中
输出门: 输出门决定了下一个隐藏状态,即生成当前时间步的输出并传递到下一时间步
记忆单元:负责长期信息的存储,通过遗忘门和输入门的相互作用,记忆单元能够学习如何选择性地记住或忘记信息

2. LSTM结构图:

涉及到的计算公式如下:

3. 单层LSTM详解

(1)设定有3个字的序列【"早""上""好"】要经过LSTM处理,每个序列由20个元素组成的列向量构成,所以input size就为20。

(2)设定全连接层中有100个隐藏单元,LSTM的层数为1。

(3)因为是3个字的序列,所以LSTM需要3个时间步(即会自循环3次)才能处理完这个序列。

(4)nn.LSTM()每层也可以拆开写,这样每层的隐藏单元个数就可以分别设定。

LSTM单元包含三个输入参数x、c、h;首先t1时刻作为第一个时间步,输入到第一个LSTM单元中,此时输入的初始从c(0)和h(0)都是0矩阵,计算完成后,第一个LSTM单元输出一组h(t1)\c(t1),作为本层LSTM的第二个时间步的输入参数;因此第二个时间步的输入就是h(t1),c(t1),x(t2),而输出是h(t2),c(t2);因此第三个时间步的输入就是h(t2),c(t2),x(t3),而输出是h(t3),c(t3)。

4. 双层LSTM详解

(1)设定有3个字的序列【"早""上""好"】要经过LSTM处理,每个序列由20个元素组成的列向量构成,所以input size就为20。

(2)设定全连接层中有100个隐藏单元,LSTM的层数为2。

(3)因为是3个字的序列,所以LSTM需要3个时间步(即会自循环3次)才能处理完这个序列。

(4)nn.LSTM()每层也可以拆开写,这样每层的隐藏单元个数就可以分别设定。

第二层LSTM没有输入参数x(t1)、x(t2)、x(t3);所以我们将第一层LSTM输出的h(t1)、h(t2)、h(t3)作为第二层LSTM的输入x(t1)、x(t2)、x(t3)。第一个时间步输入的初始c(0)和h(0)都为0矩阵,计算完成后,第一个时间步输出新的一组h(t1)、c(t1),作为本层LSTM的第二个时间步的输入参数;因此第二个时间步的输入就是h(t1),c(t1),x(t2),而输出是h(t2),c(t2);因此第三个时间步的输入就是h(t2),c(t2),x(t3),而输出是h(t3),c(t3)。

5. BiLSTM

单层的BiLSTM其实就是2个LSTM,一个正向去处理序列,一个反向去处理序列,处理完后,两个LSTM的输出会拼接起来。

6. Pytorch实现LSTM示例

python 复制代码
import torch 
import torch.nn as nn

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

class LSTM(nn.Module):
    def __init__(self, input_dim, hidden_dim, num_layers, output_dim):
        super(LSTM, self).__init__()
        self.hidden_dim = hidden_dim  # 隐藏层维度
        self.num_layers = num_layers  # LSTM层的数量

        # LSTM网络层
        self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers, batch_first=True)
        # 全连接层,用于将LSTM的输出转换为最终的输出维度
        self.fc = nn.Linear(hidden_dim, output_dim)
        
        
    def forward(self, x):
        # 初始化隐藏状态和细胞状态
        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_dim).to(device)
        c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_dim).to(device)
        # 前向传播LSTM,返回输出和最新的隐藏状态与细胞状态
        out, (hn, cn) = self.lstm(x, (h0.detach(), c0.detach()))
        # 将LSTM的最后一个时间步的输出通过全连接层
        out = self.fc(out[:, -1, :])
        return out

7. nn.LSTM参数详解

pytorch官方定义:

CLASS torch.nn.LSTM(

input_size,

hidden_size,

num_layers=1,

bias=True,

batch_first=False,

dropout=0.0,

bidirectional=False,

proj_size=0,

device=None,

dtype=None

)

input_size -- 输入 x 中预期的特征数量
hidden_size -- 隐藏状态 h 中的特征数量
num_layers -- 循环层的数量。例如,设置 num_layers=2 表示将两个 LSTM 堆叠在一起形成一个 stacked LSTM,其中第二个 LSTM 接收第一个 LSTM 的输出并计算最终结果。默认值:1
bias -- 如果 False,则该层不使用偏差权重 b_ih 和 b_hh。默认值:True
batch_first -- 如果 True,则输入和输出张量将以 (batch, seq, feature) 而不是 (seq, batch, feature) 的形式提供。请注意,这并不适用于隐藏状态或单元状态。有关详细信息,请参见下面的输入/输出部分。默认值:False
dropout -- 如果非零,则在除最后一层之外的每个 LSTM 层的输出上引入一个 Dropout 层,其 dropout 概率等于 dropout。默认值:0
bidirectional -- 如果 True,则变为双向 LSTM。默认值:False
proj_size -- 如果 > 0,则将使用具有相应大小的投影的 LSTM。默认值:0

对于输入序列每一个元素,每一层都会进行以下计算:

网络输入:

网络输出:

本文参考: https://blog.csdn.net/qq_34486832/article/details/134898868
https://pytorch.ac.cn/docs/stable/generated/torch.nn.LSTM.html#

LSTM每层的输出都要经过全连接层吗,还是直接对隐藏层进行输出?

通过在代码中对lstm的输出进行print输出:

python 复制代码
import torch 
import torch.nn as nn

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

class LSTM(nn.Module):
    def __init__(self, input_dim, hidden_dim, num_layers, output_dim):
        super(LSTM, self).__init__()
        self.hidden_dim = hidden_dim  # 隐藏层维度
        self.num_layers = num_layers  # LSTM层的数量

        # LSTM网络层
        self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers, batch_first=True)
        # 全连接层,用于将LSTM的输出转换为最终的输出维度
        self.fc = nn.Linear(hidden_dim, output_dim)
        
        
    def forward(self, x):
        # 初始化隐藏状态和细胞状态
        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_dim).to(device)
        c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_dim).to(device)
        # 前向传播LSTM,返回输出和最新的隐藏状态与细胞状态
        out, (hn, cn) = self.lstm(x, (h0.detach(), c0.detach()))
        print(out)
        print(hn)
        print(cn)
        # 将LSTM的最后一个时间步的输出通过全连接层
        out = self.fc(out[:, -1, :])
        return out
if __name__ == "__main__":
	input_dim = 3        # 输入特征的维度
	hidden_dim = 4       # 隐藏层的维度
	num_layers = 1       # LSTM 层的数量
	output_dim = 1       # 输出特征的维度
	    
	lstm = LSTM(input_dim, hidden_dim, num_layers, output_dim).to(device)
	batch_size = 1
	seq_length = 10
	input_tensor = torch.randn(batch_size, seq_length, input_dim).to(device)
	output = lstm(input_tensor)

通过对LSTM网络的输出我们可以看到,out的最后一层与最后一层隐藏层hn一致,说明并未经过全连接层,而是直接输出隐藏层

相关推荐
haiyu_y13 小时前
Day 46 TensorBoard 使用介绍
人工智能·深度学习·神经网络
阿里云大数据AI技术13 小时前
DataWorks 又又又升级了,这次我们通过 Arrow 列存格式让数据同步速度提升10倍!
大数据·人工智能
做科研的周师兄13 小时前
中国土壤有机质数据集
人工智能·算法·机器学习·分类·数据挖掘
IT一氪13 小时前
一款 AI 驱动的 Word 文档翻译工具
人工智能·word
lovingsoft13 小时前
Vibe coding 氛围编程
人工智能
百***074513 小时前
GPT-Image-1.5 极速接入全流程及关键要点
人工智能·gpt·计算机视觉
yiersansiwu123d13 小时前
AI二创的版权迷局与健康生态构建之道
人工智能
Narrastory13 小时前
拆解指数加权平均:5 分钟看懂机器学习的 “数据平滑神器”
人工智能·机器学习
SelectDB13 小时前
慢 SQL 诊断准确率 99.99%,天翼云基于 Apache Doris MCP 的 AI 智能运维实践
数据库·人工智能·apache
王中阳Go13 小时前
05 Go Eino AI应用开发实战 | Docker 部署指南
人工智能·后端·go