Attention Is All You Need
作者:elfin 參考資料來源:transformer
transformer家族近期炙手可熱,不僅霸占了NLP領域的江山,在CV領域也有踢館CNN的趨勢 。那么它有那么牛嗎?牛啊牛?在弱人工智能時代,沒有永遠的神,transformer也是如此,它也有自己擅長、不擅長的數據分布。
transformer在CV中井噴式發展,最近幾個月對新技術的梳理、測試,發現像Swin根本不能超越CNN性能,其精度是非常接近CNN系列的SOTA,但是計算速度卻裂開了。特別是 GPU算力受限的情況下,你就明白這訓練速率讓整個人生都卡頓的感覺。最近清華發表了一篇Autoformer,結構設計上非常像NLP任務,但是這個實際上並不能說其超越了transformer結構,因為它的數據分布適應域比較窄,若在一般數據據分布下,其性能一定會退化。當然也有驚喜,新鮮出爐的VOLO為transformer找回了場子 。通過對結構的巧妙設計,在技術上對計算速率進行了處理,在CV領域,作者聲稱第一次超越了CNN結構 。對此,我目前還沒有做任何嘗試,但是比較相信,論文結果在一般數據上的良好遷移性。
既然,那么多模型,都子子孫孫無窮盡了,為什么還要回到模開始的地方,研究transformer呢?如果你只是使用別人的工程項目,甚至沒有看過此論文,那么你很難對這些理論進行深刻理解;transformer總是讓人感覺很高級的樣子,我希望讓它看起來一點也不高級,用最原始的東西闡述一些“高大”的概念。
下面我們來讀論文……
摘要
主要的序列轉換模型是基於復雜的遞歸或卷積神經網絡,包括編碼器和解碼器。性能最好的模型還通過注意機制連接編碼器和解碼器。我們提出了一個新的簡單的網絡結構:Transformer,完全基於注意機制,避免了遞歸和卷積。在兩個機器翻譯任務上的實驗表明,這些模型具有更高的並行性和更少的訓練時間。我們的模型在WMT 2014英語到德語的翻譯任務中達到28.4 BLEU,比現有的最佳結果(包括聚合模型)提高了2 BLEU以上。在WMT 2014英語-法語翻譯任務中,我們的模型在8個GPU上訓練3.5天后建立了新的單模型最新BLEU分數41.8,這是文獻中最佳模型培訓成本的一小部分。通過將Transformer成功地應用於大規模和有限訓練數據下的英語選區分析,證明了Transformer具有良好的泛化能力。
1、介紹
遞歸神經網絡,特別是長-短期記憶[13]和門限遞歸[7]神經網絡,已經被確定為序列建模和轉換問題(如語言建模和機器翻譯)的最新方法[35,2,5]。自那以后,許多努力繼續推動提升循環語言模型和編解碼器架構的性能[38,24,15]。
遞歸模型通常沿着輸入和輸出序列的符號位置進行因子計算。將位置與計算時間步長對齊,它們生成一系列隱藏狀態\(h_{t}\),\(h_{t}\)作為先前隱藏狀態\(h_{t-1}\)和位置\(t\)的輸入的函數。這種固有的順序性排除了訓練示例中的並行化,這在較長的序列長度下變得至關重要,因為內存限制限制了跨示例的批處理。最近的工作通過因子分解技巧[21]和條件計算[32]在計算效率方面取得了顯著的改進,同時也提高了后者的模型性能。然而,順序計算的基本限制仍然存在。
在這項工作中,我們提出了Transformer,一種避免遞歸出現的模型架構,而完全依賴於一種注意機制來繪制輸入和輸出之間的全局依賴關系。Transformer允許更明顯的並行化,並可以在機器翻譯上達到SOTA狀態,且在8個P100GPU只要12小時訓練時間。
2、背景介紹
為了減少序列計算,也形成了擴展神經GPU〔16〕、ByteNet〔18〕和VusS2S〔9〕的基礎,所有這些都使用卷積神經網絡作為基本構建塊,並行計算所有輸入和輸出位置的隱藏表示。在這些模型中,將兩個任意輸入或輸出位置的信號關聯起來所需的操作數隨着位置之間的距離而增長,convs2是線性的,ByteNet是對數的。這使得學習遠距離位置之間的依賴關系變得更加困難[12]。在Transformer中,這被減少到一個恆定的操作數,盡管由於平均注意加權位置而降低了有效分辨率,我們用多頭部注意抵消了這種影響,如第3.2節所述。
自我注意,有時被稱為內部注意,是一種注意力機制,將單個序列的不同位置聯系起來,以計算序列的表示形式。自我注意在閱讀理解、抽象總結、語篇蘊涵和學習任務無關的句子表征等任務中得到了成功的應用[4,27,28,22]。
端到端記憶網絡是基於一種循環注意機制而不是序列對齊的遞歸,並且在簡單的語言問答和語言建模任務中表現良好[34]。
然而,據我們所知,Transformer是第一個完全依靠自我注意來計算其輸入和輸出的表示,而不使用序列對齊的RNN或卷積的轉導模型。在下面的章節中,我們將描述Transformer,激發自我關注,並討論其相對於[17,18]和[9]等模型的優勢。
3、模型架構
大多數競賽中的模型都有編碼解碼器結構[5,2,35]。這里,編碼器將符號表示\(\left( x_{1}, \cdots ,x_{n} \right)\)的輸入序列映射到連續表示\(z = \left( z_{1}, \cdots ,z_{n} \right)\)的序列。給定\(z\),解碼器然后一次生成一個元素的符號,得到輸出序列\(\left( y_{1}, \cdots ,y_{m} \right)\)。在每一步中,模型都是自回歸的[10],在生成下一步時,使用先前生成的符號作為額外的輸入。
Transformer遵循這個整體架構,使用堆疊的自我關注和逐點式,編碼器和解碼器的完全連接層,分別如圖1的左半部分和右半部分所示。

上面這個鬼東西,一看就讓人腦殼痛,花里胡哨的……下面我們就看圖說話:
上圖左邊的是編碼器:
- 最下面的小粉紅是輸入,可以理解為對世界萬物的數字化抽象對象,簡單的說就是詞向量;
- 往上走是一個加號,它是與位置編碼相加;
- 朝着箭頭的方向來到一個灰色的框,注意左邊有個\(\text{N}\times\)的符號,表示這樣的layer有\(\text{N}\)個;
- 灰色框的 第一個殘差連接塊,橙色框明確告訴我們它是多頭注意力。這就像哪吒,平時跟你說話一個頭就好了,要打你的時候就整出三個頭。頭多了就可以實現數據並行,有利於提升資源占用,提高效率。然后就是殘差連接再接layer Norm,可以理解為干完架要打掃一下戰場,shortcut就負責給重建提供指導,告訴模型這個團要10名狙擊手,別整個低配就來了;MHA分支就是干架的那批人,打贏了就限制一下,別太驕傲,干不過就補充一下。LN就負責給每個人戒驕戒躁,使數據元素整齊划一。
- 而藍色的塊是Feed Forward,一般就是 MLP,主要就是將特征進行融合提取更高級的語義。
- 經過疊加,最后形成輸入的編碼 ,此時,編碼是高維空間中的一個 點,它表示了輸入的所有信息。如果信息是完備的,那么我們可以根據這個點得到我們想要的信息。
上圖右邊的是解碼器:
下面是關於上面出現的一些名稱說明……
3.1 編碼器和解碼器堆棧
編碼器:編碼器由N=6個相同層組成。每層有兩個子層。第一層是一種多頭自我注意機制,第二種是一種簡單的逐點全連接前饋網絡。我們在兩個子層的每一個子層周圍使用殘差連接[11],然后使用LN(Layer Normalization)[1]。也就是說,每個子層的輸出是\(\text{LayerNorm}\left( x + \text{Sublayer} \left( x \right) \right)\)。為了方便這些殘差連接,模型中的所有子層以及嵌入層都會生成維數為\(d_{model}=512\)的輸出。
解碼器:解碼器也由N=6個相同層的堆疊組成。除了每個編碼器層中的兩個子層之外,解碼器還插入第三個子層,該子層對編碼器模塊的輸出執行多頭注意力。與編碼器類似,我們在每個子層周圍使用剩余連接,然后進行LN。我們還修改了解碼器堆棧中的自我注意子層,以防止位置涉及后續位置。這種掩蔽與輸出嵌入被一個位置偏移的事實相結合,確保位置\(i\)的預測只能依賴於位置小於\(i\)的已知輸出。
3.2 Attention
注意函數可以描述為將查詢和一組鍵值對映射到輸出,其中查詢\(q\)、鍵\(k\)、值\(v\)和輸出都是向量。輸出由值和值元素的權值相乘得到,權值是由查詢與鍵相乘得到。如圖所示:

3.2.1 點乘縮放注意力
首先我們提出一個問題,為啥要縮放?是不是感覺好像能理解又說不出個所以然!那么你可以參考:https://blog.csdn.net/qq_37430422/article/details/105042303
對應上圖的左邊,即為點乘縮放注意力機制。計算公式為:
這個公式很簡單,作者會有各種理論解釋,簡單來說就是:
- 我要從一堆信息中得到這層的特征工程挖掘結果;
- 現在我挖了個\(V\)出來,想了一下,這個值矩陣能代表序列信息嗎?
- 現在我又想挖個權值向量,對結果加權輸出;
- 對於權值的獲取總是要滿足一些規則的,這里我們挖了一個查詢\(Q\)與鍵\(K\)使用點乘、縮放得到權值
3.2.2 多頭注意力機制
如圖二所示,我們將\(Q,K,V\)分成\(h\)份,分別執行點乘縮放操作,得到各自的輸出,最后再合並。這樣做有啥子好處?首先假設之前的向量維度是\(d_{k}\),我們現在每個頭的向量維度是\(\frac{d_{k}}{h}\),那這樣向量之間的乘法操作我們的多頭模型只有原來的\(\frac{1}{h}\)。關鍵的點在於這\(h\)個頭我們可以並行計算,計算量的減少也會直觀體現在計算速度上。
多頭注意力的計算為:
其中的參數矩陣為:
- \(W_{i}^{Q} \in \mathbb{R}^{d_{model}\times d_{k}}\) , \(W_{i}^{K} \in \mathbb{R}^{d_{model}\times d_{k}}\) , \(W_{i}^{V} \in \mathbb{R}^{d_{model}\times d_{v}}\) ;
- \(W^{O} \in \mathbb{R}^{hd_{v} \times d_{model}}\)
transformer里面設置了8個頭,\(d_{k}=d_{v}=d_{model} / h=64\)。由於每個頭部的維數減小,總的計算量與全維單頭部注意力的計算量相似。
\(h\)個頭實際將每個頭的計算量相加就和單頭計算量一樣,后面的計算量幾乎可以忽略。
3.2.3 在Transformer中應用注意力機制
在Transformer中以如下三種不同的方式使用多頭注意力:
-
在“編碼器-解碼器注意力”層中,查詢來自前一個解碼器層,而存儲的鍵和值來自編碼器的輸出。這使得解碼器中的每個位置都可以參與輸入序列中的所有位置。這模仿了典型的編碼器-解碼器在序列到序列模型中的注意機制,如[38,2,9]。
第一種實現我們可以在架構中直接找到:
這種實現只是在編碼器向解碼器過渡的層。
-
編碼器包含自我注意層。在self-attention層中,所有的鍵、值和查詢都來自同一個地方,在本例中是編碼器中前一層的輸出。編碼器中的每個位置都可以關注編碼器前一層中的所有位置。
-
類似地,解碼器中的自我關注層允許解碼器中的每個位置關注到解碼器中直到並且包括該位置的所有位置。我們需要防止解碼器中的信息流向左流動,以保持自回歸特性。我們通過Mask輸出: softmax輸入中與非法連接相對應的所有值(設置為\(-\infty\))。見圖2。
這部分就是:
3.3 位置感知前饋網絡
除了注意子層之外,我們的編碼器和解碼器中的每一層都包含一個全連接前饋網絡,該網絡分別相同地應用於每個位置。這包括兩個線性變換,中間有一個ReLU激活。
一般在代碼中你會看到一個MLP層,就是位置感知前饋網絡的實現。
雖然線性變換在不同的位置上是相同的,但它們在層與層之間使用不同的參數。另一種描述方法是兩個核大小為1的卷積。輸入和輸出的維數為\(d_{model}\)=512,內層的維數為\(d_{ff}=2048\)。
3.4 Embeddings and Softmax
與其他序列轉換模型類似,我們使用學習的編碼器將輸入tokens和輸出tokens轉換為維度\(d_{model}\)的向量。我們還使用線性變換和softmax函數將解碼器輸出轉換為預測的下一個token概率。在我們的模型中,我們在兩個嵌入層和預softmax線性變換之間共享相同的權重矩陣,類似於[30]。在編碼層中,我們將這些權重乘以\(\sqrt{d_{model}}\)。
3.5 位置編碼
由於我們的模型不包含遞歸和卷積,為了使模型能夠利用序列的順序,我們必須注入一些關於符號在序列中的相對或絕對位置的信息。為此,我們將“位置編碼”添加到編碼器和解碼器堆棧底部的輸入嵌入中。位置編碼與嵌入具有相同的維度\(d_{model}\),因此可以將兩者相加。有許多位置編碼可以選擇,如學習的和固定的[9]。
在這項工作中,我們使用不同頻率的正弦和余弦函數:
其中\(pos\)是位置,\(i\)是向量維度。也就是說,位置編碼的每個維度對應於一個正弦曲線。波長呈幾何級數從\(2π\)到\(10000·2π\)。我們之所以選擇這個函數,是因為我們假設它可以讓模型很容易地通過相對位置來學習,因為對於任何固定的偏移量\(k\),\(PE_{pos+k}\)可以表示為\(PE_{pos}\)的線性函數。
注:為啥子使用正余弦函數進行位置編碼,我想上面的解釋大概率對於大部分看這篇文章的小菜鳥都不明白,那么建議到蘇劍林的博客下一探究竟。
我們還嘗試使用學習到的位置嵌入[9],發現這兩個版本產生了幾乎相同的結果(見表3第(E)行)。我們選擇正弦版本,因為它可能允許模型外推序列長度比訓練中遇到的更長。
完!