起這個標題的原因是,春招時期寫了一篇關於word2vec的文章,按照文章的思路跟面試官講word2vec或者裡面的細節,基本上沒有撲街的,有些面試官也表示講的很好。

益達:Embedding之word2vec?

zhuanlan.zhihu.com
圖標

但是有面試官這麼問我:「可以看出這基礎很好,但Attention、Bert等前沿模型近期很熱門啊,有機會你再瞭解一下吧」。我當場鼠軀一震,覺得自己需要繼續瞭解一下NLP的前沿模型了!

雖然自己開的專欄叫益達的Embedding空間,本著實用和全面的原則,近期我會寫一點自己對Attention的理解。這篇文章只講傳統Attention,self-Attention留到下一篇吧。

Attention起源於圖像領域的注意力機制(此處略去好多字...),發展史我這裡就不多說了。直接開始切入正題吧!

1、seq2seq的翻譯模型

在介紹Attention之前,有必要說一下seq2seq的翻譯模型,這個模型很有利於理解Attention。可以將seq2seq看成一種通用的框架,它的輸入是一個序列,輸出是一個序列,好比翻譯任務,輸入「今天是晴天」,輸出「Today is sunny」。我們使用RNN來seq2seq,RNN的結構如下:

RNN的時間步展開形式

對於每一個時間步(序列中的一個元素)將涉及2個輸入, X_th_{t-1} (類比LSTM,我們可以將 h_{t-1} 看做網路的記憶,只不過RNN沒有「長短期記憶」,只有「長時記憶」),同時具有2個輸出(兩個輸出都是 h_t )。於是一個最樸素的seq2seq可以畫作下圖:

樸素的seq2seq模型

對於上圖,我們可作如下解釋。Encoder部分具有初始記憶H0,和句子的第一個單詞一同輸入第一個神經元,然後得到輸出 h_1 ,直至句子的最後一個單詞輸入完畢。輸入Decoder的只有 中間記憶h_3 ,它承載了前面所有輸入的記憶特徵,並將被用於翻譯。

開始翻譯時,先輸入句子的開始符號<BOS>,此時Decoder裏第一個RNN單元接受輸入<BOS>和長時記憶 h_3 ,得到輸出Y1,我們希望這個Y1越接近Today這個單詞越好(這裡可以近似這麼理解)。第二個RNN單元接受長時記憶 h_4 和Today,我們希望它能夠輸出is這個單詞,後面同理。這裡使用了Teacher Forcing技術,即使用真實的翻譯結果來強制模型學到正確的信息,防止錯誤積累,參見鏈接。

在這種設計下,Decoder模型將具備2個部分(訓練、預測),因為預測的時候沒有正確的標籤告訴RNN單元,只能使用上一輪的翻譯結果作為下一個位置的輸入。

  • Encoder端 encoder_layer
  • Decoder端
    • Decoder訓練 decoder_layer_train
    • Decoder預測/推斷 decoder_layer_inference

2、多次利用Encoder記憶

這裡我們發現,長時記憶 C=h_3 承載了大量信息,但是在翻譯過程中僅被直接利用在Decoder裏第一個RNN Cell上。很自然的一個想法是讓Decoder中所有單元都得到長時記憶的「福澤」,如下圖。

將長時記憶C用於Decoder中所有RNN單元

3、Attention的思想

將這個思想進一步擴展:我們既然已經能在翻譯過程中每一個單元都使用「長時記憶」,那麼我們為什麼不把所有的「記憶」都拿過來(而不是丟棄掉中間記憶),供我們挑選呢?OK我認為這個可以看做Attention的另一種出發點,如何利用這些信息呢?

Attention充分利用多「記憶」輔助翻譯

如上圖,我們可以充分使用每一個序列的「記憶」,並對不同的「記憶」使用不同的權重。比如翻譯「Today」的時候,我們希望「今天」這個詞在最終翻譯的「貢獻」更大(圖中以粗線表示更高的權重)。令 a_{t,1} 表示Encoder中第1個輸出對Decoder翻譯第t個單詞時所產生的貢獻,圖中 a_{3,3} 表示在翻譯第3個單詞「Sunny」時,「晴天」對翻譯的貢獻程度。

OK先不管 a_{t,1} 是怎麼計算的,考慮一下我們有這個權重了,要怎麼計算Decoder的輸入呢?在那之前我們先將這些權重歸一化吧,使用softmax將權重歸一化。這個結果就叫做AttentionScore,注意力評分。

Attention-score = softmax(a_{t,1}) = frac {e^{a_{t,1}}}{sum_j e^{a_{t,j}}}

然後再將歸一化過後的結果與每個隱層狀態相乘。s_{t}=sum_{k}^{T_x} {frac {e^{a_{t,k}}}{  sum_{j}e^{a_{t,j}} } * h_k}

其中 T_x 表示輸入序列的長度,相應地有 T_x 個Cell輸出。根據上式,就能獲得一個和原始「長期記憶」C大小相同的向量 s_t (圖中粉色虛線雙箭頭表示Attention和C結合得到 s_t )。將 s_t 與Teacher Forcing相結合(就是將Y標籤後移一個時間步,用於「監督」Decoder的訓練),即完成Decoder的訓練部分。推斷部分,沒有現成的標籤,就使用 t-1 時刻已經預測得到的單詞 v_{t-1} 作為下一個時間步的輸入,並計算 t 時刻的Attention結果 s_t ,輸入 t 時刻的Cell用於翻譯。

現在我們可以討論一下 a_{t,1}=sim(c_{t-1}, h_1) 要怎麼計算了,常見的計算方式有3種,點乘、映射、加性:

sim(c_{t-1}, h_1)= left{egin{matrix} v*tanh(Wc_{t-1}+Uh_1) & add \  c_{t-1}*h_1 & dot \  c_{t-1}*W*h_1 & projection  end{matrix}
ight.   \

注意有時候加性計算方式也被寫成兩個向量concat的形式: v*tanh(W*[c_{t-1} ; h_1]) ,形式不同但是沒有本質區別。

注意力評分是個 T_y*T_x 大小的矩陣,如果將矩陣繪製出來,就是常說的Attention評分矩陣,可以看到模型學習到的Attention信息。

Attention矩陣可視化示例

4、後記和參考文獻

發現自己之前使用的分類模型用了Attention實現多分類(當時直接從github拉取的Keras代碼),分別實現了在LSTM之前和之後施加Attention。當時還有點納悶,現在一想,其實Attention就是一種對前一層網路節點評分後輸出經softmax加權表示的一個結果。那份代碼的網路結構應該如下圖(畫的有可能有點問題,歡迎大佬指正):

在LSTM之前施加Attention

至此程度應該足夠應付面試裏讓簡單講講Attention的需求了,如果有遺漏歡迎評論區討論。下一篇準備講講self-attention和Transformer。

下面是本文的參考文獻。

Understanding LSTM Networks?

colah.github.io
圖標
What is Teacher Forcing for Recurrent Neural Networks??

machinelearningmastery.com
圖標
何之源:完全圖解RNN、RNN變體、Seq2Seq、Attention機制?

zhuanlan.zhihu.com
圖標
Attention and Memory in Deep Learning and NLP - Open Data Science - Your News Source for AI, Machine Learning & more?

opendatascience.com
圖標

推薦閱讀:
相關文章