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