自然语言处理笔记总目录
LSTM(Long Short-Term Memory)也称长短时记忆结构,它是传统RNN的变体,与经典RNN相比能够有效捕捉长序列之间的语义关联,缓解梯度消失或爆炸现象,同时LSTM的结构更复杂,它的核心结构可以分为四个部分去解析
- 遗忘门
- 输入门
- 细胞状态
- 输出门
LSTM的内部结构图:

结构解释图:

遗忘门部分结构图与计算公式:

遗忘门结构分析:
- 与传统RNN的内部结构计算非常相似,首先将当前时间步输入 x ( t ) x(t) x(t) 与上一个时间步隐含状态 h ( t − 1 ) h(t-1) h(t−1) 拼接,得到 [ x ( t ) , h ( t − 1 ) ] [x(t), h(t-1)] [x(t),h(t−1)] ,然后通过一个全连接层做变换,最后通过 s i g m o i d sigmoid sigmoid 函数进行激活得到 f ( t ) f(t) f(t) ,我们可以将 f ( t ) f(t) f(t) 看作是门值,好比一扇门开合的大小程度,门值都将作用在通过该扇门的张量,遗忘门门值将作用的上一层的细胞状态上,代表遗忘过去的多少信息,又因为遗忘门门值是由 x ( t ) x(t) x(t) , h ( t − 1 ) h(t-1) h(t−1) 计算得来的,因此整个公式意味着根据当前时间步输入和上一个时间步隐含状态 h ( t − 1 ) h(t-1) h(t−1) 来决定遗忘多少上一层的细胞状态所携带的过往信息
遗忘门内部结构过程演示:

激活函数sigmiod的作用:

输入门部分结构图与计算公式:

输入门结构分析:
- 我们看到输入门的计算公式有两个,第一个就是产生输入门门值的公式,它和遗忘门公式几乎相同,区别只是在于它们之后要作用的目标上。这个公式意味着输入信息有多少需要进行过滤,输入门的第二个公式是与传统RNN的内部结构计算相同。对于LSTM来讲,它得到的是当前的细胞状态,而不是像经典RNN一样得到的是隐含状态
输入门内部结构过程演示:

细胞状态更新图与计算公式:

细胞状态更新分析:
- 细胞更新的结构与计算公式非常容易理解,这里没有全连接层,只是将刚刚得到的遗忘门门值与上一个时间步得到的 C ( t − 1 ) C(t-1) C(t−1) 相乘,再加上输入门门值与当前时间步得到的未更新 C ( t ) C(t) C(t) 相乘的结果,最终得到更新后的 C ( t ) C(t) C(t) 作为下一个时间步输入的一部分。整个细胞状态更新过程就是对遗忘门和输入门的应用
细胞状态更新过程演示:

输出门部分结构图与计算公式:

输出门结构分析:
- 输出门部分的公式也是两个,第一个即是计算输出门的门值,它和遗忘门、输入门计算方式相同;第二个即是使用这个门值产生隐含状态 h ( t ) h(t) h(t) ,他将作用在更新后的细胞状态 C ( t ) C(t) C(t) 上,并做 t a n h tanh tanh 激活,最终得到 h ( t ) h(t) h(t) 作为下一时间步输入的一部分。整个输出门的过程,就是为了产生隐含状态 h ( t ) h(t) h(t)
输出门内部结构过程演示:

注:上述所有提到的乘法都是张量的按元素相乘
什么是Bi-LSTM?
- Bi-LSTM即双向LSTM,它没有改变LSTM本身任何的内部结构,只是将LSTM应用两次且方向不同,再将两次得到的LSTM结果进行拼接作为最终输出

Bi-LSTM结构分析:
- 我们看到图中对"我爱中国"这句话或者叫这个输入序列,进行了从左到右和从右到左两次LSTM处理,将得到的结果张量进行了拼接作为最终输出。这种结构能够捕捉语言语法中一些特定的前置或后置特征,增强语义关联,但是模型参数和计算复杂度也随之增加了一倍,一般需要对语料和计算资源进行评估后决定是否使用该结构
Examples:
- LSTM
import torch
from torch import nn
lstm = nn.LSTM(10, 20, 2)
input = torch.randn(5, 3, 10)
h0 = torch.randn(2, 3, 20)
c0 = torch.randn(2, 3, 20)
output, (hn, cn) = lstm(input, (h0, c0))
>>> output.size()
torch.Size([5, 3, 20])
>>> hn.size()
torch.Size([2, 3, 20])
>>> cn.size()
torch.Size([2, 3, 20])
- Bi-LSTM:在LSTM的基础上,加入
bidirectional=True即可
import torch
from torch import nn
bi_lstm = nn.LSTM(10, 20, 2, bidirectional=True)
input = torch.randn(5, 3, 10)
h0 = torch.randn(2 * 2, 3, 20)
c0 = torch.randn(2 * 2, 3, 20)
output, (hn, cn) = bi_lstm(input, (h0, c0))
如果是双向的,h0和c0的第一项要乘2,即 D ∗ n u m _ l a y e r s D∗num\_layers D∗num_layers,2 ∗ * ∗ 隐藏层层数
>>> output.size()
torch.Size([5, 3, 40])
>>> hn.size()
torch.Size([4, 3, 20])
>>> cn.size()
torch.Size([4, 3, 20])
参考链接:https://pytorch.org/docs/stable/generated/torch.nn.LSTM.html#torch.nn.LSTM
本文详细介绍了LSTM的遗忘门、输入门和细胞状态机制,以及Bi-LSTM如何通过双向处理增强语义理解。重点讲解了LSTM结构的计算过程,并展示了如何在PyTorch中实现。最后讨论了Bi-LSTM的使用场景和其在提高模型表现上的优势。
3万+

被折叠的 条评论
为什么被折叠?



