快速过一遍RNN。

简要

RNN 循环神经网络 recurrent neural network,因此网络正向传播时是在同一个网络上「转圈」进行的——表现为将上一轮的参加进下一轮的输入。

RNN 和 CNN、MLP 架构最主要的特点在于支持可变长输入的处理。

RNN的核心思想在于两点:

  1. 将「要对可变输入推理」切分为「对固定大小的块」处理。也就是将可能大可能小的蛋糕切分成固定小块处理。
  2. 对每小块输入的处理结果x接入对下一个小块输入的处理中作为输入的一部分。——x就是隐状态。

问题切分和隐状态蕴含先前信息是RNN的核心,这也是为什么RNN可以处理变长序列的原因。

架构

设神经网络正向传播为 为要预测的序列,以预测 为例。

按顺序计算: 理解隐状态,就能理解RNN。

2025-05-09 13:47:45补充 简单说就是有一个神经网络,然后输入数据,获得输出,再将输出作为第二个输入的附加部分,这样子就可以接收序列输入,并产生序列输出。每次的输出都包含了过去状态的信息(因为输出和过去的所有输入都相关)

训练

踩到了自己的脚。

RNN的训练理论上很简单,跟普通的网络一样进行梯度下降就行了。不过实际上很麻烦,原因还是在于它「当前输出依赖过去输入」的毛病致使它想要给某个输入进行梯度下降,那么它就得先把在他之后的输入先进行梯度下降。

同时因为它是反复将输入通过神经网络,所以当输入序列很长的时候,网络可以看成是一个具有相当长层数的网络,不可避免地遇见了梯度爆炸和梯度消失问题,所以训练起来也很困难。


AI 补充(我写的确实有遗漏的点)

检查错误和润色补充:

  1. 【简要】部分:

    • 评价: 准确地指出了 RNN 的核心特点和与 CNN/MLP 的主要区别。
    • 润色/补充: “因此网络正向传播时是在同一个网络上「转圈」进行的——表现为将上一轮的参加进下一轮的输入。” 这个比喻很生动。可以稍微规范一下术语,将“上一轮的参加”说成是**“上一时刻的隐状态(或输出)”**。
  2. 【核心思想】部分:

    • 评价: 这两点概括得非常到位,是 RNN 能够处理序列数据的根本。
    • 润色/补充: “切分为固定大小的块处理” 更准确地说,是将序列的每个时间步作为一个“块”进行处理。隐状态确实是蕴含了先前所有时间步信息(理论上)的载体。
  3. 【架构】部分:

    • 评价: 理解方向是正确的,即当前计算依赖于过去的信息。

    • 关键错误: 这里的数学表达式 f(t2​)=f(f(t1​),t1​) 等等,与标准的 RNN 前向传播公式不符**,并且容易引起混淆。在标准的 RNN 中,f 通常代表了计算当前隐状态的函数,它接收当前时间步的输入上一时间步的隐状态

    • 纠正/补充: 标准的 RNN 前向传播可以这样表示:

      • 输入序列:x1​,x2​,…,xn​
      • 输出序列:y1​,y2​,…,yn​ (或者只关心最后的输出 yn​,取决于任务)
      • 隐状态序列:h1​,h2​,…,hn​ (h0​ 通常初始化为零向量)

      每个时间步 t,RNN 进行如下计算: ht​=f(Whh​ht−1​+Wxh​xt​+bh​) yt​=g(Why​ht​+by​) 其中:

      • xt​ 是当前时间步的输入。
      • ht​ 是当前时间步的隐状态。
      • ht−1​ 是上一时间步的隐状态。
      • Whh​,Wxh​,Why​ 是权重矩阵(在所有时间步共享)。
      • bh​,by​ 是偏置向量(在所有时间步共享)。
      • f 和 g 是激活函数(如 tanh, ReLU, softmax 等)。

      这里的 f 函数(计算隐状态)才是 RNN 的核心,它将当前输入 xt​上一时刻的隐状态 ht−1​ 结合起来,产生当前时刻的隐状态 ht​。然后,ht​ 可以用于计算当前时刻的输出 yt​。

      理解 RNN 架构的一个常用方法是将其进行**“展开 (Unrolling)”**。展开后,RNN 可以看作是一个非常深(层数等于序列长度)的前馈神经网络,每一层对应序列中的一个时间步,且相邻层之间通过隐状态连接,并共享权重。这有助于理解它的训练过程。

  4. 【2025-05-09 补充】部分:

    • 评价: 这段直观描述非常好,准确地概括了 RNN 通过隐状态传递历史信息、处理序列输入和产生序列输出的过程。
    • 润色/补充: 可以强调权重共享是 RNN 的一个重要特点,即在每个时间步使用的是同一套权重 Whh​,Wxh​,Why​,bh​,by​。
  5. 【训练】部分:

    • 评价: 准确地指出了训练困难的根源——反向传播的依赖性以及长序列导致的梯度问题。
    • 润色/补充:
      • 将 “想要给某个输入进行梯度下降,那么它就得先把在他之后的输入先进行梯度下降” 这种描述具体化为:RNN 的训练方法是反向传播通过时间 (Backpropagation Through Time, BPTT)。BPTT 的过程就像在展开的 RNN 图上进行反向传播,计算当前时间步的梯度需要依赖后续所有时间步的梯度,所以计算是从序列末尾开始向前进行的。
      • “当输入序列很长的时候,网络可以看成是一个具有相当长层数的网络” 这正是通过“展开”视角来看待 RNN。
      • 准确指出了 梯度爆炸 (Exploding Gradients)梯度消失 (Vanishing Gradients) 是主要问题。梯度爆炸相对容易处理(梯度裁剪 Gradient Clipping),但梯度消失更麻烦,因为它使得 RNN 难以学习到序列中远距离的依赖关系。
      • 可以提及正是为了解决梯度消失问题,才诞生了 RNN 的重要变体:长短期记忆网络 (LSTM)门控循环单元 (GRU)。它们通过引入门控机制来更有效地控制和传递信息,缓解了梯度问题,使得网络能够学习到更长距离的依赖。

总结和建议:

你的笔记已经非常接近 RNN 的核心。主要的改进点在于:

  1. 纠正数学公式: 采用标准的 RNN 前向传播公式 (ht​ 的计算)。
  2. 引入标准术语: 明确使用“隐状态 (Hidden State)” ht​ 和“输入 (Input)” xt​。
  3. 明确训练算法: 提及 BPTT (Backpropagation Through Time)。
  4. 补充实际解决方案: 简要介绍 LSTM 和 GRU 作为对原始 RNN 梯度问题的改进。
  5. 考虑加入图示: 一个“展开的 RNN”图会非常直观地帮助理解架构和训练过程。

总的来说,你的笔记基础很好,经过上述调整后会更加准确和全面。继续加油!

修改历史

  1. 初稿。2025-04
  2. 修改。2025-05-09 13:53:32

参考资料