第R2周:LSTM算法详解
往期文章可查阅: 深度学习总结
在看懂上一篇有关RNN的内部原理之后,LSTM相对就简单很多了。一句话介绍LSTM,他是RNN的进阶版,如果说RNN的最大限度是理解一句话,那么LSTM的最大限度则是理解一段话。
LSTM,全称为长短期记忆网络(Long Short Term Memory networks),是一种特殊的RNN,能够学习到长期以来关系。LSTM有Hochreiter&Schmidhuber(1997)提出,许多研究者进行了一系列的工作对其改进并使之发扬光大。LSTM在许多问题上效果非常好,现在被广泛使用。
一、RNN面临问题
RNN(递归神经网络)在处理长序列时面临的主要问题:短时记忆和梯度消失/梯度爆炸。
梯度更新规则
- 短时记忆
- 问题描述:RNN在处理长序列时,由于信息的传递是通过隐藏状态进行的,随着时间的推移,较早时间步的信息可能会在传递到后面的时间步时逐渐消失或被覆盖。
- 影响:这导致RNN难以捕捉和利用序列中的长期依赖关系,从而限制了其在处理复杂任务时的性能。
- 梯度消失/梯度爆炸
- 问题描述:在RNN的反向传播过程中,梯度会随着时间步的推移而逐渐消失(变得非常小)或爆炸(变得非常大)。
- 影响:梯度消失使得RNN在训练时难以学习到长期依赖关系,因为较早时间步的梯度信息在反向传播到初始层时几乎为零。梯度爆炸则可能导致训练过程不稳定,权重更新过大,甚至导致数值溢出。
LSTM解决问题:大脑和LSTM在处理信息时都选择性地保留重要信息,忽略不相关细节,并据此进行后续处理。这种机制使它们能够高效地处理和输出关键信息,解决了RNN(递归神经网络)在处理长序列时面临的问题。
大脑记忆机制
- 大脑记忆机制:当浏览评论时,大脑倾向于记住重要的关键词。无关紧要的词汇和内容容易被忽略。回忆时,大脑提取并表达主要观点,忽略细节。
- LSTM门控机制:LSTM通过输入门、遗忘门和输出门选择性地保留或忘记信息,使用保留的相关信息来进行预测,类似于大脑提取并表达主要观点。
二、LSTM基本概念
LSTM是一种特殊的RNN网络,他使用们(gate)的机制来解决长距离依赖的问题。回顾一下,所有的RNN都是如下图所示的结构,把RNN看成一个黑盒子的话,他会有一个“隐状态”来“记忆”一些重要的信息。当前时刻的输出除了受当前输入影响之外,也受这个“隐状态”影响。并且在这个时刻结束时,除了输出之外,这个“隐状态”的内容也会发生变化——他“记忆”了新的信息同时又“遗忘”了一些旧的信息。
LSTM也是这样的结构,但相比原始的RNN,他的内部结构更加复杂。普通的RNN就是一个全连接的层,而LSTM有四个用于控制“记忆”和运算的门,如下图所示:
1. Conveyor Belt(传输带)
- 传输带记为向量Ct:过去的信息通过传输带直接送到下一个时刻,不会发生太大的变化。
- LSTM就是靠传输带来避免梯度消失的问题
2. Forget Gate(遗忘门)
- 遗忘门有两部门组成;
- 输入的Sigmoid函数是一个向量a,Sigmoid对向量a中的每一个元素都进行压缩,压缩在(0,1)之间的范围
- Elementwise multiplication:两个矩阵对应位置元素进行乘积
遗忘门(ft):一个向量,有选择的让传输带C的值通过。
- 假如f的一个元素为0,,则C对应的元素就不能通过,对应的输出为0。
- 假如f的一个元素为1,,则C对应的元素全部通过,对应的输出为C本身。
参数矩阵Wf ,需要通过反向传播从训练数据中学习。
3. Input Gate(输入门)
输入门(it):更新传输带的值
参数矩阵Wi ,需要通过反向传播从训练数据中学习。
4. New value(新的值)
New value:将值添加到传输带上
5. Output gate(输出门)
输出门(Ot):
三、pytorch实现
import torch
import torch.nn as nn
#定义LSTM网络类
class SimpleLSTM(nn.Module):
def __init__(self,input_size,hidden_size,num_layers,output_size):
super(SimpleLSTM,self).__init__()
# 定义LSTM层
self.lstm=nn.LSTM(input_size,hidden_size,num_layers,batch_first=True)
# 定义一个线性层,将LSTM输出映射到期望的输出维度
self.fc=nn.Linear(hidden_size,output_size)
def forward(self,x):
# LSTM层的前向传播,默认返回output和(hidden_size,cell_state)
lstm_out,(hn,cn)=self.lstm(x)
# 取最后一个时间步的输出
lstm_out=lstm_out[:,-1,:]
#通过全连接层将LSTM的输出映射到输出维度
output=self.fc(lstm_out)
return output
# 参数设置
input_size=10 #输入特征的维度
hidden_size=20 #LSTM隐藏层的维度
num_layers=2 #LSTM层数
output_size=1 #输出的维度
#实例化模型
model=SimpleLSTM(input_size,hidden_size,num_layers,output_size)
#打印模型结构
print(model)
运行结果:
SimpleLSTM(
(lstm): LSTM(10, 20, num_layers=2, batch_first=True)
(fc): Linear(in_features=20, out_features=1, bias=True)
)
#示例输入(batch_size,seq_len,input_size)
x=torch.randn(5,15,input_size) # 例如:batch大小为5,序列长度为15,输入特征维度为10
# 前向传播
output=model(x)
#输出结果
print("输入shape为:",x.shape)
print("输出shape为:",output.shape)
运行结果:
输入shape为: torch.Size([5, 15, 10])
输出shape为: torch.Size([5, 1])
参考文章:一文搞懂 LSTM(长短期记忆网络) - 知乎 (zhihu.com)