15天学习大模型打卡(2):从 RNN 到 Transformer 的跨越
文章目录
关键词:隐藏状态、门控机制、Self-Attention、位置编码、梯度消失
15天学习大模型打卡(2):从 RNN 到 Transformer 的跨越
一、RNN:循环神经网络(Recurrent Neural Network)
🧠 核心思想
在每个时间步 $ t $,模型接收输入 $ x_t $,并结合上一时刻的隐藏状态 $ h_{t-1} $,计算当前状态 $ h_t $。
✅ 数学公式
h t = tanh ( W h h h t − 1 + W x h x t + b h ) y t = W h y h t + b y \begin{align*} h_t &= \tanh(W_{hh} h_{t-1} + W_{xh} x_t + b_h) \\ y_t &= W_{hy} h_t + b_y \end{align*} htyt=tanh(Whhht−1+Wxhxt+bh)=Whyht+by
- h t ∈ R h h_t \in \mathbb{R}^h ht∈Rh:隐藏状态(记忆)
- x t ∈ R d x_t \in \mathbb{R}^d xt∈Rd:输入词向量
- y t ∈ R V y_t \in \mathbb{R}^V yt∈RV:输出(通常是词表上的概率分布)
- W h h , W x h , W h y W_{hh}, W_{xh}, W_{hy} Whh,Wxh,Why:可学习权重矩阵
- tanh \tanh tanh:激活函数,压缩数值范围
📐 网络架构(时间展开)
x₁ x₂ x₃ x_T
↓ ↓ ↓ ↓
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
→ │ h₁ │→│ h₂ │→│ h₃ │→ ... │ h_T │→ y_T
└─────┘ └─────┘ └─────┘ └─────┘
↑ ↑ ↑ ↑
h₀ h₁ h₂ h_{T-1}
每个 h t h_t ht 依赖 h t − 1 h_{t-1} ht−1,形成链式结构。
⚠️ 问题:梯度消失/爆炸
反向传播时,梯度通过链式法则:
∂ L ∂ h 1 = ∂ L ∂ h T ⋅ ∏ t = 2 T ∂ h t ∂ h t − 1 \frac{\partial L}{\partial h_1} = \frac{\partial L}{\partial h_T} \cdot \prod_{t=2}^T \frac{\partial h_t}{\partial h_{t-1}} ∂h1∂L=∂hT∂L⋅t=2∏T∂ht−1∂ht
若 ∥ ∂ h t ∂ h t − 1 ∥ < 1 \left\| \frac{\partial h_t}{\partial h_{t-1}} \right\| < 1
∂ht−1∂ht
<1,梯度指数衰减 → 早期信息丢失
二、LSTM:长短期记忆网络
🎯 核心结构
LSTM 引入细胞状态 c t c_t ct 作为长期记忆通道,并通过三个门控制信息流动。
✅ 数学公式
f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) 遗忘门 i t = σ ( W i ⋅ [ h t − 1 , x t ] + b i ) 输入门 c ~ t = tanh ( W c ⋅ [ h t − 1 , x t ] + b c ) 候选记忆 c t = f t ⊙ c t − 1 + i t ⊙ c ~ t 更新细胞状态 o t = σ ( W o ⋅ [ h t − 1 , x t ] + b o ) 输出门 h t = o t ⊙ tanh ( c t ) 输出隐藏状态 \begin{align*} f_t &= \sigma(W_f \cdot [h_{t-1}, x_t] + b_f) && \text{遗忘门} \\ i_t &= \sigma(W_i \cdot [h_{t-1}, x_t] + b_i) && \text{输入门} \\ \tilde{c}_t &= \tanh(W_c \cdot [h_{t-1}, x_t] + b_c) && \text{候选记忆} \\ c_t &= f_t \odot c_{t-1} + i_t \odot \tilde{c}_t && \text{更新细胞状态} \\ o_t &= \sigma(W_o \cdot [h_{t-1}, x_t] + b_o) && \text{输出门} \\ h_t &= o_t \odot \tanh(c_t) && \text{输出隐藏状态} \end{align*} ftitc~tctotht=σ(Wf⋅[ht−1,xt]+bf)=σ(Wi⋅[ht−1,xt]+bi)=tanh(Wc⋅[ht−1,xt]+bc)=ft⊙ct−1+it⊙c~t=σ(Wo⋅[ht−1,xt]+bo)=ot⊙tanh(ct)遗忘门输入门候选记忆更新细胞状态输出门输出隐藏状态
- σ \sigma σ:Sigmoid 函数(输出 0~1,控制“通过多少”)
- ⊙ \odot ⊙:逐元素相乘(Hadamard 积)
- [ h t − 1 , x t ] [h_{t-1}, x_t] [ht−1,xt]:拼接向量
📐 LSTM 单元结构(ASCII 图)
x_t h_{t-1}
↓ ↓
+-----------------+
| Forget Gate f_t| → f_t ⊙ c_{t-1}
| Input Gate i_t| → i_t ⊙ c̃_t
|Candidate ĉ_t |
| Output Gate o_t| → o_t ⊙ tanh(c_t)
+-----------------+
↓
c_{t-1} → ⊗ → c_t → tanh → ⊗ → h_t
↑ ↑ ↑
└─────────┘ │
h_t
细胞状态 c t c_t ct 像一条“信息高速公路”,贯穿整个序列,门控决定信息的增删。
GRU(Gated Recurrent Unit)
简化公式:
z t = σ ( W z ⋅ [ h t − 1 , x t ] ) 更新门 r t = σ ( W r ⋅ [ h t − 1 , x t ] ) 重置门 h ~ t = tanh ( W h ⋅ [ r t ⊙ h t − 1 , x t ] ) 候选状态 h t = ( 1 − z t ) ⊙ h t − 1 + z t ⊙ h ~ t 最终状态 \begin{align*} z_t &= \sigma(W_z \cdot [h_{t-1}, x_t]) && \text{更新门} \\ r_t &= \sigma(W_r \cdot [h_{t-1}, x_t]) && \text{重置门} \\ \tilde{h}_t &= \tanh(W_h \cdot [r_t \odot h_{t-1}, x_t]) && \text{候选状态} \\ h_t &= (1 - z_t) \odot h_{t-1} + z_t \odot \tilde{h}_t && \text{最终状态} \end{align*} ztrth~tht=σ(Wz⋅[ht−1,xt])=σ(Wr⋅[ht−1,xt])=tanh(Wh⋅[rt⊙ht−1,xt])=(1−zt)⊙ht−1+zt⊙h~t更新门重置门候选状态最终状态
💡 GRU 将细胞状态和隐藏状态合并,用两个门完成 LSTM 三个门的功能,更轻量。
三、Transformer:自注意力机制详解
🏗 整体架构(Encoder 部分)
Input Sequence: [x₁, x₂, ..., x_T]
↓
Embedding + Positional Encoding
↓
┌───────────────────────────────┐
│ Transformer Block │
│ │
│ ┌─────────────────────────┐ │
│ │ Multi-Head Attention │←─── Query, Key, Value
│ └─────────────────────────┘ │
│ ↓ │
│ LayerNorm + Residual │
│ ↓ │
│ ┌─────────────────────────┐ │
│ │ Feed-Forward Network │ │
│ └─────────────────────────┘ │
│ ↓ │
│ LayerNorm + Residual │
│ │
└───────────────────────────────┘
↓
[h₁, h₂, ..., h_T] → 上下文感知表示
🔍 Self-Attention 详细计算
1. 输入表示
每个词 x i x_i xi 转为向量 x i ∈ R d \mathbf{x}_i \in \mathbb{R}^d xi∈Rd
2. 线性变换(生成 Q, K, V)
Q = X W Q K = X W K V = X W V \begin{align*} \mathbf{Q} &= \mathbf{X} W_Q \\ \mathbf{K} &= \mathbf{X} W_K \\ \mathbf{V} &= \mathbf{X} W_V \\ \end{align*} QKV=XWQ=XWK=XWV
- X ∈ R T × d \mathbf{X} \in \mathbb{R}^{T \times d} X∈RT×d:输入矩阵
- W Q , W K , W V ∈ R d × d k W_Q, W_K, W_V \in \mathbb{R}^{d \times d_k} WQ,WK,WV∈Rd×dk:可学习权重
3. 计算注意力分数
Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{softmax}\left( \frac{QK^T}{\sqrt{d_k}} \right) V Attention(Q,K,V)=softmax(dkQKT)V
- Q K T ∈ R T × T QK^T \in \mathbb{R}^{T \times T} QKT∈RT×T:相似度矩阵
- d k \sqrt{d_k} dk:缩放因子,防止梯度消失
- softmax:归一化为概率分布
4. 多头注意力(Multi-Head)
MultiHead ( Q , K , V ) = Concat ( head 1 , . . . , head h ) W O \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, ..., \text{head}_h) W^O MultiHead(Q,K,V)=Concat(head1,...,headh)WO
其中:
head i = Attention ( Q W i Q , K W i K , V W i V ) \text{head}_i = \text{Attention}(Q W_i^Q, K W_i^K, V W_i^V) headi=Attention(QWiQ,KWiK,VWiV)
- 每个“头”关注不同语义(如语法、指代、情感)
- W O W^O WO:合并输出
📍 位置编码(Positional Encoding)
因为 Self-Attention 不关心顺序,必须加入位置信息。
常用正弦编码:
P E ( p o s , 2 i ) = sin ( p o s 1000 0 2 i / d ) P E ( p o s , 2 i + 1 ) = cos ( p o s 1000 0 2 i / d ) PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d}}\right) \\ PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d}}\right) PE(pos,2i)=sin(100002i/dpos)PE(pos,2i+1)=cos(100002i/dpos)
- p o s pos pos:位置索引
- i i i:维度索引
- 偶数位用 sin,奇数位用 cos
最终输入:
z i = x i + p i \mathbf{z}_i = \mathbf{x}_i + \mathbf{p}_i zi=xi+pi
🧩 Feed-Forward Network(FFN)
每个位置独立处理:
FFN ( x ) = W 2 ⋅ ReLU ( W 1 x + b 1 ) + b 2 \text{FFN}(x) = W_2 \cdot \text{ReLU}(W_1 x + b_1) + b_2 FFN(x)=W2⋅ReLU(W1x+b1)+b2
- 通常是两层全连接网络
- 增强非线性表达能力
🔁 残差连接与层归一化
每个子层都有:
LayerNorm ( x + Sublayer ( x ) ) \text{LayerNorm}(x + \text{Sublayer}(x)) LayerNorm(x+Sublayer(x))
- 残差连接:防止梯度消失
- LayerNorm:稳定训练
四、对比总结(含架构特性)
| 特性 | RNN | LSTM | GRU | Transformer |
|---|---|---|---|---|
| 记忆机制 | 隐藏状态 $ h_t $ | 细胞状态 $ c_t $ + 门控 | 更新门 + 重置门 | Self-Attention 权重 |
| 并行性 | ❌ 串行 | ❌ 串行 | ❌ 串行 | ✅ 全并行 |
| 长期依赖 | 差 | 较好 | 较好 | 极好 |
| 参数量 | 小 | 中 | 中 | 大 |
| 训练速度 | 慢 | 慢 | 中 | 快(并行) |
| 架构核心 | 时间递归 | 门控 + 细胞状态 | 双门简化 | 多头注意力 + FFN |
五、代码风格伪代码(帮助理解)
# RNN Cell
def rnn_step(x_t, h_prev, W_hh, W_xh, b):
h_t = tanh(W_hh @ h_prev + W_xh @ x_t + b)
return h_t
# LSTM Cell
def lstm_step(x_t, h_prev, c_prev, W_f, W_i, W_c, W_o, b_f, b_i, b_c, b_o):
concat = concat(h_prev, x_t)
f = sigmoid(W_f @ concat + b_f) # 遗忘门
i = sigmoid(W_i @ concat + b_i) # 输入门
c_tilde = tanh(W_c @ concat + b_c) # 候选记忆
c_t = f * c_prev + i * c_tilde # 更新细胞状态
o = sigmoid(W_o @ concat + b_o) # 输出门
h_t = o * tanh(c_t) # 输出隐藏状态
return h_t, c_t
六、学习建议
- ✅ 推荐阅读:The Illustrated Transformer
- ✅ 动手实现:用 NumPy 写一个简易 Self-Attention
- ✅ 可视化工具:BERT-Viz 查看注意力头
这里的也留下来一个测试,各位同学可以试试,两天后我会发布代码
🚀 下一讲预告:我们将用 PyTorch 实现一个迷你 Transformer,从数据预处理到训练,完整走一遍流程!
更多推荐


所有评论(0)