1997 - 長短期記憶 LSTM(解決梯度消失的記憶細胞)#
案件摘要#
1997 年,Sepp Hochreiter(1967– ) 與 Jürgen Schmidhuber(1963– ) 在 Neural Computation 發表 Long Short-Term Memory—— LSTM(長短期記憶)正式誕生:
案件背景:1991 年,還是學士生的 Hochreiter 在畢業論文中 發現了遞迴神經網路(RNN)的致命傷——梯度消失:
RNN 按理論應該能記住一切(它的隱藏狀態是圖靈機式的記憶), 但實際上只能記住幾步——理論與實踐的鴻溝長達六年。 LSTM 用加法的記憶細胞與 sigmoid 閘門修復了這條斷橋:
這是序列建模的基石——2010 年代,機器翻譯與語音辨識全是 LSTM 的天下。
前因 -- 為什麼會有這個案子#
- RNN 的理論承諾(1980s): 遞迴神經網路(RNN)把上一刻的隱藏狀態餵回下一刻:
這在理論上等價於一台圖靈機(見 ../資訊科學/1936-圖靈機.md)—— 隱藏狀態 \(h\) 就是那條無限長的紙帶:
按理論,RNN 應該能學會任何序列任務。 - 1991 Hochreiter 的發現——梯度消失: 還是學士生的 Hochreiter 在 1991 年的畢業論文中 數學上證明:反向傳播穿過時間(BPTT, back-propagation through time)時,
矩陣連乘 t 次:若 \(|W|<1\) ,梯度指數衰減到零; 若 \(|W|>1\) ,指數爆炸——
理論承諾與實踐現實的鴻溝就此揭穿(見 1986-反向傳播復興.md)。 - 問題的本質:加法 vs 乘法: 梯度消失的根源是梯度沿著乘法路徑流動(矩陣連乘):
若記憶沿著加法路徑流動(恆等映射),梯度原樣通過:
Hochreiter 與 Schmidhuber 的目標:設計一個網路, 讓記憶走加法的高速公路,而不是乘法的鄉間小路。 - 先驅的嘗試與失敗: - Elman(1990):簡單遞迴網路——還是被梯度消失困住; - Mozer(1992)、Schmidhuber(1992):各種時間延遲的嘗試—— 效果有限; - Bengio(1994):也獨立分析了 RNN 的長期依賴困境—— 三組人馬同時逼近答案,而 Hochreiter–Schmidhuber 先到終點。
線索與推理 -- 數學式、程式、理論#
第一條線索:記憶細胞——加法的時間旅行#
LSTM 的細胞狀態(cell state) \(c_t\) 是一條貫穿時間的資訊高速公路:
- \(\odot\) :逐元素乘法; \(c_{t-1}\) :舊記憶; \(\tilde{c}_t\) :新訊息(候選記憶);
- 關鍵:舊記憶靠加法進入 \(c_t\) (不是乘進矩陣連乘!)——
- 為什麼叫「Long Short-Term Memory」? 這條細胞狀態是短期的(每步更新),但可以通過加法保留任意久—— 長期記憶由短期記憶的高速公路組成。
第二條線索:三個閘門——σ 的開關藝術#
sigmoid 門控: \(\sigma(z) = \frac{1}{1+e^{-z}} \in (0, 1)\) —— 可微的開關(0 = 關閉,1 = 全開):
候選記憶(tanh 壓縮到 \((-1,1)\) ):
隱藏狀態(記憶的讀出):
三個閘的分工:
與圖靈機的對照:讀寫頭讀、寫、擦除—— LSTM 的三個閘正是可微版的讀寫頭:
第三條線索:長期依賴的數學——為什麼 LSTM 贏了#
BPTT 的梯度消失(RNN):
LSTM 的梯度(沿細胞狀態):
- 若網路學到 \(f_k \approx 1\) (不遺忘),則
- 對照:RNN 的 \(\prod\) 中每一項都是變化的矩陣(衰減是常態); LSTM 的 \(\prod\) 中每一項是網路自己選的閘門(保持 1 是選項)。
- Hochreiter–Schmidhuber 的實驗:LSTM 能學會 數百步以上的延遲回憶—— RNN 在同樣的任務上完全失敗。1997 年的論文以此當庭宣判。
Python:LSTM cell 的前向傳播#
import math
def sig(x): return 1.0/(1.0+math.exp(-x))
def tanh(x): return math.tanh(x)
# 3 維輸入、2 維隱藏狀態的小型 LSTM cell(手動矩陣運算)
x = [0.5, -1.0, 2.0]
h_prev = [0.1, -0.2]
c_prev = [0.0, 0.5]
Wf = [[0.6, -0.4, 0.2], [-0.3, 0.5, 0.1]]; bf = [0.5, 0.5] # 遺忘閘
Wi = [[0.4, 0.3, -0.5], [0.2, -0.6, 0.4]]; bi = [0.0, 0.0] # 輸入閘
Wc = [[0.7, 0.1, 0.3], [-0.2, 0.4, 0.6]]; bc = [0.0, 0.0] # 候選記憶
Wo = [[0.5, -0.2, 0.4], [0.3, 0.6, -0.1]]; bo = [0.2, 0.0] # 輸出閘
def affine(W, b, v):
return [sum(wj*xj for wj, xj in zip(row, v))+bj for row, bj in zip(W, b)]
f = [sig(v) for v in affine(Wf, bf, x+h_prev)] # 遺忘閘 σ
i = [sig(v) for v in affine(Wi, bi, x+h_prev)] # 輸入閘 σ
c_hat = [tanh(v) for v in affine(Wc, bc, x+h_prev)] # 候選記憶 tanh
c = [fi*cp + ii*ch for fi, ii, cp, ch in zip(f, i, c_prev, c_hat)] # 細胞狀態
o = [sig(v) for v in affine(Wo, bo, x+h_prev)] # 輸出閘 σ
h = [ok*tanh(ck) for ok, ck in zip(o, c)] # 隱藏狀態
print("LSTM cell 前向傳播(輸入 3 維、隱藏 2 維)")
print(f"輸入 x = {x}")
print(f"上一刻 h = {h_prev}")
print(f"上一刻 c = {c_prev}")
print(f"\n遺忘閘 f = σ(Wf·[x,h]+bf) = [{f[0]:.4f}, {f[1]:.4f}]")
print(f"輸入閘 i = σ(Wi·[x,h]+bi) = [{i[0]:.4f}, {i[1]:.4f}]")
print(f"候選記憶 c̃ = tanh(Wc·[x,h]+bc) = [{c_hat[0]:.4f}, {c_hat[1]:.4f}]")
print(f"細胞狀態 c = f⊙c_prev + i⊙c̃ = [{c[0]:.4f}, {c[1]:.4f}]")
print(f"輸出閘 o = σ(Wo·[x,h]+bo) = [{o[0]:.4f}, {o[1]:.4f}]")
print(f"隱藏狀態 h = o⊙tanh(c) = [{h[0]:.4f}, {h[1]:.4f}]")
print("\n時間旅行的對照實驗:f=1(記住)vs f=0(遺忘)")
for fv in (1.0, 0.0):
c_t = [fv*c_prev[0] + i[0]*c_hat[0], fv*c_prev[1] + i[1]*c_hat[1]]
print(f" f={fv} → c = [{c_t[0]:.4f}, {c_t[1]:.4f}]")
print(" f≈1:舊記憶原封不動地通過(梯度高速公路);f≈0:舊記憶被洗掉。")
LSTM cell 前向傳播(輸入 3 維、隱藏 2 維)
輸入 x = [0.5, -1.0, 2.0]
上一刻 h = [0.1, -0.2]
上一刻 c = [0.0, 0.5]
遺忘閘 f = σ(Wf·[x,h]+bf) = [0.8320, 0.5125]
輸入閘 i = σ(Wi·[x,h]+bi) = [0.2497, 0.8176]
候選記憶 c̃ = tanh(Wc·[x,h]+bc) = [0.6911, 0.6044]
細胞狀態 c = f⊙c_prev + i⊙c̃ = [0.1726, 0.7504]
輸出閘 o = σ(Wo·[x,h]+bo) = [0.8100, 0.3430]
隱藏狀態 h = o⊙tanh(c) = [0.1384, 0.2179]
時間旅行的對照實驗:f=1(記住)vs f=0(遺忘)
f=1.0 → c = [0.1726, 0.9941]
f=0.0 → c = [0.1726, 0.4941]
f≈1:舊記憶原封不動地通過(梯度高速公路);f≈0:舊記憶被洗掉。
結案 -- 後果與影響#
- 序列建模的基石(1997 → 2010s):
1997 年發表時默默無聞(Hochreiter 曾被期刊拒稿多年); 十年後(2007 起)LSTM 橫掃一切序列任務——
- 2010 年代的主力應用:
- 語音辨識:Google 的語音辨識在 2015 年全面改用 LSTM;
- 機器翻譯:Google 翻譯 2016 年改用 LSTM seq2seq—— 翻譯品質一夜之間大幅躍進(減少 60% 錯誤);
- 語言模型、圖像描述、手寫生成——全都以 LSTM 為核心。
- 2015 Attention 的伏筆: LSTM 的瓶頸:長句要壓縮成一個固定向量——記不住全部。 Bahdanau 等(2015)的 attention 機制讓解碼器回頭看編碼器的每一步:
這個伏筆在 2017 年爆發——Transformer 棄用 LSTM、只用 attention, 成為大語言模型的基礎(見 2017-瓦茲瓦尼Transformer.md)。
- 理論與工程的雙贏:
- Hochreiter 的兩次關鍵貢獻:1991 年發現問題(梯度消失), 1997 年解決問題(LSTM)——偵探兼兇手剋星;
- Schmidhuber 的實驗室(IDSIA)在 2010 年代以 LSTM 贏下 多項國際競賽(含 2011 年 GPU 訓練的網路視覺競賽)。
- GPU 的意外幫手(2011): Cireşan 與 Hochreiter 證明 LSTM 可以用 GPU 大幅加速訓練—— 這為 2012 年 AlexNet 的 GPU 訓練鋪路 (見
2012-亞歷克斯AlexNet.md)。 - 歷史定位:LSTM 是機器的海馬迴(大腦的記憶中樞)—— 從 1997 到今天,每一個處理序列的系統(語音、翻譯、時間序列預測) 都受益於同一個思想:加法的記憶高速公路 + 可微的閘門。
理論承諾的鴻溝(圖靈機式的 RNN)被一座橋修復——而這座橋的名字叫 LSTM。
關鍵人物與文獻#
- S. Hochreiter:Untersuchungen zu dynamischen neuronalen Netzen(學士論文,1991)——梯度消失的發現;Long Short-Term Memory(1997,與 Schmidhuber)。
- J. Schmidhuber:LSTM 共同作者(1997);IDSIA 實驗室的 LSTM 競賽(2010s)。
- Y. Bengio 等:Learning Long-Term Dependencies with Gradient Descent is Difficult(1994)——獨立的梯度消失分析。
- D. Bahdanau 等:attention 機制(2015)——Transformer 的伏筆。
- F. Gers:peephole 連接與 LSTM 的改進(2000)。
- 相關案件:
1986-反向傳播復興.md、1989-楊立昆卷積網路.md、2012-亞歷克斯AlexNet.md、2017-瓦茲瓦尼Transformer.md、../資訊科學/1936-圖靈機.md。