1041 字
5 分钟
从零开始深度学习 Day 3 RNN 循环神经网络

拼劲全力肘赢数字电路 11/05 前的所有作业,请让我在周三前过完最基础的 RNN。

RNN 的优势#

  • RNN (Recurrent) 意为“循环”。
  • 适合处理有周期性或序列依赖的数据。

序列模型#

xtP(xtxt1,,x1)x_t \sim P(x_t | x_{t-1} , \dots, x_1)

自回归模型#

自回归模型:保存过去时间的一段数据(autoregressive models)#

[xt1,xtτ][x_{t-1}, x_{t-\tau}]

使用固定长度 τ\tau 的窗口,参数数量固定。

隐变量自回归模型:保存一个隐状态 ht1h_{t-1}(latent autoregressive models)#

ztp(ztzt1,xt1)(隐变量动态模型)xtp(xtzt,xt1)(观测生成模型)\begin{aligned} z_t &\sim p(z_t \mid z_{t-1}, x_{t-1}) \quad &\text{(隐变量动态模型)}\\ x_t &\sim p(x_t \mid z_t, x_{t-1}) \quad &\text{(观测生成模型)} \end{aligned}

引入隐变量 ztz_t(不可观测)来捕捉复杂的时序结构和未观测到的动态,简化建模过程。

马尔可夫链#

假设当前状态只依赖于前一个或前几个状态(马尔可夫假设)。

因果#

模型假设 xtx_t 是由 xt1x_{t-1} 引起的,具有因果性。

NLP 入门#

文本预处理#

将文本切分为词元(Token),并建立词汇表索引:

f(word):vf(\text{word}) : \vec{v}

语言模型#

语言模型 (LM) 估计词元序列的联合概率:

P(x1,x2,...,xT)P(x_1, x_2, ..., x_T)

用于评估句子合理性或生成文本,辅助语音识别、机器翻译等任务。

根据链式法则:

P(deep,learning,is,fun)=P(deep)P(learningdeep)P(isdeep,learning)P(fundeep,learning,is).P(\text{deep}, \text{learning}, \text{is}, \text{fun}) = P(\text{deep}) P(\text{learning} \mid \text{deep}) P(\text{is} \mid \text{deep}, \text{learning}) P(\text{fun} \mid \text{deep}, \text{learning}, \text{is}).

n-gram 频率估计

P^(learning | deep)=n(deep, learning)n(deep)\hat{P}(\text{learning | deep}) = \frac{n(\text{deep, learning})}{n(\text{deep})}

拉普拉斯平滑补偿#

使用拉普拉斯平滑(加一平滑)解决 n-gram 中的“零概率”问题。

P(wic)=count(wi,c)+αjcount(wj,c)+α×VP(w_i | c) = \frac{\text{count}(w_i, c) + \alpha}{\sum_j \text{count}(w_j, c) + \alpha \times V}

n阶马尔可夫递推#

n-gram (n阶马尔可夫) 中,n 越大,上下文越长,但数据稀疏问题越严重。

齐普夫定律(Zipf’s Law)#

n(x)1xsn(x) \propto \frac{1}{x^s}

词频与其排名 xx 成反比(幂律分布)。高频词主导,低频词众多。

读取长序列数据的方法#

为训练神经网络,长文本需切分为固定长度的子序列:

  • 随机采样(Random Sampling):从文本中随机抽取片段,批次间不一定连续。
  • 顺序分区(Sequential Partitioning):按顺序划分文本,保证批次间的连续性。

循环神经网络#

对于一个普通的多层感知机 (MLP):

H=ϕ(XWxh+bh)O=HWhq+bqH = \phi(XW_{xh} + b_h) \\ O = HW_{hq} + b_q

MLP 无法处理时序依赖,因其样本间计算相互独立。

RNN 引入隐状态,使当前输出依赖于前一时间步的状态:

Ht=ϕ(XtWxh+Ht1Whh+bh)Ot=HtWhq+bqH_t = \phi(X_tW_{xh} + H_{t-1}W_{hh} + b_h) \\ O_t = H_tW_{hq} + b_q
  • WxhW_{xh}:输入到隐状态的权重
  • WhhW_{hh}:隐状态到隐状态的权重(循环连接)
  • WhqW_{hq}:隐状态到输出的权重
  • 所有时间步共享相同参数,参数量不随序列长度增加。

隐状态 HtH_t 捕捉过去的序列信息(记忆/上下文)。

RNN 的计算#

RNN 在时间上是“展开的”:

  • 每个时间步都接收输入 XtX_t
  • 隐状态从 Ht1H_{t-1} 传递到 HtH_t
  • 输出 OtO_t 可用于预测或损失计算。

数学上等价于对输入与隐状态进行拼接:

Ht=ϕ([Xt,Ht1][Wxh;Whh]+bh)H_t = \phi\big([X_t, H_{t-1}][W_{xh}; W_{hh}] + b_h\big)

困惑度(Perplexity)#

困惑度 (PPL) 是评估语言模型性能的指标,基于交叉熵损失 ll

l=1Tt=1TlogP(wtw<t)l = -\frac{1}{T} \sum_{t=1}^{T} \log P(w_t | w_{<t})

困惑度定义为:

PPL=exp(l)\text{PPL} = \exp(l)

PPL 越低,模型预测越准确。

情况困惑度含义
理想模型(预测正确)1完美预测
均匀分布=词汇表大小随机猜测
错误模型\to \infty完全不确定

当前痛点#

  1. 输出维度问题:若预测下一个字符,输出维度 = 词汇表大小。
  2. RNN的条件概率表示:RNN 可基于所有先前词元的隐状态计算当前词元的条件概率。
  3. 梯度消失与爆炸问题:长序列反向传播时,梯度会指数衰减或爆炸,这是 RNN 的主要挑战。
  4. RNN 语言模型的局限
    • 难以捕捉长期依赖;
    • 训练缓慢;
    • 对序列长度敏感。 (后续会通过 LSTM 和 GRU 改进。)

实践 RNN#

梯度裁剪#

梯度裁剪 (Gradient Clipping) 用于防止梯度爆炸:

g:=θgg g := \frac{\theta g}{||g||}

防止不了梯度消失。

相关学习资料#

  • d2l
从零开始深度学习 Day 3 RNN 循环神经网络
https://blog.candlest.cc/posts/ai/rnn_i/
作者
candlest
发布于
2025-10-21
许可协议
CC BY-NC-SA 4.0