Transformer模型詳細介紹

簡介

Transformer出自于Google于2017年發(fā)表的論文《Attention is all you need》,最開始是用于機器翻譯,并且取得了非常好的效果。但是自提出以來,Transformer不僅僅在NLP領(lǐng)域大放異彩,并且在CV、RS等領(lǐng)域也取得了非常不錯的表現(xiàn)。尤其是2020年,絕對稱得上是Transformer的元年,比如在CV領(lǐng)域,基于Transformer的模型橫掃各大榜單,完爆基于CNN的模型。為什么Transformer模型表現(xiàn)如此優(yōu)異?它的原理是什么?它成功的關(guān)鍵又包含哪些?本文將簡要地回答一下這些問題。

Transformer總覽

我們知道Transformer模型最初是用于機器翻譯的,機器翻譯應(yīng)用的輸入是某種語言的一個句子,輸出是另外一種語言的句子。如下圖:
機器翻譯應(yīng)用

將中間的Transformer模塊進一步拆開,可以看到它主要包含Encoders和Decoders兩個部分,加了s代表它包含多個encoder和decoder。如下:
如果再進一步拆解開來,在原始的Transformer模型中,Encoders和Decoders部分中都分別包含6個encoder和decoder。
其中每一個encoder和decoder結(jié)構(gòu)都是一樣的,這里只是單純地疊加起來而已。我們主要要關(guān)注的是單個encoder和decoder的內(nèi)部結(jié)構(gòu),先將encoder的結(jié)構(gòu)展示如下:
encoder結(jié)構(gòu)

encoder的一共包含2層,分別是Self-Attention(SA)層和Feed Forward Neural Network(FFN)層,SA層的作用是在對輸出序列中的每個詞編碼的時候,讓編碼信息中包含序列中的其他單詞的信息,即保存了當(dāng)前單詞與其余單詞之間的關(guān)系。FFN層就是普通的前向網(wǎng)絡(luò),對SA層的輸出進行近一步的特征提取。

Self-Attention層

我們現(xiàn)在了解了Transformer模型的整體結(jié)構(gòu),其實并不復(fù)雜。這節(jié)主要要介紹其中的Self-Attention層,這也是困擾諸多初學(xué)者的部分。相信很多人都是第一次聽說self-attention這個詞,那么它的工作原理究竟是什么呢?接下來我們一步一步地將它分解開來。
首先我們知道encoder的輸入是序列,也就是詞向量,也叫做token。畢竟原始的句子,比如英文,是無法直接輸入到模型的,我們需要使用類似Word Embedding等方式,將單詞轉(zhuǎn)換成一個個固定長度的詞向量,比如512維。將詞向量序列直接輸入encoder,即依次經(jīng)過SA層和FNN層,如下:

encoder
以上圖為例,讀者不要被圖中的箭頭迷惑了,認為z_i只與x_i有關(guān),實際上在SA層的內(nèi)部,每一個z_i的輸出都需要依賴所有的輸入x_i,即所謂注意力機制。

Self-Attention的實現(xiàn)細節(jié)

這一節(jié)通過實際的例子來剖析SA層的實現(xiàn)細節(jié),首先是如何基于向量來計算注意力,然后我們看一下它在實際應(yīng)用中是如何基于矩陣進行加速的。整個Self-Attention過程可以分為6步,接下來我們來一探究竟。

一、 創(chuàng)建Q、K、V矩陣

首先我們需要為每個輸入向量(也就是詞向量)創(chuàng)建3個向量,分別叫做Query、Key、Value。那么如何創(chuàng)建呢?我們可以對輸入詞向量分別乘上3個矩陣來得到Q、K、V向量,這3個矩陣的參數(shù)在訓(xùn)練的過程是可以訓(xùn)練的。注意Q、K、V向量的維度是一樣的,但是它們的維度可以比輸入詞向量小一點,比如設(shè)置成64,其實這步也不是必要的,這樣設(shè)置主要是為了與后面的Mulit-head注意力機制保持一致(當(dāng)使用8頭注意力時,單頭所處理的詞向量維度為512/8=64,此時Q、K、V向量與輸入詞向量就一致了)。我們假設(shè)輸入序列為英文的"Thinking Machines",那么對應(yīng)的Q、K、V向量的計算示例圖如下:

Q、K、V向量的計算示意圖
計算完成后,對于每一個輸入詞向量,都有3個Q、K、V向量。比如對于輸入向量X_1,對應(yīng)的QKV向量為q_1, k_1, v_1。

但是究竟什么是Q、K、V向量呢?它們的具體含義是什么?如何理解記憶呢?首先Query、Key、Value這個概念出自于信息檢索系統(tǒng),我們以在Youtube上搜索視頻為例來具體說明一下它的工作流程。
當(dāng)你搜索(query)一個特定的視頻的時候,搜索引擎會將你的query映射到一組keys(比如視頻標題、描述等等)上去,然后去找與這些keys最匹配的視頻,也就是values。這就是基于特征的查詢的基本原理。整體流程如下:

二、 計算Score

得到Q、K、V矩陣之后,第一步是計算Self-Attention中的score,具體做法如下。以輸入序列的第一個單詞"Thinking"為例,我們需要計算這個單詞與輸入序列的所有單詞之間的score。當(dāng)我們在某個位置對單詞進行編碼時,這個score其實決定了將多少注意力放在輸入句子的其他部分上。
score的計算是取當(dāng)前被計算單詞的query向量,以及所有的單詞的key向量,取兩者的點積來當(dāng)做當(dāng)前單詞的score。比如我們對輸入序列的第一個單詞“Thinking”計算score,由于整個序列長度為2,那么第一個score的計算使用q_1k_1的點積,第二個score使用q_1k_1的點積。如下圖:

score的計算過程

三、 Softmax

接下來,我們首先將上一步得到的score除以8,為什么是8,因為在第一步中,我們定義了Q、K、V矩陣的維度為64,64開根號為8。這么做的原因是為了保證更加穩(wěn)定的梯度。然后將結(jié)果通過一個Softmax函數(shù),Softmax函數(shù)會將scores歸一化,使其全部都是整數(shù),并且累加和為1。
Softmax

經(jīng)過Softmax函數(shù)后的score決定了當(dāng)前單詞對每個位置的單詞的影響程度。很顯然當(dāng)前單詞對當(dāng)前位置的影響程度一般是最大的。

四、將socre乘以values

接下來,將softmax后的scores乘以values向量,這么做的目的是為了保證我們需要關(guān)注的values向量的完整性,并且忽略掉不相關(guān)的values向量。例如對不相關(guān)的values向量乘以一個0.001,使其變得微不足道。

五、將values累加起來

這一步就很簡單,將上一步得到的各個values向量累加起來就得到當(dāng)前輸入詞向量的輸出向量了。將四五步結(jié)合起來看,其實就相當(dāng)于是一個加權(quán)求和操作,其中的權(quán)重就是第三步計算出來的scores,整個過程示意圖如下:

這就是Self-Attention層的整體計算過程。這個輸出向量就是我們需要進一步送往前饋神經(jīng)網(wǎng)絡(luò)中的。但是在實際的計算中,為了加快計算速度,我們通常會使用矩陣運算,接下來我們看下如何使用矩陣運算來簡化和加速上述的計算步驟。

Self-Attention矩陣計算

第一步是計算Query, Key,和Value向量,我們先將所有的輸入詞向量拼成一個矩陣X,然后乘以已經(jīng)訓(xùn)練好的權(quán)重矩陣(W^Q,W^K,W^V)。

計算QKV矩陣

注意輸入矩陣X中的每一行都代表了輸入序列中的一個詞向量。

剩下的步驟其實就是計算scores,通過softmax函數(shù),再乘以矩陣V,我們可以用一下公式來表示:

多頭注意力機制

上面提到的Self-Attention層可以認為是單頭的,那什么叫多頭注意力機制呢?其實也非常簡單,就是對于輸入詞向量矩陣, 不再只是擁有一組(W^Q,W^K,W^V)權(quán)重矩陣,而是擁有多組。這樣做主要會帶來一下2個好處:

  • 它擴展了模型專注于不同位置的詞向量的能力
  • 它給予了attention層多種表示子空間,即擁有多組(W^Q,W^K,W^V)權(quán)重矩陣,這樣可以將輸入詞向量映射到不同的特征子空間。
    兩頭注意力機制

    如果我們將Self-Attention的計算重復(fù)8次,每次使用不同的權(quán)重矩陣,那么我們就得到了8頭注意力機制,論文中的Transformer實現(xiàn)就是8頭的。同理,我們也會得到8個不同的輸出矩陣z
    但是這會引發(fā)一個問題,8個輸出矩陣無法輸入到encoder下一層的FNN層,所以我們需要設(shè)計一種方式來講這8個輸出矩陣聚合成單個矩陣。
    怎么做呢?我們可以首先將這8個矩陣concat起來,然后乘以一個額外的權(quán)重矩陣W^O,這樣就可以得到與輸入詞向量一樣大小的輸出向量,然后再傳入FNN層。
    下面是多頭注意力機制的整體計算過程圖:
    多頭注意力機制

Positional Encoding

到目前為止,我們都還沒有考慮輸入序列的順序問題。然后對于一句話而言,詞的順序直接影響到了整句話的意思,所以順序非常重要。Transformer使用了Positional Encoding來解決這個問題,即給每個輸入詞向量都加上一個位置向量。這些位置向量可以決定每個單詞在句子中的位置,或者說可以指示句子中不同單詞之間的相對位置。
位置編碼

假如輸入詞向量的維度為4,那么實際的位置編碼向量可能是這樣的:
位置向量

殘差連接

encoder中的SA層基本就講完了,F(xiàn)FN層其實沒有什么特別好說的,就是普通的全連接層。有一點要注意的是,為了解決深度學(xué)習(xí)中的退化問題,encoder中的SA層和FFN層都采用了殘差連接。如下圖中虛線部分
殘差連接

如果將上圖再細化一下,可以得到如下的結(jié)構(gòu)圖:
encoder

這便是encoder的整體計算流程圖了,Transformer模型中堆疊了多個這樣的encoder,無非就是輸出連接輸入罷了,常規(guī)操作。

最后再附上一個Transformer的代碼實現(xiàn),讀者有興趣可以跟著自己復(fù)現(xiàn)一下Transformer模型的代碼。

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容