LSTM
token 10 若需 token 1,相关信息须保存在每一个中间 cell update 中。
EECS498 · Sequence Models · 08
LSTM 的关键不是背四条 gate equation,而是为“保留、写入、读出”设计一条更直接的 memory path。它改善长期记忆,却没有让 time steps 变得并行。
30-second recall
你实现了 lstm_step_forward/backward 和 sequence wrapper。一次 affine 同时产生四个 H-wide gate blocks。
普通 RNN 的核心长期问题?
affine 输出 shape [N,4H] 的原因?
LSTM 可完全并行所有 time steps 吗?
普通 RNN 的 h_t=tanh(x_tWx+h_{t-1}Wh+b) 强迫历史每一步穿过 affine+tanh。即使此刻没有新信息值得写入,也必须生成一份全新 h_t。我们想要更细的控制:
[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)
f⊙c_prev 决定旧 memory 的直接保留比例。i⊙g 决定候选内容写入多少。o⊙tanh(c_t) 决定当前对外暴露的 hidden state。Cell state 是受门控的 memory highway;hidden state 是本时刻暴露给输出和下一步计算的 view。
对某一个 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,近似复制。
旧信息永远累积,模型难以主动清除已失效内容;cell 可能不断叠加 candidates。
每一步 candidate 都被完整写入,memory 无法在“不值得更新”时保持稳定。
沿 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 · A4
A4/rnn_lstm_attention_captioning.py · lstm_step_forward()
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
token 10 若需 token 1,相关信息须保存在每一个中间 cell update 中。
token 10 构造 query,直接与 token 1 key 匹配并读取 value。
“LSTM memory 就是完整保存过去 tokens”不准确。c_t 仍是固定 H-dimensional learned compression;gates 选择保留/覆盖哪些 features,不是无损事件日志。
若 forget gate 初期太小,memory 很快衰减;一些实现给 forget bias 正初始化以鼓励初期保留。但这是 optimization heuristic,不改变 equations,也不能替代任务学习。历史 repository 行为应按实际代码记录,不反向声称采用了某现代 convention。
c_t=c_{t-1},memory 直接复制;h_t 仍受 output gate 与 tanh 影响。
它提供相对直接的 identity-like path,gradient 不必在每一步只穿过完整 nonlinear rewrite。
不会;它令当前 h_t 不暴露该 memory,但 c_t 可继续传到下一步。
每一步 gates 依赖 h_{t-1},cell update 依赖 c_{t-1}。
Then I implemented: four packed gates、additive cell update、hidden exposure.
Now I understand: LSTM 给 recurrence 加了一条可门控的 memory highway;它修了“怎样沿链记住”,没修“为什么必须沿链走”。
Transformer 不再要求一个 state 依次吞掉整段历史。它保留每个 token 的 representation,让当前位置用内容相关 query 直接读取其他 positions。下一课先回答这些 positions 如何从字符串变成 vectors。
Based on your implementation