当前位置: 首页 > news >正文

NLP——RNN变体LSTM和GRU

LSTM

一、概念

 LSTM(Long Short-Term Memory)也称长短时记忆结构, 它是传统RNN的变体, 与经典RNN相比能够有效捕捉长序列之间的语义关联, 缓解梯度消失或爆炸现象. 同时LSTM的结构更复杂, 它的核心结构可以分为四个部分去解析:

遗忘门:控制上一个时间步的细胞状态遗忘多少,通过门宽的保留下来

输入门:控制当前时间步的候选记忆( 传统RNN公式得到的结果 )保留多少

细胞状态:存储长期记忆,贯穿计算的全过程

输出门:从当前细胞状态中得到当前隐层输出

这种分工使LSTM既能捕捉长期依赖(如小说伏笔),又能灵活处理局部特征(如对话语气)。

二、LSTM内部结构

计算过程

简单来讲,LSTM一个时间步的计算通过以下几步进行运行:

  1. 遗忘门筛选历史记忆: 决定从长期记忆(细胞状态)选择遗忘丢弃哪些旧信息

    1. 输入:拼接后的参数矩阵[h(t-1), x(t)]

    2. 输出:遗忘门门值f(t)

  2. 输入门吸取新信息:选并整合当前输入中的关键信息生成候选记忆

    1. 输入:拼接后的参数矩阵[h(t-1), x(t)]

    2. 输出:输入门门值i(t),生成候选记忆C~(t) (RNN的计算方式)

  3. 细胞状态更新融合新旧记忆:通过线性叠加更新长期记忆C(t)。

    1. 输入:候选记忆C~(t),遗忘系数 f(t), 上一个时间步的细胞状态C(t-1) , 输入门值i(t)

    2. 输出:长期记忆 C(t)

  4. 输出门生成隐藏状态:控制细胞状态中哪些信息作为当前输出(短期记忆)

    1. 输入:当前时间步的细胞状态 C(t),拼接后的参数矩阵[h(t-1), x(t)]

    2. 输出:输出门门值o(t) (中间变量),短期记忆h(t)

三、代码实现

实例化LSTM是默认参数batch_first=False,

所以构建的输入参数先sequence_length后batch_size;

如果更改参数batch_first=True,则构建的输入参数先batch_size后sequence_length。

# -*- coding: utf-8 -*-
import torch.nn as nn
import torch# 第一个参数:input_size代表输入数据的词嵌入表示维度
# 第二个参数:hidden_size代表隐藏层输出维度
# 第三个参数:num_layers代表隐藏层的个数
lstm = nn.LSTM(input_size=5, hidden_size=6, num_layers=1)# 第一个参数:sequence_length代表输入数据的每个样本的句子长度
# 第二个参数:batch_size代表一个批次几个样本
# 第三个参数:input_size代表输入数据的词嵌入表示维度
input_x = torch.randn(4, 3, 5)# 第一个参数:num_layers代表隐藏层的个数
# 第二个参数:batch_size代表一个批次几个样本
# 第三个参数:hidden_size代表隐藏层输出维度
h0 = torch.randn(1, 3, 6)
c0 = torch.randn(1, 3, 6)output, (hn, cn) = lstm(input_x, (h0, c0))
print(f'output: {output}')
print(f'hn: {hn}')
print(f'cn: {cn}')

四、LSTM优缺点

优点:

LSTM的门结构能够有效减缓长序列问题中可能出现的梯度消失或爆炸, 虽然并不能杜绝这种现象, 但在更长的序列问题上表现优于传统RNN。

缺点:

由于内部结构相对较复杂, 因此训练效率在同等算力下较传统RNN低很多。

五、BI-LSTM

定义: 不改变原始的LSTM模型内部结构,只是将文本从左到右计算一遍,再从右到左计算一遍,把最终的输出结果拼接得到模型的完整输出。

GRU

一、概念

GRU(Gated Recurrent Unit)也称门控循环单元结构, 它也是传统RNN的变体, 同LSTM一样能够有效捕捉长序列之间的语义关联, 缓解梯度消失或爆炸现象. 同时它的结构和计算要比LSTM更简单, 它的核心结构可以分为两个部分去解析:

更新门:

作用:决定当前时刻的隐藏状态需要保留多少上一时刻的隐藏状态信息,以及吸收多少新的候选隐藏状态信息。(类似于LSTM中的“输入门”和“遗忘门”的结合,但更高效)

门值越趋近于1,保留上一时间步信息越多;越趋近于0,表示更新的越多,采用当前状态越多。

重置门:

作用:控制上一时刻的隐藏状态对当前候选隐藏状态的影响程度。(决定是否“忽略”过去的信息,以便更好地捕捉短期依赖)

门值越趋近于1,表示将上一时刻状态与当前输入结合生成候选状态;门值越趋近0,忽略上一时刻状态越多,候选状态更依赖当前输入。

二、GRU内部结构

1. 计算更新门和重置门的门值

        更新门值        z_{t}=\sigma \left ( W_{z}\cdot \left [ h_{t-1},x_{t} \right ] \right )

        重置门值        r_{t}=\sigma \left ( W_{r}\cdot \left [ h_{t-1},x_{t} \right ] \right )

2. 然后重置门值作用在h(t-1)上,控制上一时间步的输入保留下多少(作用类似遗忘门),再用留下的部分进行基本RNN运算(与x(t)拼接进行线性变换,经过tanh激活),得到新\widetilde{h_{t}},再使用新值与z_{t}相乘。

\widetilde{h_{t}}=tanh\left ( W\cdot \left [ r_{t}*h_{t-1},x_{t} \right ] \right )

z_{t}*\widetilde{h_{t}}

3. 使用(1-z(t))作用再h(t-1)上再与第二步结果相加输出新的h(t)

h_{t}=\left ( 1-z_{t} \right )*h_{t}+z_{t}*\widetilde{h_{t}}

三、代码实现

# -*-coding:utf-8-*-
import torch
import torch.nn as nn
# 实例化GRU模型
#todo: 1.GRU实例化主要参数说明:
# 第一个参数:input_size代表输入数据的词嵌入表示维度
# 第二个参数:hidden_size代表隐藏层输出维度
# 第三个参数:num_layers代表隐藏层的个数gru = nn.GRU(5, 6, 1)#todo: 2.输入数据参数说明:
# 第一个参数:sequence_length代表输入数据的每个样本的句子长度
# 第二个参数:batch_size代表一个批次几个样本
# 第三个参数:input_size代表输入数据的词嵌入表示维度
input_x = torch.randn(3, 4, 5)#todo: 3.隐藏状态参数说明:
# 第一个参数:num_layers代表隐藏层的个数
# 第二个参数:batch_size代表一个批次几个样本
# 第三个参数:hidden_size代表隐藏层输出维度
h0 = torch.randn(1, 4, 6)# todo:将数据送入模型
output, hn = gru(input_x, h0)
print(f'output-->{output}')
print(f'hn-->{hn}')

四、GRU优缺点

GRU的优势:

GRU和LSTM作用相同, 在捕捉长序列语义关联时, 能有效抑制梯度消失或爆炸, 效果都优于传统RNN且计算复杂度相比LSTM要小、重置门直接作用于上一隐藏状态,而LSTM遗忘门作用于细胞状态。更像一个滑动开关,决定保留与更新的比例。

GRU的缺点:

GRU仍然不能完全解决梯度消失问题, 同时其作用RNN的变体, 有着RNN结构本身的一大弊端, 即不可并行计算, 这在数据量和模型体量逐步增大的未来, 是RNN发展的关键瓶颈。

五、BI-GRU

Bi-GRU与Bi-LSTM的逻辑相同, 都是不改变其内部结构, 而是将模型应用两次且方向不同, 再将两次得到的LSTM结果进行拼接作为最终输出. 具体参见上小节中的Bi-LSTM。

http://www.lqws.cn/news/601795.html

相关文章:

  • Android布局管理器实战指南:从LinearLayout到ConstraintLayout的优化之旅
  • Redis——常用指令汇总指南(一)
  • 【Python】断言(assert)
  • 监听器模式
  • [Python] -基础篇8-Python中的注释与代码风格PEP8指南
  • 【C++】inline的作用
  • InnoDB数据页
  • 61、【OS】【Nuttx】【构建】向量表
  • OpenCv基础(C++)
  • 6.Docker部署ES+kibana
  • 无人机目标检测数据集介绍-14,751张图片 无人机检测 航拍图像
  • 路科V0—基础(2)设计特性与接口
  • 【第二章:机器学习与神经网络概述】04.回归算法理论与实践 -(3)决策树回归模型(Decision Tree Regression)
  • 融智学定律3:流动创造价值仅当跨域协同
  • Arduino LED立方体3D公告板制作指南
  • uniapp+vue3 中使用echart 以及echart文件过大需要分包的记录
  • imx6ull芯片中断机制6.24-6.25
  • Redis为什么是单线程
  • UE5.6 官方文档笔记 [1]——虚幻编辑器界面
  • 6.2 实现文档加载和切分和简易向量数据库的功能
  • browser-tools-mcp + excel-mcp-server + cursor 实现读取网页信息自动写入Excel
  • SQL Server 进阶:递归 CTE+CASE WHEN 实现复杂树形统计(第二课)
  • 读Vista
  • Python实例题:基于 Python 的简单爬虫与数据可视化
  • Hibernate中save与saveOrUpdate的差异解析
  • HDMI2.1 FRL流控 概览
  • Linux驱动学习day13(同步与互斥)
  • AI的未来:人类会被取代,还是变得更强大?
  • HTTPS安全传输时采用的顶级阳谋
  • 【Maven 】 <resources> 配置中排除 fonts/** 目录无效,可能是由于以下原因及解决方案: