文獻閱讀筆記—Attention is ALL You Need

本文主要是參考

https://yq.aliyun.com/articles/342508?utm_content=m_39938

https://mchromiak.github.io/articles/2017/Sep/12/Transformer-Attention-is-all-you-need/#positional-encoding-pe

將互相缺少的融合到一起,略微加了點其他東西。

一、簡介

對於Seq2Seq任務,均採用encoder-decoder+attention的模型,以往的encoder-decoder採用rnn或cnn,捕捉輸入輸出的全局信息,attention捕捉輸入和輸出之間的側重關係;而這篇google大作,採用的是attention做encoder-decoder;也就是說,模型中只有attention, 沒有rnn或者cnn。

二、模型整體架構

encoder由6個相同的層堆疊在一起,每一層又有兩個支層。第一個支層是一個多頭的自注意機制(Multi-head attention),第二個支層是一個簡單的全連接前饋網絡(position-wise FFN)。在兩個支層外面都添加了一個residual的連接,然後進行了layer nomalization的操作。模型所有的支層以及embedding層的輸出維度都是dmodel=512.

    Stage1_out = Embedding512 + TokenPositionEncoding512
    Stage2_out = layer_normalization(multihead_attention(Stage1_out) + Stage1_out)
    Stage3_out = layer_normalization(FFN(Stage2_out) + Stage2_out)
    out_enc = Stage3_out

decoder也是由6個相同的層堆疊在一起,不過每層除了編碼器中那兩個支層,還加入了第三個支層,即該層decoder和對應層encoder之間的多頭注意力機制,同樣也用了residual以及layer normalization,因爲decoder時只能用這個token之前的tokens,那麼做attention的時候需要添加一個mask將這個token及其之後的遮蓋住(是一種從左到右預測的味道)。

    Stage1_out = OutputEmbedding512 + TokenPositionEncoding512
    Stage2_Mask = masked_multihead_attention(Stage1_out)
    Stage2_Norm1 = layer_normalization(Stage2_Mask + Stage1_out)
    Stage2_Multi = multihead_attention(Stage2_Norm1 + out_enc) +  Stage2_Norm1
    Stage2_Norm2 = layer_normalization(Stage2_Multi) + Stage2_Multi
    Stage3_FNN = FNN(Stage2_Norm2)
    Stage3_Norm = layer_normalization(Stage3_FNN + Stage2_Norm2) 
    out_dec = Stage3_Norm

三、分塊解析

1. Scaled Dot-Product Attention

                   Attention\left ( Q,K,V \right )=softmax\left (\frac{QK^{T}}{\sqrt{d_{k}}} \right )V

                   Q\in R^{n\times d_{k}},K\in R^{m\times d_{k}},V\in R^{m\times d_{v}}

如果忽略激活函數 softmax 的話,那麼事實上它就是三個 n\times d_{k},d_{k}\times m,m\times d_{v} 的矩陣相乘,最後的結果就是一個n\times d_{v}的矩陣。於是我們可以認爲:這是一個 Attention 層,將n\times d_{k}的序列 Q 編碼成了一個新的 n\times d_{v} 的序列。

那怎麼理解這種結構呢?我們不妨逐個向量來看。

                  Attention\left ( q_{t},K,V \right )=\sum_{s=1}^{m} \frac{1}{Z}exp\left ( \frac{<q_{t},k_{s}>}{\sqrt{d_{k}}}\right )v_{s}

其中 Z 是歸一化因子。事實上q,k,v分別是 query,key,value 的簡寫,K,V 是一一對應的,它們就像是 key-value 的關係,那麼上式的意思就是通過 q_{t} 這個 query,通過與各個 k_{s} 內積的並 softmax 的方式,來得到 q_{t} 與各個 v_{s} 的相似度,然後加權求和,得到一個 d_{v} 維的向量。其中\sqrt{d_{k}}因子起到調節作用,使得內積不至於太大(太大的話 softmax 後就非 0 即 1 了,不夠“soft”了),因爲文章假設數據符合標準正態分佈,爲了使點乘結果的方差爲1,所以使用了根號。

2. Multi-Head Attention

不過從形式上看,它其實就再簡單不過了,就是把 Q,K,V通過參數矩陣映射一下,然後再做 Attention,把這個過程重複做 h 次,結果拼接起來就行了,可謂“大道至簡”了。具體來說:

                    head_{i}=Attention\left ( QW_i^Q,KW_i^K,VW_i^V\right )

                   MultiHead\left (Q,K,V \right )=Concat\left ( head_{1},......,head_{h}\right )

最後得到一個 n\times h\times d_{v} 的序列。所謂“多頭”(Multi-Head),就是隻多做幾次同樣的事情(參數不共享),然後把結果拼接。有點類似於cnn裏面的多kernel。

本文中,大部分的 Attention 都是 Self Attention,即“自注意力”,或者叫內部注意力,就是Attention(X,X,X)X 就是前面說的輸入序列。也就是說,在序列內部做 Attention,尋找序列內部的聯繫。decoder裏面和encoder的attention是Attention(decoder-out,encoder-out,encoder-out)

3. position-wise FFN

一個position對應一個詞,一個詞對應矩陣的一行,該函數爲對矩陣的每一行做兩個線性映射,中間加一個ReLU,每一行的線性映射參數一樣,相當於size爲1的kernel。不同layer的兩個線性映射參數不一致。記輸入矩陣的某行爲x,則:

                   FFN(X)=max(0,xW_1+b_1)W_2+b_2

4. position encoding

但是這樣的模型並不能捕捉序列的順序。換句話說,如果將 K,V 按行打亂順序(相當於句子中的詞序打亂),那麼 Attention 的結果還是一樣的。所以,到目前爲止,Attention 模型頂多是一個非常精妙的“詞袋模型”而已。 

但是對於時間序列來說,尤其是對於 NLP 中的任務來說,順序是很重要的信息,它代表着局部甚至是全局的結構,學習不到順序信息,那麼效果將會大打折扣(比如機器翻譯中,有可能只把每個詞都翻譯出來了,但是不能組織成合理的句子)。 

於是 引入——Position Embedding,也就是“位置向量”,將每個位置編號,然後每個編號對應一個向量,通過結合位置向量和詞向量,就給每個詞都引入了一定的位置信息,這樣 Attention 就可以分辨出不同位置的詞了。 

以前在 RNN、CNN 模型中其實都出現過 Position Embedding,但在那些模型中,Position Embedding 是錦上添花的輔助手段,也就是“有它會更好、沒它也就差一點點”的情況,因爲 RNN、CNN 本身就能捕捉到位置信息。但是在這個純 Attention 模型中,Position Embedding 是位置信息的唯一來源,因此它是模型的核心成分之一。 

在以往的 Position Embedding 中,基本都是根據任務訓練出來的向量。而 Google 直接給出了一個構造 Position Embedding 的公式:

                  \left\{\begin{matrix}PE_{2i}\left ( p \right )=sin\left ( p/10000^{2i/d_{pos}} \right ) \\ PE_{2i+1}\left ( p \right )=cos\left ( p/10000^{2i/d_{pos}}\right ) \end{matrix}\right.

這裏的意思是將位置 p 映射爲一個 dpos 維的位置向量,這個向量的第 i 維的數值就是 PEi(p)。

Position Embedding 本身是一個絕對位置的信息,但在語言中,相對位置也很重要,由於我們有 sin\left ( \alpha +\beta \right )=sin\alpha cos\beta+cos\alpha sin\beta 以及 cos\left ( \alpha +\beta \right )=cos\alpha cos\beta-sin\alpha sin\beta,這表明位置 p+k 的向量可以表明位置 p 的向量的線性變換,這提供了表達相對位置信息的可能性。

結合位置向量和詞向量有幾個可選方案,可以把它們拼接起來作爲一個新向量,也可以把位置向量定義爲跟詞向量一樣大小,然後兩者加起來,本文選擇加起來。

四、優點

從三個方面去對比self-attention和遞歸結構、卷積結構的優劣性,首先是每一層的計算複雜度,其次是能夠被並行的計算量,最後是網絡中長期依賴的路徑長度。對比顯示,self-attention表現最好。

Attention 層的好處是能夠一步到位捕捉到全局的聯繫,因爲它直接把序列兩兩比較(代價是計算量變爲 O(n^2),當然由於是純矩陣運算,這個計算量相當也不是很嚴重)。相比之下,RNN 需要一步步遞推才能捕捉到,而 CNN 則需要通過層疊來擴大感受野,這是 Attention 層的明顯優勢。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章