1. 什么是Attention機制
在“編碼器—解碼器(seq2seq)”⼀節⾥,解碼器在各個時間步依賴相同的背景變量來獲取輸⼊序列信息。當編碼器為循環神經⽹絡時,背景變量來⾃它最終時間步的隱藏狀態。
現在,讓我們再次思考那⼀節提到的翻譯例⼦:輸⼊為英語序列“They”“are”“watching”“.”,輸出為法語序列“Ils”“regardent”“.”。不難想到,解碼器在⽣成輸出序列中的每⼀個詞時可能只需利⽤輸⼊序列某⼀部分的信息。例如,在輸出序列的時間步1,解碼器可以主要依賴“They”“are”的信息來⽣成“Ils”,在時間步2則主要使⽤來⾃“watching”的編碼信息⽣成“regardent”,最后在時間步3則直接映射句號“.”。這看上去就像是在解碼器的每⼀時間步對輸⼊序列中不同時間步的表征或編碼信息分配不同的注意⼒⼀樣。這也是注意⼒機制的由來。
仍然以循環神經⽹絡為例,注意⼒機制通過對編碼器所有時間步的隱藏狀態做加權平均來得到背景變量。解碼器在每⼀時間步調整這些權重,即注意⼒權重,從而能夠在不同時間步分別關注輸⼊序列中的不同部分並編碼進相應時間步的背景變量。
在注意⼒機制中,解碼器的每⼀時間步將使⽤可變的背景變量。記 ct′ 是解碼器在時間步 t′ 的背景變量,那么解碼器在該時間步的隱藏狀態可以改寫為:
這⾥的關鍵是如何計算背景變量 ct′ 和如何利⽤它來更新隱藏狀態 st′。下⾯將分別描述這兩個關鍵點。
2. 計算背景變量
我們先描述第⼀個關鍵點,即計算背景變量。下圖描繪了注意⼒機制如何為解碼器在時間步 2 計算背景變量。
- 函數 a 根據解碼器在時間步 1 的隱藏狀態和編碼器在各個時間步的隱藏狀態計算softmax運算的輸⼊。
- softmax運算輸出概率分布並對編碼器各個時間步的隱藏狀態做加權平均,從而得到背景變量。
令編碼器在時間步t的隱藏狀態為 ht,且總時間步數為 T。那么解碼器在時間步 t′ 的背景變量為所有編碼器隱藏狀態的加權平均:
矢量化計算背景變量
我們還可以對注意⼒機制采⽤更⾼效的⽮量化計算。我們先定義,在上⾯的例⼦中,查詢項為解碼器的隱藏狀態,鍵項和值項均為編碼器的隱藏狀態。
⼴義上,注意⼒機制的輸⼊包括查詢項以及⼀⼀對應的鍵項和值項,其中值項是需要加權平均的⼀組項。在加權平均中,值項的權重來⾃查詢項以及與該值項對應的鍵項的計算。
讓我們考慮⼀個常⻅的簡單情形,即編碼器和解碼器的隱藏單元個數均為 h,且函數 \(a(s,h)=s^Th\)。假設我們希望根據解碼器單個隱藏狀態 st′−1 和編碼器所有隱藏狀態 ht, t = 1, . . . , T來計算背景向量 ct′ 。我們可以將查詢項矩陣 Q 設為 \(s_{t^{′}-1}^T\),並令鍵項矩陣 K 和值項矩陣 V 相同且第 t ⾏均為 \(h_t^T\)。此時,我們只需要通過⽮量化計算:
即可算出轉置后的背景向量 \(c_{t^{′}}^T\)。當查詢項矩陣 Q 的⾏數為 n 時,上式將得到 n ⾏的輸出矩陣。輸出矩陣與查詢項矩陣在相同⾏上⼀⼀對應。
3. 更新隱藏狀態
現在我們描述第⼆個關鍵點,即更新隱藏狀態。以⻔控循環單元為例,在解碼器中我們可以對⻔控循環單元(GRU)中⻔控循環單元的設計稍作修改,從而變換上⼀時間步 t′−1 的輸出 yt′−1、隱藏狀態 st′−1 和當前時間步t′ 的含注意⼒機制的背景變量 ct′。解碼器在時間步: math:t’ 的隱藏狀態為:
其中的重置⻔、更新⻔和候選隱藏狀態分別為:
其中含下標的 W 和 b 分別為⻔控循環單元的權重參數和偏差參數。
4. 發展
本質上,注意⼒機制能夠為表征中較有價值的部分分配較多的計算資源。這個有趣的想法⾃提出后得到了快速發展,特別是啟發了依靠注意⼒機制來編碼輸⼊序列並解碼出輸出序列的變換器(Transformer)模型的設計。變換器拋棄了卷積神經⽹絡和循環神經⽹絡的架構。它在計算效率上⽐基於循環神經⽹絡的編碼器—解碼器模型通常更具明顯優勢。含注意⼒機制的變換器的編碼結構在后來的BERT預訓練模型中得以應⽤並令后者⼤放異彩:微調后的模型在多達11項⾃然語⾔處理任務中取得了當時最先進的結果。不久后,同樣是基於變換器設計的GPT-2模型於新收集的語料數據集預訓練后,在7個未參與訓練的語⾔模型數據集上均取得了當時最先進的結果。除了⾃然語⾔處理領域,注意⼒機制還被⼴泛⽤於圖像分類、⾃動圖像描述、唇語解讀以及語⾳識別。
5. 代碼實現
注意力模型實現中英文機器翻譯
-
數據預處理
首先先下載本目錄的數據和代碼,並執行 datautil.py,生成中、英文字典。
-
執行 train.ipynb,訓練時間會比較長。
-
測試模型,運行test.py文件。
6. 參考文獻
作者:@mantchs