在前一天,我們介紹了 Seq2Seq 架構 (Encoder-Decoder),它將輸入序列壓縮成一個固定維度的上下文向量 (Context Vector),再交由解碼器 (Decoder) 逐步生成輸出。這種方法為機器翻譯、摘要生成等任務帶來了突破,但它也有一個致命的缺陷——瓶頸效應 (Bottleneck Problem)。
不論輸入序列多長,最終都必須壓縮到單一向量 $c$,再交給解碼器使用。對短序列來說這還能接受,但一旦輸入序列過長,資訊勢必會大量遺失。這就像是要把一本書濃縮成一句話,再交給翻譯員去翻譯成另一種語言,結果可想而知。
為了解決這個問題,Bahdanau 等人在 2015 年提出了 Attention 機制,讓模型在生成輸出時,不再依賴單一上下文,而是能夠「動態選擇性地關注輸入序列的不同部分」。這一設計徹底改變了序列建模的方式,並為後來的 Transformer 奠定了基礎。
Attention 的直觀想法可以用一個比喻來理解:
換句話說:Decoder 在生成每個輸出詞時,不僅依賴最後的上下文向量,而是能針對 Encoder 的所有隱藏狀態進行加權。
假設輸入序列為 $(x_1, x_2, \dots, x_T)$,經 Encoder 後得到隱藏狀態序列 $h_1, h_2, \dots, h_T$。在生成輸出 $y_t$ 時:
計算注意力權重 (Attention Weights)
$$
e_{t,i} = \text{score}(s_{t-1}, h_i)
$$
$$
\alpha_{t,i} = \frac{\exp(e_{t,i})}{\sum_j \exp(e_{t,j})}
$$
計算上下文向量 (Context Vector)
生成輸出
這裡的 $\alpha_{t,i}$ 就代表「在生成第 $t$ 個輸出時,模型對輸入第 $i$ 個詞的注意程度」。
Attention 的關鍵在於 score 函數 的設計。常見的幾種方式:
Dot Product Attention
$$
e_{t,i} = s_{t-1}^\top h_i
$$
最簡單,計算快。
General Attention
$$
e_{t,i} = s_{t-1}^\top W h_i
$$
引入可學習矩陣 $W$,更靈活。
Concat Attention (Bahdanau Attention)
$$
e_{t,i} = v^\top \tanh(W[s_{t-1}; h_i])
$$
較複雜,但效果通常更好。
Attention 讓 Decoder 在每一步輸出時,都能「看一眼 Encoder 的所有隱藏狀態」,並根據需求分配權重。
舉例:
當 Decoder 輸出「今天」時,Attention 權重主要集中在輸入的 “today”;當輸出「高興」時,則集中在 “happy”。
這種對齊 (Alignment) 能力,使得 Seq2Seq 模型在翻譯和摘要任務上效果大幅提升。
這些缺點為後來 Self-Attention 與 Transformer 的誕生鋪路。
Attention 機制徹底改變了序列建模的方式。它不再依賴單一向量,而是允許模型動態關注輸入序列的不同部分,從而大幅提升 Seq2Seq 的表現。
如果說 RNN/LSTM/GRU 是序列建模的「第一代」,Seq2Seq 是「第二代」,那麼 Attention 就是「第三代」,為 Transformer 與大型語言模型的崛起奠定了基礎。