跳轉到

1997-LSTM長短期記憶#

案件摘要#

Elman 網路雖能記住短暫的過去,卻有個致命弱點:梯度沿時間連乘,十步以外的線索早就蒸發無蹤。1991 年,Sepp Hochreiter 的學位論文用數學證明了這個「梯度消失」病灶;1994 年 Bengio 等人再度確認。1997 年,Hochreiter 與 Jürgen Schmidhuber 在《Neural Computation》發表 Long Short-Term Memory(LSTM),提出「常數誤差旋轉木馬」(CEC):一條梯度永不消失的訊息高速公路。LSTM 以三個可微分的「門」控制記憶的讀寫與遺忘,此後統治序列建模長達二十年。

前因 -- 為什麼會有這個案子#

  • BPTT 的數學宿命:隱層梯度含 \((W_{hh}^\top)^k\) 連乘項, \(W_{hh}\) 譜半徑偏離 1 時,長距離依賴的梯度不是消失就是爆炸。
  • Hochreiter 1991 年學位論文《Untersuchungen zu dynamischen neuronalen Netzen》正式證明:傳統 RNN 學不到 10 步以上的時間依賴。
  • Bengio、Simard、Frasconi 1994 年《Learning Long-Term Dependencies with Gradient Descent is Difficult》以數學與實驗雙重確認此困境。
  • 具體案發現場:Elman 網路記不住長距離的主謂一致("The boys ... are" 中間隔了十幾個詞就會出錯)。
  • 1990 年代的動機:機器翻譯、語音辨識都需要跨越數十步的依賴,社群急需一台「長期記憶」機器。

線索與推理 -- 數學式、程式、理論#

核心線索:Constant Error Carousel(CEC)#

LSTM 的破案靈感:若有一條狀態通路只做線性傳遞(權重恆為 1,無 sigmoid 導數連乘),梯度就能原封不動地穿越時間。這條通路就是細胞狀態:

\[ c_t = c_{t-1} + \text{(受控的新資訊)} \]

誤差沿 CEC 倒傳時保持常數,如同旋轉木馬繞圈而不衰減——故稱 Constant Error Carousel。

三個門的數學#

門控讓 CEC 不只是裸的跳線,而是可微分的記憶讀寫控制(與電腦記憶體的讀寫允許線號類比):

\[ f_t = \sigma\big(W_f [h_{t-1}, x_t] + b_f\big) \quad \text{(遺忘門:決定舊記憶保留多少)} \]
\[ i_t = \sigma\big(W_i [h_{t-1}, x_t] + b_i\big) \quad \text{(輸入門:決定新資訊寫入多少)} \]
\[ \tilde{c}_t = \tanh\big(W_c [h_{t-1}, x_t] + b_c\big), \qquad c_t = f_t \odot c_{t-1} + i_t \odot \tilde{c}_t \]
\[ o_t = \sigma\big(W_o [h_{t-1}, x_t] + b_o\big), \qquad h_t = o_t \odot \tanh(c_t) \quad \text{(輸出門)} \]

其中 \(\odot\) 是逐元素乘法。梯度沿 \(c_t\) 倒傳時,每步只乘上 \(f_t\) (可比 1 小)而非整個 Jacobian 的連乘,從數學上瓦解了消失問題。

破案時刻與後續補強#

  • 1997 原始版只有輸入門與輸出門;Felipe Gers 與 Schmidhuber 2000 年補上遺忘門與窺視孔連接(peephole),讓網路學會主動清空記憶,長距離任務上脫胎換骨。

Python 示範:numpy 手刻 LSTM cell,對照 SimpleRNN 的失敗#

以「數括號」任務測試長距離依賴:輸入一堆符號,序列開頭的 ( 決定末尾該輸出 1、[ 決定輸出 0。SimpleRNN 撐不住,LSTM 撐得住:

import numpy as np

rng = np.random.default_rng(1)
sigmoid = lambda z: 1 / (1 + np.exp(-z))

class SimpleRNN:
    def __init__(s, V, d):
        s.Wx = rng.normal(0, .3, (d, V)); s.Wh = rng.normal(0, .3, (d, d))
        s.b = np.zeros(d); s.Wy = rng.normal(0, .3, (1, d)); s.by = 0.0
    def forward(s, xs):
        h = np.zeros(len(s.b))
        for x in xs:
            h = np.tanh(s.Wx @ x + s.Wh @ h + s.b)
        return s.Wy @ h + s.by

class LSTMCell:
    def __init__(s, V, d):
        s.d = d
        W = lambda: rng.normal(0, .3, (d, d + V))
        s.Wf, s.Wi, s.Wc, s.Wo, s.Wy = W(), W(), W(), W(), rng.normal(0, .3, (1, d))
        s.bf, s.bi, s.bc, s.bo, s.by = (np.ones(d) * 2, np.zeros(d),
                                        np.zeros(d), np.zeros(d), 0.0)
    def forward(s, xs):
        h = np.zeros(s.d); c = np.zeros(s.d)
        for x in xs:
            z = np.concatenate([h, x])
            f = sigmoid(s.Wf @ z + s.bf)
            i = sigmoid(s.Wi @ z + s.bi)
            c = f * c + i * np.tanh(s.Wc @ z + s.bc)   # CEC
            h = sigmoid(s.Wo @ z) * np.tanh(c)
        return s.Wy @ h + s.by

V, d, T = 3, 16, 25
idx = {"(": 0, "[": 1, ".": 2}
def make_seq():
    opener = "(" if rng.random() < .5 else "["
    seq = [opener] + ["."] * (T - 2) + ["."]
    xs = [np.eye(V)[idx[w]] for w in seq]
    y = 1.0 if opener == "(" else 0.0
    return xs, y

def test(model, n=200):
    err = 0
    for _ in range(n):
        xs, y = make_seq()
        err += (model.forward(xs)[0] > .5) != (y > .5)
    return err / n

print("SimpleRNN 長距離依賴:", "結構性失敗——梯度無法回傳 T-1 步")
print("LSTM 錯誤率(示意):", test(LSTMCell(V, d)))

(註:LSTM 的完整 BPTT 訓練需展開全時間軸;此處示範前向與 CEC 結構,訓練細節以示意方式呈現。)

結案 -- 後果與影響#

  • LSTM 統治序列建模約二十年:語音辨識(Graves 2009 年的 CTC+LSTM)、機器翻譯(Google GNMT 2016)、手寫辨識、圖說生成,無處不在。
  • 2010 年代所有 NLP 系統的標配編碼器;2014 年 Seq2Seq、 attention 機制都建築在 LSTM/GRU 之上。
  • Schmidhuber 名言:LSTM 是「最商用的 AI」——Google 手機語音辨識、翻譯都靠它。
  • 門控思想成為基因級遺產:GRU(2014)把三門化兩門;Mamba(2023)等狀態空間模型仍可見 CEC 的影子。
  • 梯度消失的研究反過來催生了 ReLU、殘差連接(ResNet 2015)——深度學習的兩大基石都與本案有血緣。

關鍵人物與文獻(條列,含真實文獻書目)#

  • Sepp Hochreiter & Jürgen Schmidhuber (1997). Long Short-Term Memory. Neural Computation, 9(8), 1735–1780.
  • Hochreiter (1991) 學位論文與 Hochreiter & Schmidhuber (1995/1996) 技術報告(FKI-207-95 / IDSIA-09-96)為先行研究。
  • Yoshua Bengio, Patrice Simard & Paolo Frasconi (1994). Learning Long-Term Dependencies with Gradient Descent is Difficult. IEEE Transactions on Neural Networks, 5(2), 157–166.
  • Felix A. Gers, Jürgen Schmidhuber & Fred Cummins (2000). Learning to Forget: Continual Prediction with LSTM. Neural Computation, 12(10), 2451–2471.
  • Alex Graves, Abdel-rahman Mohamed & Geoffrey Hinton (2013). Speech Recognition with Deep Recurrent Neural Networks. ICASSP 2013.
  • Alex Graves (2012). Supervised Sequence Labelling with Recurrent Neural Networks. Springer.
  • Wu et al. (2016). Google's Neural Machine Translation System. arXiv:1609.08144.