Truncated BPTT 是什么?为什么 RNN 训练需要截断反传?
简化版
Truncated BPTT 将长序列切成片段,隐状态数值跨片段传递,但在边界 detach,使梯度只回传固定步数。它降低显存和计算图长度,代价是无法通过梯度直接学习超过截断窗口的依赖。
详细版
-
chunk 长度控制梯度视野与显存。
-
状态传值与梯度跨界是两件事。
-
每个 chunk 后 detach,不是清零状态。
-
新序列边界才 reset。
-
优化器更新频率与 chunk 划分需明确。
完整版教学
一、截断的是计算图,不一定截断记忆数值
完整 BPTT 保存所有时间步激活,长流会无法承受。
TBPTT 让 state 继续携带过去信息,但把它视为下一段常量。
模型仍可能利用旧信息做预测,却无法把当前误差直接归因并更新很久以前的状态转换。
二、底层机制与公式
state=initial
for chunk in stream:
output,state=RNN(chunk,state)
backward(loss)
state=detach(state)
三、带数字的推演
序列 10,000 步,chunk=100 时每次图只覆盖约 100 步;状态从第 1 段传到第 100 段,但第 100 段损失不会反传 9900 步。
四、方案对比
| 方案/对象 | 核心特点 | 代价或边界 |
|---|---|---|
| 完整 BPTT | 梯度覆盖全序列 | 显存/数值成本高 |
| TBPTT | 可训练长流 | 长依赖梯度被截断 |
| Stateless chunks | 最简单 | 片段间信息也丢失 |
五、执行流程
按序列顺序分 chunk -> state 前向传递 -> chunk loss/backward
-> optimizer step -> detach state -> 下一 chunk -> 序列结束 reset
六、边界条件与工程代价
若 optimizer.step 后仍保留连接旧参数版本的图,容易原地修改报错;detach 时机需与更新循环一致。
多个序列并行时,结束样本的状态要按 mask 清零,不能等整个 batch 都结束。
记忆钩子:TBPTT 记“状态继续走,梯度到边界停”。
七、常见误区与追问
-
误区:detach 等于把 state 设为零。 它保留数值,只断开历史图。
-
追问:chunk 越长有什么代价? 显存、反向时间和梯度不稳定性增加。
-
误区:TBPTT 完全不能用长期信息。 数值状态可携带,但长期信用分配受限。
-
追问:何时 reset? 真正新序列或会话结束时。
-
追问:如何选截断长度? 按依赖跨度、显存和验证指标做消融。
八、加强记忆
TBPTT 记“状态继续走,梯度到边界停”。
detach 不清空记忆,reset 才清空;窗口长度决定信用分配范围。