EECS498 · Sequence Models · 08

LSTM: Better Memory, Same Sequential Bottleneck

LSTM 的关键不是背四条 gate equation,而是为“保留、写入、读出”设计一条更直接的 memory path。它改善长期记忆,却没有让 time steps 变得并行。

80–100 分钟A4 CaptioningCell state · gates · gradient path

30-second recall

30 秒回忆

你实现了 lstm_step_forward/backward 和 sequence wrapper。一次 affine 同时产生四个 H-wide gate blocks。

  1. cell state 与 hidden state 分别承担什么角色?
  2. gate 为什么用 sigmoid?candidate 为什么用 tanh?
  3. LSTM 没解决什么?

Before We Start

普通 RNN 的核心长期问题?

affine 输出 shape [N,4H] 的原因?

LSTM 可完全并行所有 time steps 吗?

Problem · 每一步都完整重写记忆

普通 RNN 的 h_t=tanh(x_tWx+h_{t-1}Wh+b) 强迫历史每一步穿过 affine+tanh。即使此刻没有新信息值得写入,也必须生成一份全新 h_t。我们想要更细的控制:

Keep / forget旧 memory 有多少直接留下?
Write当前 candidate 写入多少?
Read / exposememory 的哪些部分成为 visible hidden state?

从三个需求推出 gates

[i, f, o, g] = split(x_t W_x + h_{t-1} W_h + b)
i = sigmoid(i)       input/write gate       [N,H]
f = sigmoid(f)       forget/keep gate       [N,H]
o = sigmoid(o)       output/read gate        [N,H]
g = tanh(g)          candidate content       [N,H]

c_t = f ⊙ c_{t-1} + i ⊙ g
h_t = o ⊙ tanh(c_t)
  1. Sigmoid 将控制量压到 0…1,适合作为逐 feature valve;它不是硬开关。
  2. f⊙c_prev 决定旧 memory 的直接保留比例。
  3. i⊙g 决定候选内容写入多少。
  4. 两条 additive paths 汇合成新 cell state。
  5. o⊙tanh(c_t) 决定当前对外暴露的 hidden state。
Mental model

Cell state 是受门控的 memory highway;hidden state 是本时刻暴露给输出和下一步计算的 view。

Worked Example · 不背 gate,算一次 memory update

对某一个 cell feature,设:

c_prev = 2.0
f = 0.9      keep most old memory
i = 0.2      write a little
g = -0.5     candidate content
o = 0.8

c_t = 0.9×2.0 + 0.2×(-0.5) = 1.7
h_t = 0.8×tanh(1.7) ≈ 0.748

旧 memory 大部分沿乘法加法路径保留,新 evidence 只小幅修正它。若 f≈1、i≈0,则 c_t≈c_prev,近似复制。

如果没有 forget gate,固定 f=1?

旧信息永远累积,模型难以主动清除已失效内容;cell 可能不断叠加 candidates。

如果没有 input gate,固定 i=1?

每一步 candidate 都被完整写入,memory 无法在“不值得更新”时保持稳定。

为什么它改善 long-range gradient?

沿 cell path 的局部导数包含 ∂c_t/∂c_{t-1}=f_t(还需考虑 gates 的间接路径)。当模型令 relevant dimensions 的 f 接近 1,gradient 可沿 additive memory path 比反复经过 tanh recurrence 更直接地传播。

c₁ ─×f₂→ c₂ ─×f₃→ c₃ ...

ordinary RNN: h₁ → affine+tanh → h₂ → affine+tanh → ...

这不是保证永不 vanishing:多个 f<1 相乘仍会缩小,其他 paths 也存在。LSTM 给模型的是可学习的保留机制,不是无限记忆证明。

Your Code · 一次 affine,四种角色

Your code · A4

A4/rnn_lstm_attention_captioning.py · lstm_step_forward()

View source →
a = x.mm(Wx) + prev_h.mm(Wh) + b
ai, af, ao, ag = torch.chunk(a, 4, dim=1)
i, f, o = torch.sigmoid(ai), torch.sigmoid(af), torch.sigmoid(ao)
g = torch.tanh(ag)
next_c = f * prev_c + i * g
next_h = o * torch.tanh(next_c)

Wx [D,4H] 与 Wh [H,4H] 让 affine 输出 [N,4H];chunk 后每个 gate [N,H]。四倍是 feature packing,不是额外 time 或 batch 轴。

Inline check. N=8,D=32,H=64,Wx/Wh/b shapes?

它没有解决什么?

要计算 c_t/h_t,仍必须先得到 c_{t-1}/h_{t-1}。LSTM 改善了沿链保存什么,没有删除链本身:

(h₁,c₁) → (h₂,c₂) → ... → (h₁₀,c₁₀)

long-range memory: improved
time-step parallelism: still blocked
direct token-to-token access: still absent

LSTM

token 10 若需 token 1,相关信息须保存在每一个中间 cell update 中。

Attention

token 10 构造 query,直接与 token 1 key 匹配并读取 value。

Misconception diagnosis

“LSTM memory 就是完整保存过去 tokens”不准确。c_t 仍是固定 H-dimensional learned compression;gates 选择保留/覆盖哪些 features,不是无损事件日志。

Deep Dive · 为什么 gate bias 初始化常被讨论?

若 forget gate 初期太小,memory 很快衰减;一些实现给 forget bias 正初始化以鼓励初期保留。但这是 optimization heuristic,不改变 equations,也不能替代任务学习。历史 repository 行为应按实际代码记录,不反向声称采用了某现代 convention。

End-of-Lesson Deep Checks

f=1、i=0 时 cell 发生什么?

c_t=c_{t-1},memory 直接复制;h_t 仍受 output gate 与 tanh 影响。

为什么 c_t 用加法合并 old/new path 有帮助?

它提供相对直接的 identity-like path,gradient 不必在每一步只穿过完整 nonlinear rewrite。

output gate=0 会擦除 cell memory 吗?

不会;它令当前 h_t 不暴露该 memory,但 c_t 可继续传到下一步。

LSTM 为什么仍难以沿 time 并行?

每一步 gates 依赖 h_{t-1},cell update 依赖 c_{t-1}。

Transfer Questions

  1. 若某 dimension 连续 20 步 f=0.95 且无写入,旧 memory 剩余比例约是多少?
  2. GRU 合并部分 gates,改变了哪些参数化选择,是否删除 recurrence?
  3. 若任务要求随机读取 1,000 步前某个 token,固定 cell compression 与 attention memory 各有什么 tradeoff?

闭卷解释

  1. 不背 gate 名称,从 keep/write/read 三个需求推出 LSTM。
  2. 解释 cell state 与 hidden state 的不同。
  3. 为什么 LSTM 改善 gradient,却没有解决 sequential bottleneck?

Then I implemented: four packed gates、additive cell update、hidden exposure.

Now I understand: LSTM 给 recurrence 加了一条可门控的 memory highway;它修了“怎样沿链记住”,没修“为什么必须沿链走”。

Connection · 从压缩过去到直接读取

Transformer 不再要求一个 state 依次吞掉整段历史。它保留每个 token 的 representation,让当前位置用内容相关 query 直接读取其他 positions。下一课先回答这些 positions 如何从字符串变成 vectors。

Based on your implementation