Attention is All You Need | 每周一起讀

「每周一起讀」是由 PaperWeekly 發起的協同閱讀小組。我們每周精選一篇優質好文,利用在線協同工具進行精讀並發起討論,在碎片化時代堅持深度閱讀。目前已成立的專題小組有:Chatbot、機器翻譯、知識圖譜、GAN、推薦系統、QA、增強學習、多模態、自動文摘和統計學習。

Attention Is All You Need

通常來說,主流序列傳導模型大多基於 RNN 或 CNN。Google 此次推出的翻譯框架—Transformer 則完全捨棄了 RNN/CNN 結構,從自然語言本身的特性出發,實現了完全基於注意力機制的 Transformer 機器翻譯網路架構。

1. 開源實現

#Chainer#

soskek/attention_is_all_you_need

#PyTorch#

jadore801120/attention-is-all-you-need-pytorch

#TensorFlow#

Kyubyong/transformer

2. 閱讀筆記精選

Robin_CityU:

該 paper 可以算作是 Google 針對 Facebook 之前的 CNN seq2seq: 1705.03122 的回應。工程性較強,主要目的是在減少計算量和提高並行效率的同時不損害最終的實驗結果。

模型的框架如下:

  • Encoder 部分 -- 6 個 block,每個 block 中有兩層,他們分別是 Multi-head self attention 和 Position-wise feed forward。

    1. Multi-head self attention - 多組self attention的連接。首先 encoder 的初始輸入為sentence embedding + position embedding,其中position embedding的三角函數表示挺有意思。

    Attention(Q,K,V)=softmax(QK^T/sqrt(d_k))V,其中 Q 與 K 均為輸入,(V 為 learned value?此處存疑)。輸入 size 為[sequence_length, d_model],輸出 size 不變。然後是 residual connection,即 LayerNorm(x+Sublayer(x)),輸出 size 不變。

    2. Position-wise feed forward network,其實就是一個 MLP 網路,1 的輸出中,每個 d_model 維向量 x 在此先由 xW1+b1 變為 d_ff 維的 x,再經過 max(0, x)W2+b2 回歸 d_model 維。之後再是一個 residual connection。輸出 size 仍是 [sequence_length, d_model]。

  • Decoder 部分 -- 6 個 block,每個 block 中有 3 層,他們分別是 Multi-head self attention (with mask),Multi-head attention (with encoder),Position-wise feed forward。

    1. Multi-head self attention (with mask) 與 encoder 部分相同,只是採用 0-1mask 消除右側單詞對當前單詞 attention 的影響。

    2. Multi-head attention(with encoder) 引入 encoder 部分的輸出在此處作為 multi-head 的其中幾個 head。

    3. Position-wise feed forward network 與encoder部分相同。

  • some tricks during training process:(1) residual dropout; (2) attention dropout; (3) label smoothing

幾點思考:

該模型沒有使用 RNN 與 CNN,但做法其實像 CNN 的簡化版,包括 normalization,dropout 的使用,以及 future work 提出的 local,restricted attention。

文章的第四部分其實並沒有清楚地解釋為什麼使用所謂 self-attention,但是可否由此引出大家對 RNN 系列模型更深入的思考?畢竟 long dependency 與 hard to parallel 等問題一直存在。

在 seq2seq 任務中,一般 RNN 模型,encoder 與 decoder 自身受語言模型的約束較大,因此往往 decode 時常常出現重複、缺失等語言模型常出現的問題,如果真的切斷由 RNN 建立的單詞與單詞之間的聯繫(其實 CNN 已經這麼做了),也值得一試。而 position embedding 的引入,是否可以補充順序信息?

WarBean:

嘗試用自己的理解對比一下卷積、recurrent 和 self attention:

卷積:只能看到領域,適合圖像,因為在圖像上抽象更高層信息僅僅需要下一層特徵的局部區域。

recurrent:理論上能看到所有歷史,適合文本,但是存在梯度消失問題。

self attention:相比 recurrent 不存在梯度消失問題,這點顯然。對比 CNN 更加適合文本,因為能夠看到更遠距離的信息,這點展開說明——因為文本語義的抽象不同於圖像語義的抽象,後者看下一層的局部就行,前者經常需要看很遠的地方。比如現在「蘋果」這個詞我要對它做一個抽象,按「蘋果公司」抽象還是按「水果」抽象呢?這個選擇可能依賴於幾十個 step 之外的詞。誠然,CNN 疊高了之後可以看到很遠的地方,但是 CNN 本來需要等到很高層的時候才能完成的抽象,self attention 在很底層的時候就可以做到,這無疑是非常巨大的優勢。

3. Q&A 精選

Hinse:

We suspect this to be caused by the dot products growing too large in magnitude to result in useful gradients after applying the softmax function.

解釋了引入 scale 是為了避免:當 dk 比較大時點乘結果太大導致有效梯度太大(或被 clipped)。

WarBean: 但是為什麼是除以根號 d_k 而不是 d_k 呢,有沒有人能解釋一下為什麼這麼選?

soloice: 不是很懂為什麼內積變大會導致梯度變小。如果內積變大,應該是每一個 k 和 q 的內積都變大,做 softmax 的話反正最後要歸一化,應該不受影響啊。

有一種可能的解釋是,點積只是絕對值變大,但是數值有正有負,比如 [0.1, -0.1] 變成 [10, -10],softmax 算出來結果就很糟糕。而且即使是這樣的話,也可以期待一半的梯度有效回傳吧 = = 另外這個 scale 其實就是 softmax 里的 temperature 吧,但是為什麼用根號 d_k 就不清楚了。

dalegebit: 回復一下樓上的,其實注釋里寫得很清楚,假設兩個 d_k 維向量每個分量都是一個相互獨立的服從標準正態分布的隨機變數,那麼他們的點乘的方差就是 d_k,每一個分量除以 sqrt(d_k) 可以讓點乘的方差變成 1。

gujiuxiang:

Since our model contains no recurrence and no convolution, in order for the model to make use of the order of the sequence

存疑,輸入應該包含 previous word,怎麼就不無 recurrence。他們的 claim 和之前 facebook cnn 那篇類似,idea 賣得都很炫。不過,我認為都包含recurrence。

wxuan: 編碼器端的 recurrence,都通過這個 Positional Encoding 消除了。

rqyang: 確實是編碼器不存在 recurrence,解碼器存在廣義上的 recurrence。這裡論文的出發點應該是對輸入的序列不存在 recurrence,輸出序列的時候是把上一時刻的詞當作「query」來看了。

Hinse: 感覺 dec 也不存在 recurrence。 因為 recurrence 是指不同 step 之間要順序執行從影響速度的 recurrence。而這個 decoder 每一層對不同位置的計算是並行的。當前位置的計算不依賴前面位置的計算結果。 當然這也是因為他使用的是 ground truth 做輸入。 為了並行, 模型的靈活性受到了限制。

WarBean: 同意樓上說 decode(在訓練階段)也不存在 recurrence。之前的 rnn decoder 在訓練的時候即便給 ground truth(即 Teacher Forcing 訓練法),由於 hidden state 之間存在的連接,所以仍然必須一個個 position 滾過去。本文則不需要,因為已經砍掉相鄰兩步之間 hidden state 這條連接了。不過,在測試階段 decode下一個詞依賴於上一個輸出,所以仍然是 recurrence 的。

jordan: 整個都不存在依賴上一詞的信息的, 只是依賴上一層,但詞與詞之間是可以並行的。

wxuan:

In this work, we use sine and cosine functions of different frequencies.

不是很理解這裡的出發點,對最終效果有多大影響?

Hinse: 文章裡面提到了這樣做,是因為 sin(a+b) = sin(a)cos(b) + cos(b)sin(a),其中 b 是一個固定的 offset 也就是常數了,所以 pos+k 的編碼就可以通過 pos 的編碼來線性表示了。但我感覺還有一個原因就是不容易重複:不同的維度使用不同的頻率 (i=0,1,2... dim_size)。不同位置就是同一個頻率的不同相位。感覺就像信號處理裡面不同的頻率承載不同的信息疊加(位置編碼後有兩個 fc 和 relu)後仍然容易分離,同一個頻率用不同的相位區分信息。這個其實沒太想清楚還是先忽略吧。

rqyang: 如果我運算符優先順序沒弄錯的話,指數運算優先順序更高,然後在最後一維,那不是意味著後面的維度和位置的改變幾乎無關了?不太理解這麼做的意義。參考文獻 [9] 當中用了一個 positional embedding 和詞向量相加,相對好理解得多。

WarBean: 你公式寫錯了,最後一維的 PE = sin(pos / 10000)。

rqyang: 才發現這裡是應該是 PE 的第二個參數是維度,ii 的最大值是維度的一半,謝謝提醒。

WarBean: 這個 position embedding 設置得很有意思,我嘗試解釋一下:每兩個維度構成一個二維的單位向量,總共有 d_model / 2 組。每一組單位向量會隨著 pos 的增大而旋轉,但是旋轉周期不同,按照論文裡面的設置,最小的旋轉周期是 2pi,最大的旋轉周期是 10000 x 2pi。至於為什麼說相鄰 k 步的 position embedding 可以用一個線性變換對應上,是因為上述每組單位向量的旋轉操作可以用表示為乘以一個 2 x 2 的旋轉矩陣。

隱約感覺論文像這樣把 position 表示成多組不同旋轉周期的單位向量,能有助於泛化到訓練時沒有見過的長度,但是說不出為什麼,坐等大神分析。 看上去 10000(省略 2pi)的最大周期好像拉得有點大,似乎沒啥必要,不過我在自己做的一個任務上用了這個 position embedding,我那個任務的 decode step 通常是 50 多,但是最大周期設置到 10、100、1000 效果都還不錯,所以這裡設置成 10000 應該也沒太大問題,最多就是後面一些維度的周期太長變化率太慢,沒啥用,冗餘而已,也沒什麼壞處。如果擔心冗餘維度擠佔有用維度的份額,那就把 d_model 設大一點就好了,論文用 512 維我感覺已經足夠了。

yang: 一個是 sin 一個是 cos,這種位置信息能將相對位置表示的挺不錯的,將時域和頻域空間做了映射,將文本位置信息做成信號。

wxuan:

一般的機器學習論文中,向量默認都是列向量,這裡的公式是根據行向量寫的。

rqyang: 這裡應該都是矩陣,假設 query 的長度為 Lq,序列長度為 L,那麼

論文共讀報名方式

點擊提交內測申請,我們將在 48 小時內完成審核並和您取得聯繫。

關於PaperWeekly

PaperWeekly 是一個推薦、解讀、討論、報道人工智慧前沿論文成果的學術平台。如果你研究或從事 AI 領域,歡迎在公眾號後台點擊「交流群」,小助手將把你帶入 PaperWeekly 的交流群里。

微信公眾號:PaperWeekly

新浪微博:@PaperWeekly

推薦閱讀:

基於TF-IDF演算法抽取文章關鍵詞
層疊注意力模型 - 實現機器閱讀的正確姿勢 | 論文訪談間 #04
<Neural Relation Extraction with Selective Attention over Instances>筆記
HIN2Vec:異質信息網路中的表示學習 | PaperDaily #18
如何處理不均衡數據?

TAG:机器翻译 | 自然语言处理 |