【NLP】圖解 Attention完整版
本文約4000字,建議閱讀11分鐘
審稿人:Jepson,Datawhale成員,畢業(yè)于中國科學院,目前在騰訊從事推薦算法工作。
序列到序列(seq2seq)模型是一種深度學習模型,在很多任務上都取得了成功,如:機器翻譯、文本摘要、圖像描述生成。谷歌翻譯在 2016 年年末開始使用這種模型。有2篇開創(chuàng)性的論文:
Sutskever等2014年發(fā)布的:https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf,
Cho等2014年發(fā)布的:http://emnlp2014.org/papers/pdf/EMNLP2014179.pdf
都對這些模型進行了解釋。
然而,我發(fā)現,想要充分理解模型并實現它,需要拆解一系列概念,而這些概念是層層遞進的。我認為,如果能夠把這些概念進行可視化,會更加容易理解。這就是這篇文章的目標。你需要先了解一些深度學習的知識,才能讀完這篇文章。我希望這篇文章,可以對你閱讀上面提到的 2 篇論文有幫助。
一個序列到序列(seq2seq)模型,接收的輸入是一個輸入的(單詞、字母、圖像特征)序列,輸出是另外一個序列。一個訓練好的模型如下圖所示:

在神經機器翻譯中,一個序列是指一連串的單詞。類似地,輸出也是一連串單詞。

進一步理解細節(jié)
模型是由編碼器(Encoder)和解碼器(Decoder)組成的。其中,編碼器會處理輸入序列中的每個元素,把這些信息轉換為一個向量(稱為上下文(context))。當我們處理完整個輸入序列后,編碼器把上下文(context)發(fā)送給解碼器,解碼器開始逐項生成輸出序列中的元素。

這種機制,同樣適用于機器翻譯。
在機器翻譯任務中,上下文(context)是一個向量(基本上是一個數字數組)。編碼器和解碼器一般都是循環(huán)神經網絡,一定要看看 Luis Serrano寫的一篇關于循環(huán)神經網絡(https://www.youtube.com/watch?v=UNmqTiOnRfg)的精彩介紹
你可以在設置模型的時候設置上下文向量的長度。這個長度是基于編碼器 RNN 的隱藏層神經元的數量。上圖展示了長度為 4 的向量,但在實際應用中,上下文向量的長度可能是 256,512 或者 1024。
根據設計,RNN 在每個時間步接受 2 個輸入:
輸入序列中的一個元素(在解碼器的例子中,輸入是指句子中的一個單詞) 一個 ?hidden state(隱藏層狀態(tài))
然而每個單詞都需要表示為一個向量。為了把一個詞轉換為一個向量,我們使用一類稱為 "word embedding" 的方法。這類方法把單詞轉換到一個向量空間,這種表示能夠捕捉大量的單詞的語義信息(例如,king - man + woman = queen (http://p.migdal.pl/2017/01/06/king-man-woman-queen-why.html))。
現在,我們已經介紹完了向量/張量的基礎知識,讓我們回顧一下 RNN 的機制,并可視化這些 RNN 模型:

RNN 在第 2 個時間步,采用第 1 個時間步的 hidden state(隱藏層狀態(tài)) 和第 2 個時間步的輸入向量,來得到輸出。在下文,我們會使用類似這種動畫,來描述神經機器翻譯模型里的所有向量。
在下面的可視化圖形中,編碼器和解碼器在每個時間步處理輸入,并得到輸出。由于編碼器和解碼器都是 RNN,RNN 會根據當前時間步的輸入,和前一個時間步的 hidden state(隱藏層狀態(tài)),更新當前時間步的 hidden state(隱藏層狀態(tài))。
讓我們看下編碼器的 hidden state(隱藏層狀態(tài))。注意,最后一個 hidden state(隱藏層狀態(tài))實際上是我們傳給解碼器的上下文(context)。
解碼器也持有 hidden state(隱藏層狀態(tài)),而且也需要把 hidden state(隱藏層狀態(tài))從一個時間步傳遞到下一個時間步。我們沒有在上圖中可視化解碼器的 hidden state,是因為這個過程和解碼器是類似的,我們現在關注的是 RNN 的主要處理過程。現在讓我們用另一種方式來可視化序列到序列(seq2seq)模型。下面的動畫會讓我們更加容易理解模型。這種方法稱為展開視圖。其中,我們不只是顯示一個解碼器,而是在時間上展開,每個時間步都顯示一個解碼器。通過這種方式,我們可以看到每個時間步的輸入和輸出。
Attention 講解
事實證明,上下文向量是這類模型的瓶頸。這使得模型在處理長文本時面臨非常大的挑戰(zhàn)。
在 Bahdanau等2014發(fā)布的(https://arxiv.org/abs/1409.0473) 和 Luong等2015年發(fā)布的(https://arxiv.org/abs/1508.04025) 兩篇論文中,提出了一種解決方法。這 2 篇論文提出并改進了一種叫做注意力(Attention)的技術,它極大地提高了機器翻譯的質量。注意力使得模型可以根據需要,關注到輸入序列的相關部分。
讓我們繼續(xù)從高層次來理解注意力模型。一個注意力模型不同于經典的序列到序列(seq2seq)模型,主要體現在 2 個方面:
首先,編碼器會把更多的數據傳遞給解碼器。編碼器把所有時間步的 hidden state(隱藏層狀態(tài))傳遞給解碼器,而不是只傳遞最后一個 hidden state(隱藏層狀態(tài))。
第二,注意力模型的解碼器在產生輸出之前,做了一個額外的處理。為了把注意力集中在與該時間步相關的輸入部分。解碼器做了如下的處理:
查看所有接收到的編碼器的 hidden state(隱藏層狀態(tài))。其中,編碼器中每個 hidden state(隱藏層狀態(tài))都對應到輸入句子中一個單詞。 給每個 hidden state(隱藏層狀態(tài))一個分數(我們先忽略這個分數的計算過程)。 將每個 hidden state(隱藏層狀態(tài))乘以經過 softmax 的對應的分數,從而,高分對應的 ?hidden state(隱藏層狀態(tài))會被放大,而低分對應的 ?hidden state(隱藏層狀態(tài))會被縮小。
這個加權平均的步驟是在解碼器的每個時間步做的。
現在,讓我們把所有內容都融合到下面的圖中,來看看注意力模型的整個過程:
注意力模型的解碼器 RNN 的輸入包括:一個embedding 向量,和一個初始化好的解碼器 hidden state(隱藏層狀態(tài))。 RNN 處理上述的 2 個輸入,產生一個輸出和一個新的 hidden state(隱藏層狀態(tài) h4 向量),其中輸出會被忽略。 注意力的步驟:我們使用編碼器的 hidden state(隱藏層狀態(tài))和 h4 向量來計算這個時間步的上下文向量(C4)。 我們把 h4 和 C4 拼接起來,得到一個向量。 我們把這個向量輸入一個前饋神經網絡(這個網絡是和整個模型一起訓練的)。 前饋神經網絡的輸出的輸出表示這個時間步輸出的單詞。 在下一個時間步重復這個步驟。
下圖,我們使用另一種方式來可視化注意力,看看在每個解碼的時間步中關注輸入句子的哪些部分:
如果你覺得你準備好了學習注意力機制的代碼實現,一定要看看基于 TensorFlow 的 神經機器翻譯 (seq2seq) 指南(https://github.com/tensorflow/nmt)
本文經原作者?@JayAlammmar(https://twitter.com/JayAlammar) 授權翻譯,期望你的反饋。
往期精彩回顧
獲取一折本站知識星球優(yōu)惠券,復制鏈接直接打開:
https://t.zsxq.com/y7uvZF6
本站qq群704220115。
加入微信群請掃碼:




