PyTorch循环神经网络(Pytotch)

发布于:2025-05-16 ⋅ 阅读:(11) ⋅ 点赞:(0)

循环神经网络(RNN)

  • 循环神经网络(RecurrentNeuralNetwork,RNN)又称递归神经网络,它是常规前馈神经网络(FeedforwardNeuralNetwork,FNN)的扩展,本节介绍几种常见的循环神经网络。

简单的循环神经网络

  • 循环神经网络(RNN)会遍历所有序列的元素,每个当前层的输出都与前面层的输出有关,会将前面层的状态信息保留下来。理论上,RNN应该可以处理任意长度的序列数据,但为了降低一定的复杂度,实践中通常只会选取与前面的几个状态有关的信息。
  • 简单的循环神经网络如图:
    在这里插入图片描述
  • x是输入,y是输出,中间由一个箭头表示数据循环更新的是隐藏层,主要由中间部分实现时间记忆功能。
  • 神经网络输入x并产生输出y,最后将输出的结果反馈回去。假设在一个时间t内,神经网络的输入除来自输入层的 x ( t ) x(t) x(t)外,还有上一时刻的输出 y ( t − 1 ) y(t-1) y(t1),两者共同输入产生当前层的输出 y ( t ) y(t) y(t)
  • 将这个神经网络按照时间序列形式展开:
    在这里插入图片描述
  • 每个神经元的输出都是根据当前的输入 x ( t ) x(t) x(t)和上一时刻的 y ( t − 1 ) y(t-1) y(t1)共同决定。它们对应的权重分别是 W x W_x Wx W y W_y Wy,单个神经元的输出计算如下:
    y t = O ( x t T ⋅ W x + y t − 1 T ⋅ W y + b ) \boldsymbol { y } _ { t } = \mathcal { O } ( \boldsymbol { x } _ { t } ^ { \mathrm { T } } \cdot \boldsymbol { W } _ { x } + \boldsymbol { y } _ { t - 1 } ^ { \mathrm { T } } \cdot \boldsymbol { W } _ { y } + b ) yt=O(xtTWx+yt1TWy+b)
  • 将隐藏层的层级展开,结果如下图:
    在这里插入图片描述
  • RNN单元在时间 t t t的状态记作 h t h_t ht U U U表示此刻输入的权重, W W W表示前一次输出的权重, V V V表示此刻输出的权重。
  • t = 1 t=1 t=1时刻,一般 h 0 h_0 h0表示初始状态为0,随机初始化 U 、 W 、 V U、W、V UWV,公式如下:
    h 1 = f ( U x 1 + W h 0 + b h ) O 1 = g ( V h 1 + b o ) \begin {array} { l } { h _ { 1 } = f ( U x _ { 1 } + W h _ { 0 } + b _ { h } ) } \\ { O _ { 1 } = g ( V h _ { 1 } + b _ { o } ) } \\ \end{array} h1=f(Ux1+Wh0+bh)O1=g(Vh1+bo)
  • f 和 g 均为激活函数(光滑的曲线函数), f f f可以是Sigmoid、ReLU、Tanh等激活函数, g g g通常是Softmax损失函数。 b h b_h bh是隐藏层的偏置项, b 0 b_0 b0是输出层的偏置项。
  • 前向传播算法,按照时间 t t t向前推进,而此时隐藏状态 h 1 h_1 h1是参与下一个时间的预测过程。
    h 2 = f ( U x 2 + W h 1 + b h ) O 2 = g ( V h 2 + b o ) \begin {array} { l } { h _ { 2 } = f ( U x _ { 2 } + W h _ { 1 } + b _ { h } ) } \\ { O _ { 2 } = g ( V h _ { 2 } + b _ { o } ) } \\ \end{array} h2=f(Ux2+Wh1+bh)O2=g(Vh2+bo)
  • 以此类推,最终可得到输出公式为:
    h t = f ( U x t + W h t − 1 + b h ) O t = g ( V h t + b o ) \begin {array} { l } { h _ { t } = f ( U x _ { t } + W h _ { t-1 } + b _ { h } ) } \\ { O _ { t } = g ( V h _ { t } + b _ { o } ) } \\ \end{array} ht=f(Uxt+Wht1+bh)Ot=g(Vht+bo)
  • 权重共享机制通过统一网络参数(W、U、V及偏置项)实现了三方面优势:一是降低计算复杂度,二是增强模型泛化能力,三是实现对可变长度连续序列数据的特征提取。该机制不仅能捕捉序列特征的时空连续性,还通过位置无关的特性避免了逐位置规则学习,但保留了序列位置的识别能力。
  • 尽管RNN网络在时序数据处理上表现优异,其基础结构仍存在显著缺陷。理论上RNN应具备长期记忆能力和任意长度序列处理能力,但实际应用中会出现梯度消失现象。该问题源于两方面:一是BP算法的固有缺陷(前馈神经网络中随深度增加出现训练失效),二是RNN特有的长程依赖问题(时间跨度导致记忆衰减)。从数学视角看,当激活函数导数小于1时,多层网络梯度呈指数衰减;反之若导数大于1则引发指数级梯度膨胀,造成网络失稳(即梯度爆炸问题)。
  • 针对这些局限性,学界提出了两种主流改进架构:长短期记忆网络(LSTM)和门控循环单元(GRU)。

长短期记忆网络(LSTM)

  • 长短期记忆网络(Long Short-Term Memory,LSTM)主要为了解决标准RNN在处理长序列数据时面临的梯度消失等问题。
  • 基本的LSTM结构单元如图:
    在这里插入图片描述
  • 图中四个矩形即图标1,2,3,4是普通神经网络的隐藏层结构。其中 f ( t ) , i t , o ( t ) f_{(t),i_{{t}},o_(t)} f(t)ito(t)都是Logistic函数, g ( t ) g_{(t)} g(t)是Tanh函数。
  • LSTM单元状态分为长时记忆和短时记忆,其中短时记忆i用向量 h ( t ) h_{(t)} h(t)表示,长时记忆用 c ( t ) c_{(t)} c(t)表示。
  • LSTM单元结构中还有三个门限控制器:忘记门限,输入门限和输出门限。三个门限都使用Logistic函数,如果输出值为1,表示门限打开;如果输出值为0,表示门限关闭。
    • 忘记门限:主要用 f ( t ) f_{(t)} f(t)控制着长时记忆是否被遗忘。
    • 输入门限:主要由 i ( t ) i_{(t)} i(t) g t g_{{t}} gt i ( t ) i_{(t)} i(t)用于控制 g t g_{{t}} gt用于增强记忆的部分。
    • 输出门限:主要由 o ( t ) o_{(t)} o(t)控制应该在该时刻被读取和输出的部分。
  • LSTM单元的基本流程如下:随着短时记忆 c ( t ) c_{(t)} c(t)从左到右横穿整个网络,它首先经过一个遗忘门,丢弃一些记忆,然后通过输入门限来选择增加一些新记忆,最后直接输出 c ( t ) c_{(t)} c(t)。此外,增加记忆这部分操作中,长时记忆先经过Tanh函数,然后被输出门限过滤,产生了短时记忆ht)。
  • 综上所述,LSTM可以识别重要的输入(输入门限的作用),并将这些信息在长时记忆中存储下来,通过遗忘门保留需要的部分,以及在需要的时候能够提取它。

  • LSTM单元结构中的三个门限控制器、两种状态以及输出:
    i ( t ) = σ ( w × i ⊤ ⋅ x ( t ) + w h i ⊤ ⋅ h ( t − 1 ) + b i ) f ( t ) = σ ( w × j ⊤ ⋅ x ( t ) + w h j ⊤ ⋅ h ( t − 1 ) + b f ) o ( t ) = σ ( w x o ⊤ ⋅ x ( t ) + w h o ⊤ ⋅ h ( t − 1 ) + b o ) g ( t ) = T a n h ( w x g ⊤ ⋅ x ( t ) + w h g ⊤ ⋅ h ( t − 1 ) + b g ) c ( t ) = f ( t ) ⊗ c ( t − 1 ) + i ( t ) ⊗ g ( t ) y ( t ) = h ( t ) = o ( t ) ⊗ T a n h ( c ( t ) ) \begin{array} { r l } & { i _ { ( t ) } = \sigma ( w _ { \times i } ^ { \top } \cdot x _ { ( t ) } + w _ { h i } ^ { \top } \cdot h _ { ( t - 1 ) } + b _ { i } ) } \\ & { f _ { ( t ) } = \sigma ( w _ { \times j } ^ { \top } \cdot x _ { ( t ) } + w _ { h j } ^ { \top } \cdot h _ { ( t - 1 ) } + b _ { f } ) } \\ & { o _ { ( t ) } = \sigma ( w _ { x o } ^ { \top } \cdot x _ { ( t ) } + w _ { h o } ^ { \top } \cdot h _ { ( t - 1 ) } + b _ { o } ) } \\ & { g _ { ( t ) } = \mathrm { T a n h } ( w _ { x g } ^ { \top } \cdot x _ { ( t ) } + w _ { h g } ^ { \top } \cdot h _ { ( t - 1 ) } + b _ { g } ) } \\ & { c _ { ( t ) } = f _ { ( t ) } \otimes c _ { ( t - 1 ) } + i _ { ( t ) } \otimes g _ { ( t ) } } \\ & { y _ { ( t ) } = h _ { ( t ) } = o _ { ( t ) } \otimes \mathrm { T a n h } ( c _ { ( t ) } ) } \end{array} i(t)=σ(w×ix(t)+whih(t1)+bi)f(t)=σ(w×jx(t)+whjh(t1)+bf)o(t)=σ(wxox(t)+whoh(t1)+bo)g(t)=Tanh(wxgx(t)+whgh(t1)+bg)c(t)=f(t)c(t1)+i(t)g(t)y(t)=h(t)=o(t)Tanh(c(t))
  • w x i 、 w x f 、 w x o 、 w x g w_{xi}、w_{xf}、w_{xo}、w_{xg} wxiwxfwxowxg是每一层连接到 x ( t ) x_{(t)} x(t)的权重, w h i 、 w h f 、 w h o 、 w h g w_{hi}、w_{hf}、w_{ho}、w_{hg} whiwhfwhowhg是每层连接到前一个短时记忆 h ( t − 1 ) h_{(t-1)} h(t1)的权重, b i 、 b f 、 b o 、 b g b_i、b_f、b_o、b_g bibfbobg是每一层的偏置项。

门控循环单元(GRU)

  • 门控循环单元(GateRecurrentUnit,GRU)是循环神经网络(RNN)的一个变种,它旨在解决标准RNN中梯度消失的问题。GRU结构更简单,效果更好。

  • GRU的设计初衷是解决长期依赖问题,即标准RNN难以捕捉长序列中较早时间步的信息。通过引入更新门和重置门,GRU能够学习到何时更新或忽略某些信息,从而更好地处理序列数据。

  • 相较于LSTM,GRU有更少的参数和计算复杂度,特别是在资源受限的情况下训练更快,同时也能取得不错的性能表现,。GRU已被广泛应用于各种序列建模任务,如语言模型、机器翻译、语音识别等领域。

  • GRU如图所示:
    在这里插入图片描述

  • GRU中包含三个激活函数,分别为Logistic、Logistic、Tanh函数。

  • 如图所示,GRU通过精简门控机制提升了计算效率,其核心特征如下:

  1. 门控结构简化

    • 采用**重置门(r)更新门(z)**双门架构,激活函数缩减至3个(使用Sigmoid或Logistic函数,输出0~1的门控信号)。
    • 合并状态向量为单一隐藏状态 h t h_t ht,简化信息流动路径。
  2. 门控功能详解

    • 重置门(r):控制前一时刻隐藏状态 h t − 1 h_{t-1} ht1对当前候选状态的影响程度。门值越接近0,丢弃的历史信息越多,主层(如Tanh激活单元)将更多依赖当前输入 x t x_t xt 重新计算候选状态。
    • 更新门(z):调节 h t − 1 h_{t-1} ht1 传递至当前状态 h t h_t ht 的比例。门值越接近1,保留的历史信息比例越高,新生成的信息比例越低。
  3. 工作流程

    • 步骤1:根据 h t − 1 h_{t-1} ht1 x t x_t xt 计算重置门 r t r_t rt 和更新门 z t z_t zt
    • 步骤2:利用 r t r_t rt 重置 h t − 1 h_{t-1} ht1,生成候选状态 h ~ t \tilde{h}_t h~t(通常通过Tanh激活)。
    • 步骤3:通过 z t z_t zt 加权融合 h t − 1 h_{t-1} ht1 h ~ t \tilde{h}_t h~t,输出最终状态 h t h_t ht

  • GRU单元结构的计算过程:
    z ( t ) = σ ( w x z T ⋅ x ( t ) + w h z T ⋅ h ( t − 1 ) ) r ( t ) = σ ( w x r T ⋅ x ( t ) + w h r T ⋅ h ( t − 1 ) ) g ( t ) = T a n h ( w x g T ⋅ x ( t ) + w h g T ⋅ ( r ( t ) ⊗ h ( t − 1 ) ) ) h ( t ) = ( 1 − z ( t ) ) ⊗ T a n h ( w x g T ⋅ h ( t − 1 ) + z ( t ) ⊗ g ( t ) ) \begin{array} { r l } & { z _ { ( t ) } = \sigma ( w _ { x z } ^ { \mathrm { T } } \cdot x _ { ( t ) } + w _ { h z } ^ { \mathrm { T } } \cdot h _ { ( t - 1 ) } ) } \\ & { r _ { ( t ) } = \sigma ( w _ { x r } ^ { \mathrm { T } } \cdot x _ { ( t ) } + w _ { h r } ^ { \mathrm { T } } \cdot h _ { ( t - 1 ) } ) } \\ & { g _ { ( t ) } = \mathrm { T a n h } ( w _ { x g } ^ { \mathrm { T } } \cdot x _ { ( t ) } + w _ { h g } ^ { \mathrm { T } } \cdot ( r _ { ( t ) } \otimes h _ { ( t - 1 ) } ) ) } \\ & { h _ { ( t ) } = ( 1 - z _ { ( t ) } ) \otimes \mathrm { T a n h } ( w _ { x g } ^ { \mathrm { T } } \cdot h _ { ( t - 1 ) } + z _ { ( t ) } \otimes g _ { ( t ) } ) } \end{array} z(t)=σ(wxzTx(t)+whzTh(t1))r(t)=σ(wxrTx(t)+whrTh(t1))g(t)=Tanh(wxgTx(t)+whgT(r(t)h(t1)))h(t)=(1z(t))Tanh(wxgTh(t1)+z(t)g(t))
  • w x z 、 w x r w_{xz}、w_{xr} wxzwxr w x g w_{xg} wxg是每一层连接到输入 x ( t ) x(t) x(t)的权重, W h z 、 W h r , W_{hz}、W_{hr}, WhzWhr, W h g W_{hg} Whg 是每一层连接到前一个短时记忆 h ( t − 1 ) h_{(t-1)} h(t1)的权重。