Lec4 循环神经网络

动机: N-gram 和前馈模型的上下文有限(N-1 个标记)。RNN 理论上提供无限的上下文。

三种序列模型

  • 递归: 基于历史编码条件表示
  • 卷积: 基于局部上下文条件表示
  • 注意力: 基于所有标记的加权平均条件表示

基本 RNN (Elman, 1980)

一个序列模型 \(f_\theta(x_1, \ldots, x_{|x|}) \rightarrow h_1, \ldots, h_{|x|}\),在每一步转换隐藏状态:

\[h_t = \sigma(W_h h_{t-1} + W_x x_t + b)\]

其中 \(\sigma\) 是激活函数(tanh, relu),\(h_t \in \mathbb{R}^d\) 是隐藏状态,参数 \(\theta = \{W_h \in \mathbb{R}^{d \times d}, W_x \in \mathbb{R}^{d \times d_{in}}, b \in \mathbb{R}^d\}\)

用于语言建模: \(p_\theta(\cdot \mid x_{<t}) = \text{softmax}(W h_t)\)

RNN 训练

时间反向传播 (BPTT): 将 RNN 展开为 DAG 计算图,运行标准反向传播。

  • 每一步使用相同的参数;梯度被累积
  • 训练目标(最大似然估计):\(\min -\sum_{x \in D_{train}} \sum_t \log p_\theta(x_t \mid x_{<t})\)
  • 并行化困难: 在步骤 \(t\) 计算损失需要 \(h_t\),这依赖于 \(h_{t-1}, h_{t-2}, \ldots\)

RNN 推理

生成一个标记 → 使用新的隐藏状态 → 重复直到 [EOS]

  • 优点: 只需存储上一个隐藏状态(常量内存),每步 \(O(1)\),总长度 \(T\)\(O(T)\)
  • 缺点: 顺序处理,无法并行化

消失梯度

梯度在反向传播时减小:\(\frac{\partial L}{\partial h_0}\) 变得微小。

为什么? \(\frac{\partial h_T}{\partial h_t} = \prod_{t'=t}^{T} \frac{\partial h_{t'+1}}{\partial h_{t'}}\),其中 \(\frac{\partial h_{t'+1}}{\partial h_{t'}} = \text{diag}(\tanh'(\cdot)) W\)

\(W\) 的主特征值 \(< 1\) 时,梯度指数消失。影响: 无法建模长距离依赖关系!

门控:解决方案

基本思想: 通过学习的门在时间步之间传递信息。

\[h_t = (1 - z_t) \odot h_{t-1} + z_t \odot \tilde{h}_t\]

其中 \(z_t = \sigma(W_z x_t + U_z h_{t-1})\) 是更新门,\(\tilde{h}_t\) 是候选状态。

  • \(z \to 0\):保留长期信息(\(\frac{\partial h_{t_2}}{\partial h_{t_1}} = 1\)
  • \(z > 0\):结合新的隐藏状态

GRU (Cho et al., 2014)

2-门架构: - 更新门 \(z_t\):我应该更新上一个隐藏状态吗? - 重置门 \(r_t = \sigma(W_r x_t + U_r h_{t-1})\):我应该在更新中使用隐藏状态吗?

\[\hat{h}_t = \tanh(W_h x_t + U_h(r_t \odot h_{t-1})), \quad h_t = (1-z_t) \odot h_{t-1} + z_t \odot \hat{h}_t\]

LSTM (Hochreiter & Schmidhuber, 1997)

4-门架构,带有额外的上下文向量。在实践中,GRU/LSTM 是对普通 RNN 的替代。

编码器-解码器

动机: 条件生成 \(p_\theta(y_1, \ldots, y_T \mid x)\)(例如,翻译、摘要)

架构: 将输入 \(x\) 编码为上下文向量 \(c \in \mathbb{R}^d\),在解码器中使用: - 初始化解码器隐藏状态 - 包含在递归更新中:\(W[h_t; x_t; c]\) - 包含在输出层:\(\text{softmax}(W[h_t; c])\)

训练: \(\min_\theta \sum_{(x,y) \in D} \sum_t -\log p_\theta(y_t \mid y_{<t}, x)\)

局限性: 所有标记只有一个上下文向量——我们能做得更好吗?

注意力 (Bahdanau et al., 2015)

关键思想: 在每个解码器步骤计算不同的上下文向量,作为编码器状态的加权和。

  • 键: 编码器状态 \(h_1^{enc}, \ldots, h_N^{enc}\)
  • 查询: 当前解码器隐藏状态 \(h\)
  • 注意力分数: \(\alpha_n = \text{score}(h, h_n^{enc})\)
  • 上下文向量: \(c = \sum_{n=1}^{N} \alpha_n h_n^{enc}\)

分数函数: - 点积:\(\text{score}(q, k) = q^\top k\) - 双线性:\(\text{score}(q, k) = q W k\) - 非线性:\(\text{score}(q, k) = w^\top \tanh(W[q; k])\)

用法: \(\text{logits} = \tanh(W_{out}[c_t; h_t])\)

关键要点

  • RNN:具有递归隐藏状态的序列模型(理论上无限上下文)
  • 普通 RNN 遇到消失梯度问题 → 使用 GRU/LSTM
  • 编码器-解码器用于条件生成
  • 注意力:通过编码器状态的加权和动态上下文向量
  • RNN 训练是顺序的(难以并行化)→ 激励变换器(下一讲)

Lec5 变换器

此内容类似于 CS336-Lec3 架构与超参数

image-20260130002623323

image-20260130002716882

注意力分数函数:最常用的函数是 缩放点积。这解决了点积的规模随着维度增大而增加的问题。 \[ a(q, k) = \frac{q^\top k}{\sqrt{|k|}} \] image-20260130003730167

多头的直觉:句子不同部分的信息可以以不同方式帮助消歧。

image-20260130011718563