循环神经网络复习1-RNN,LSTM,GRU(为什么讲gru,因为阿里的推荐DIEN的论文中self-attention中大量是基于GRU的)

本文深入解析循环神经网络(RNN)、长短期记忆网络(LSTM)及门控循环单元(GRU)的工作原理与机制。阐述了RNN处理序列数据的优势,详细解释了LSTM的三个门控机制,以及GRU的简化设计。对比了不同模型的激活函数选择与应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

循环神经网络复习1-RNN,LSTM,GRU(为什么将gru)因为阿里的推荐DIEN的论文中self-attention中大量是基于GRU的

动机: 传统的前馈神经网络一般都是输入一个定长的向量,没法处理变长的序列特征,即使通过一些方法,把数据处理成定长的向量(如滑窗截断)也很难捕捉到序列的长距离依赖关系。

RNN解决方式: RNN是让神经元串联,处理序列化特征,每个神经元利用它的内部变量保存之前的输入序列信息**,因此,整个序列被浓缩成抽象的表示。

传统处理文本的tf-idf方法:
把文本表征为 tf-idf 向量,维度是词汇表大小
弊端:

  • tf-idf向量,本身失去了文本的序列性(前后性)
  • 滑窗可缓解序列性(前后性)不足的问题,但长距离依赖问题仍存在

RNN的初衷就是把之前的有用信息,编码到一个(一群)状态变量中去,从而拥有一定的记忆能力,当然,这里的记忆能力不是单纯地指记住之前的信息,而是可以有选择的从状态变量中,利用之前的信息

RNN中的最后一层的状态hTh_{T}hT,一般都被认为是编码了整个序列的信息,因此可以被视为是整个输入的压缩表示。

LSTM的3个门,6个公式

长短期记忆,从名字上就看出,能记住近期的,又能记住远期的,靠什么呢?靠门控,遗忘门(远期若还有用,就不该忘记),输入门(近期若重要,多一些进来)。
首先6个公式中,3个门(输入门,遗忘门,输出门)肯定就占了3个公式
剩下3个公式呢?如何记呢?这就需要知道LSTM中相比与RNN多出了一个单元——记忆单元ctc_tct,或者说记忆变量ctc_tct,原本RNN中只有的隐状态单元hth_tht,或者说隐状态变量hth_tht,在LSTM中还是有的。
第四个公式就是关于记忆变量ctc_tct的,(准确的说是准记忆变量ct~\tilde{c_t}ct~ 会与输入门控结果的向量相乘,作为记忆变量ctc_tct的一部分),同时,与前三个3个门(输入门,遗忘门,输出门)的公式不同,前三个3个门的公式中用到的是sigmoid激活函数(输出0-1,能起到门控的作用,符合门控的物理含义),而准记忆变量ct~\tilde{c_t}ct~用到的是双曲正切函数tanh,(下面马上讲为什么用tanh双曲正切函数)。
第五个公式,就是真正计算记忆变量ctc_tct的, 把第四个计算的准记忆变量ct~\tilde{c_t}ct~,与输入门控结果的向量相乘,作为一部分结果,同时把上一步的记忆变量ct−1c_{t-1}ct1与遗忘门控结果的向量相乘,作为另一部分结果。两部分结果相加作为最终的记忆变量ctc_tct(遗忘门控就是控制上一步的记忆变量ctc_tct还有多少该被记住)
第六个公式,是关于LSTM中隐状态变量hth_tht的, 之前说过,虽然,记忆变量ctc_tct是LSTM的一大亮点,但真正每个结点输出的仍是隐状态变量hth_tht,这点和传统RNN一样,这里直接把第五步得到的记忆变量ctc_tct再次经过一个激活函数,这里仍是双曲正切函数tanh,到这里是不是感觉少了什么,对好像漏了输出门控,一直讲到这里,输出门控的戏份都有点少,但是人家很重要的好吧,你们之前算了半天的东西,都得最后从我输出门控这里卡一下,我让你输出多少,你最后只能乖乖输出多少,哪怕你之前tanh(ct)tanh(c_t)tanh(ct)(算的再大。

上面啰里八嗦的讲了一大堆,保证你会觉得还是看公式吧,公式多简洁,可是上面的啰里八嗦,有助于记公式哈~

it=σ(Wixt+Uiht−1+bi)i_t=\sigma(W_ix_t+U_ih_{t-1}+b_i)it=σ(Wixt+Uiht1+bi)公式一
ft=σ(Wfxt+Ufht−1+bf)f_t=\sigma(W_fx_t+U_fh_{t-1}+b_f)ft=σ(Wfxt+Ufht1+bf)公式二
ot=σ(Woxt+Uoht−1+bo)o_t=\sigma(W_ox_t+U_oh_{t-1}+b_o)ot=σ(Woxt+Uoht1+bo)公式三

ct~=tanh(Wcxt+Ucht−1)\tilde{c_t}=tanh(W_cx_t+U_ch_{t-1})ct~=tanh(Wcxt+Ucht1)公式四
ct=ft⊙ct−1+it⊙ct~c_t=f_t ⊙ c_{t-1}+i_t ⊙ \tilde{c_t}ct=ftct1+itct~公式五
ht=ot⊙tanh(ct)h_t=o_t ⊙ tanh(c_{t})ht=ottanh(ct)公式六

输入门控,遗忘门控,输出门控的结果,it、ft、oti_t、f_t、o_titftot都是向量,其中每个元素值都是0-1的实数,用于控制各维度流经阀门后的信息量。

输入门控,遗忘门控的物理意义,如何控制长短期记忆?
在一个接近训练好的网络中,当输入的序列中没有新增的重要信息时,LSTM的遗忘门的值会接近于1,输入门的值会接近于0,此时,过去的记忆会被较好的保存下来,从而实现了长期记忆功能。
当输入的序列中有较多的新增重要信息时,LSTM应该将其存入记忆单元中(回忆上面公式五),输入门的值会接近于1,且LSTM的遗忘门的值会慢慢接近于0,这样旧的记忆会被适当遗忘,新的重要信息被记忆,从而实现了短期记忆功能。
综上,LSTM经过3个门控的设计,特别是输入门控,遗忘门控,整个网络更容易学习到了序列之间的长短期依赖。
在这里插入图片描述

LSTM里各模块分别采用什么激活函数,可以别的激活函数吗?
3个门控函数,用的是sigmoid函数,sigmoid函数已经是神经网络中,设计到门控时的共同选择。
理由:sigmoid有饱和区,sigmoid函数输出值0-1,符合门控的物理含义
relu这样的激活函数没有饱和区。
另外,准记忆变量ct~\tilde{c_t}ct~,和隐状态变量hth_tht的激活函数,是双曲正切函数tanh,理由:
tanh有饱和区,tanh函数-1到1,这与多数场景下的特征分布是以0为中心相吻合。另外,tanh函数在0处的导数比sigmoid函数的大,这有助于模型在梯度下降时更快收敛。

再讲GRU ——循环门单元(Gated Recurrent Unit,GRU)

GRU其实一点都不神秘
因为它相当于只在LSTM的基础上做减法,而没有加法的公式,
公式也从6个变成了4个公式,是不是很简单,
显然LSTM六个公式,对应了三个门控,所以GRU四个公式,就对应了两个门控。
从LSTM中的输入门控,遗忘门控,输出门控三个门控,变成了两个门控,(更新门控和重置门),果然输出门控戏份少哈哈。

下面来看这四个公式,前两个必然就是和门控有关的,sigmoid函数。
第一个公式rt=σ(Wrxt+Urht−1)r_t=\sigma(W_rx_t+U_rh_{t-1})rt=σ(Wrxt+Urht1)重置门控reset
第二个公式zt=σ(Wzxt+Uzht−1)z_t=\sigma(W_zx_t+U_zh_{t-1})zt=σ(Wzxt+Uzht1)更新门控update,为什么不用首字母u,估计是u不太好记吧,一般不用辅音字母。

第三个和第四个公式就关于计算隐状态变量hth_tht的,和LSTM一样,GRU也是先计算了一个准隐状态变量ht~\tilde{h_t}ht~
第三个公式就是关于准隐状态变量ht~\tilde{h_t}ht~,利用tanh激活函数。
ht~=tanh(Wxt+rtht−1)\tilde{h_t}=tanh(Wx_t+r_th_{t-1})ht~=tanh(Wxt+rtht1)这时利用了第一个公式的重置门控rtr_trt
现在第二个公式的更新门控ztz_tzt还没用到,显然第四个公式就会用到更新门控ztz_tzt
它决定了用多少过去的信息和现在的信息。
第四个公式就是关于隐状态变量ht=(1−zt)ht−1+ztht~h_t=(1-z_t)h_{t-1}+z_t\tilde{h_t}ht=(1zt)ht1+ztht~
在这里插入图片描述
上图中1−Zt和Zt1-\boldsymbol Z_t和\boldsymbol Z_t1ZtZt位置标反了.
通过以上啰嗦,GRU的四个公式也是很好记的,
需要注意这里GRU与LSTM的区别是GRU中没有output gate

一般来说,那么具有短依赖的单元reset gate比较活跃,(果然重置门控rtr_trt=1,更新门控ztz_tzt=0的话,GRU直接退化为标准的RNN,能处理短距离依赖),具有长距离依赖的场景下,update gate比较活跃。

多说一句,GRU 简单,参数比LSTM少三分之一,比 LSTM 的训练更快一下,效果也不差于LSTM ,会被用的更多。

### 循环神经网络 (RNN) 循环神经网络(Recurrent Neural Network,简称 RNN)是一种专门设计用来处理序列数据的神经网络结构。这种类型的网络可以记住之前的信息并将其应用于当前的任务中,从而有效地捕捉时间上的依赖关系[^2]。 ```python import torch.nn as nn class SimpleRNN(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(SimpleRNN, self).__init__() self.rnn = nn.RNN(input_size, hidden_size, batch_first=True) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): out, _ = self.rnn(x) out = self.fc(out[:, -1, :]) return out ``` ### 长短期记忆单元 (LSTM) 为了克服传统RNN在网络较深或输入序列较长时可能出现的记忆衰退问题——即梯度消失现象,提出了长短期记忆(Long Short-Term Memory),简称LSTM。它引入了一种称为“门”的机制来控制信息流,使得模型可以在更长时间跨度内保持重要信息而不丢失细节[^4]。 ```python class SimpleLSTM(nn.Module): def __init__(self, input_size, hidden_size, num_layers, output_size): super(SimpleLSTM, self).__init__() 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): lstm_out, _ = self.lstm(x) out = self.fc(lstm_out[:, -1, :]) return out ``` ### 门控循环单元 (GRU) 门控循环单元(Gated Recurrent Unit), 或者说GRU,则是在简化版的基础上进一步优化了LSTM的设计理念,在保留核心优势的同时减少了参数数量以及计算复杂度。具体而言,GRU 将遗忘门和输入门合二为一,并移除了细胞状态的概念,只保留了一个隐藏层的状态传递方式[^1]。 ```python class SimpleGRU(nn.Module): def __init__(self, input_size, hidden_size, num_layers, output_size): super(SimpleGRU, self).__init__() self.gru = nn.GRU(input_size, hidden_size, num_layers, batch_first=True) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): gru_out, _ = self.gru(x) out = self.fc(gru_out[:, -1, :]) return out ``` ### 区别 - **架构差异**: RNN是最基础的形式;LSTM增加了三个不同的门(输入门、输出门和忘记门)以更好地管理长期依赖;GRU则把其中两个门合并成更新门,并且取消了单独存在的细胞状态。 - **性能特点**: 对于非常长的时间序列预测任务,LSTM通常优于标准形式下的RNN; 而当考虑到效率因素时, GRU可能是一个不错的选择因为它拥有较少的数量级可调参量却依然能提供接近甚至超过LSTM的表现效果. - **应用场景**: * RNN适用于相对简单的序列建模需求. * LSTM适合那些需要特别关注远距离上下文关联性的场合,例如语音识别、机器翻译等自然语言处理领域内的高级应用. * GRU由于其实现更加高效简洁的特点,在资源受限环境下或是对于实时性要求较高的在线服务方面表现出色.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值