學一學Transfomer


 

 

017年,Google發表論文《Attention is All You Need》,提出經典網絡結構Transformer,全部采用Attention結構的方式,代替了傳統的Encoder-Decoder框架必須結合CNN或RNN的固有模式。並在兩項機器翻譯任務中取得了顯著效果。該論文一經發出,便引起了業界的廣泛關注,同時,Google於2018年發布的划時代模型BERT也是在Transformer架構上發展而來。所以,為了之后學習的必要,本文將詳細介紹Transformer模型的網絡結構。

一 理論基礎

1、整體架構

            
 
            

 


 

 
 

Transformer作為seq2seq,也是由經典的Encoder-Decoder模型組成。在上圖中,整個Encoder層由6個左邊Nx部分的結構組成。整個Decoder由6個右邊Nx部分的框架組成,Decoder輸出的結果經過一個線性層變換后,經過softmax層計算,輸出最終的預測結果。

(1)、Encoder結構:

輸入序列X經過word embedding和positional encoding做直接加和后,作為Encoder部分的輸入。輸入向量經過一個multi-head self-attention層后,做一次residual connection(殘差連接)和Layer Normalization(層歸一化,下文中簡稱LN),輸入到下一層position-wise feed-forward network中。之后再進行一次殘差連接+LN,輸出到Decoder部分,這里所涉及到的相關知識會在下文中詳細介紹。

(2)、Decoder結構:

輸出序列Y經過word embedding和positional encoding做直接加和后,作為Decoder部分的輸入。很多對seq2seq不了解的朋友看到這里可能有些糊塗,簡單說明以下。以翻譯任務為例,假設我們要進行一個中譯英任務。我們現在有一段中文序列X,對應的英文序列Y。我們在翻譯出某個單詞Yt時,並非只是用中文序列X翻譯,而是用中文序列X加已經翻譯出來的英文序列(y1,y2,……yt-1)進行翻譯,所以也要將已經翻譯出來的英文序列輸入其中。這也就解釋了為什么會將輸出序列Y作為Decoder的輸入。在論文中,在訓練過程中為了處理方便同時不引入未來信息,采用了一種sequence masking機制,具體的實現下文再詳細介紹。

Decoder部分的輸入向量首先經過一層multi-head self-attention,進行一次殘差連接+LN,再經過一層multi-head context-attention,進行一次殘差連接+LN,最后再經過一層position-wise feed-forward network,進行一次殘差連接+LN后,輸出至線性層。

以上介紹了Encoder和Decoder的基本流程,相信大家對其中具體的實現還有不明白的細節,下面我就來為大家一一闡述。

2、Attention機制

上文中提到了兩個Attenton結構,multi-head self-attention和multi-head context-attention可以說是本文中最重要的概念,這里來解釋下兩者的實現,首先,我們來回顧以下基礎的Attention機制。

(1)、基礎Attention機制

之前曾經寫過一篇詳細介紹Attention的文章,感興趣的朋友可以關注我的公眾號查找,這里主要使用論文中描述的方式來簡單介紹以下基礎Attention。

在自然語言處理中,Attention的本質可以理解為一個查詢(query)到一些列(key - value)對的映射。以基礎的Attention計算公式為例:

 

 

 

計算attention時:第一步,將query和每個key進行相似度計算得到權重,即上圖中的第三個公式。第二步,一般使用一個softmax函數將這些權重進行歸一化,即上圖中的第二個公式,最后將權重和相應的鍵值value進行加權求和,得到最終的attention,即第一個公式。通常key和value取值相同,例如上圖中,key=value=hj, query=si-1。

其實,Google所用到的基本attention思路是與上面一致的,只是在計算Attention分數時,采用了另一種計算機制:Scaled dot-product attention

(2)、Scaled dot-product attention

Scaled dot-product attention的計算公式如下:

 

 

其實基本元素還是Q,K,V三項,無非就是公式變了下。具體的計算圖結構文章中也給了圖,公式很清晰這里就不列了。

(3)Self-attention 和Context-attention

Self-attention:自己跟自己做Attention,輸入序列=輸出序列。Q=K=V。

Context-attention:Encoder輸出結果跟Decoder第一部分輸出結果之間做Attention。

具體到網絡結構中:

Encoder中的self-attention,Q,K,V均為Encoder的輸入。

Decoder中的self-attention,Q,K,V均為Decoder的輸入,也就是上一層Decoder的輸入,具體原因見Decoder的介紹。

Decoder中context-attention,Q為decoder中第一部分的輸出,K,V均為encoder的輸出。

(4)、Multi-head attention

論文中采用的Multi-head attention,就是將Q, K, V先經過一個線性映射,再在在輸入維度dk,dq,dv上切分成h份,再對每一份進行Scaled dot-product attention,之后將每部分結果合並起來,經過線性映射,得到最終的輸出,結構圖如下:

 
                    

 

                    
                
大戰多頭怪

 

 

 

說的有些繞,舉個例子,原文中d=512(即詞向量和位置向量的維度),h=8。那么假設原始輸入為[batch_size*seq_len*512]的三維表,處理后共分成8份[batch_size*seq_len* 64]的三維表,每份分別做Scaled dot-product,就是Multi-head attention了。這樣進行了h次運算,可以允許模型在不同的表示子空間中學習到相關信息。

以上就是Attention部分的全部講解,說清楚這一部分,其他的都是一些零碎的細節。

3、Position-wise Feed-Forward network

一個全聯接神經網絡,先進行一次線性變換,再通過一次ReLU激活函數,最后再進行一次線性變化。公式如下:

 

 

 

4、Positional encoding

位置編碼,顧名思義,對序列中詞語的位置進行編碼,公式如下:

 

 

 

即奇數位置用余弦編碼,偶數位置用正弦編碼,最終得到一個512維的位置向量。

5、Residual connection

殘差連接其實在很多網絡機構中都有用到。原理很簡單,假設一個輸入向量x,經過一個網絡結構,得到輸出向量f(x),加上殘差連接,相當於在輸出向量中加入輸入向量,即輸出結構變為f(x)+x,這樣做的好處是在對x求偏導時,加入一項常數項1,避免了梯度消失的問題。

6、Layer Normalization

歸一化的本質都是將數據轉化為均值為0,方差為1的數據。這樣可以減小數據的偏差,規避訓練過程中梯度消失或爆炸的情況。我們在訓練網絡中比較常見的歸一化方法是Batch Normalization,即在每一層輸出的每一批數據上進行歸一化。而Layer Normalization與BN稍有不同,即在每一層輸出的每一個樣本上進行歸一化。

7、Mask

mask的思想非常簡單:就是對輸入序列中沒某些值進行掩蓋,使其不起作用。在論文中,做multi-head attention的地方用到了padding mask,在decode輸入數據中用到了sequence mask。

(1)、padding mask

在我們輸入的數據中,因為每句話的長度不同,所以要對較短的數據進行填充補齊長度。而這些填充值並沒有什么作用,為了減少填充數據對attention計算的影響,采用padding mask的機制,即在填充物的位置上加上一個趨緊於負無窮的負數,這樣經過softmax計算后這些位置的概率會趨近於0

(2)、sequence mask

在上文中我們提到,預測t時刻的輸出值yt,應該使用全部的輸入序列X,和t時刻之前的輸出序列(y1,y2,……,yt-1)進行預測。所以在訓練時,應該將t-1時刻之后的信息全部隱藏掉。所以需要用到sequence mask。

實現也很簡單,就是用一個上三角矩陣,上三角值均為1,下三角值均為0,對角線值為0,與輸入序列相乘,就達到了目的。

以上就是Transformer框架的全部知識點,BERT模型也是在此基礎上發展而來。


二: 例子

      先來看一個翻譯的例子“I arrived at the bank after crossing the river” 這里面的bank指的是銀行還是河岸呢,這就需要我們聯系上下文,當我們看到river之后就應該知道這里bank很大概率指的是河岸。在RNN中我們就需要一步步的順序處理從bank到river的所有詞語,而當它們相距較遠時RNN的效果常常較差,且由於其順序性處理效率也較低。Self-Attention則利用了Attention機制,計算每個單詞與其他所有單詞之間的關聯,在這句話里,當翻譯bank一詞時,river一詞就有較高的Attention score。利用這些Attention score就可以得到一個加權的表示,然后再放到一個前饋神經網絡中得到新的表示,這一表示很好的考慮到上下文的信息。如下圖所示,encoder讀入輸入數據,利用層層疊加的Self-Attention機制對每一個詞得到新的考慮了上下文信息的表征。Decoder也利用類似的Self-Attention機制,但它不僅僅看之前產生的輸出的文字,而且還要attend encoder的輸出。

 三: 對自注意力機制的感性認識

A: 從宏觀視角看自注意力機制 

例如,下列句子是我們想要翻譯的輸入句子:

The animal didn't cross the street because it was too tired

 

這個“it”在這個句子是指什么呢?它指的是street還是這個animal呢?這對於人類來說是一個簡單的問題,但是對於算法則不是。

當模型處理這個單詞“it”的時候,自注意力機制會允許“it”與“animal”建立聯系。

隨着模型處理輸入序列的每個單詞,自注意力會關注整個輸入序列的所有單詞,幫助模型對本單詞更好地進行編碼。

如果你熟悉RNN(循環神經網絡),回憶一下它是如何維持隱藏層的。RNN會將它已經處理過的前面的所有單詞/向量的表示與它正在處理的當前單詞/向量結合起來。而自注意力機制會將所有相關單詞的理解融入到我們正在處理的單詞中。

 

 

當我們在編碼器#5(棧中最上層編碼器)中編碼“it”這個單詞的時,注意力機制的部分會去關注“The Animal”,將它的表示的一部分編入“it”的編碼中。

請務必檢查Tensor2Tensor notebook ,在里面你可以下載一個Transformer模型,並用交互式可視化的方式來檢驗。

B: 從微觀視角看自注意力機制

首先我們了解一下如何使用向量來計算自注意力,然后來看它實怎樣用矩陣來實現。

計算自注意力的第一步就是從每個編碼器的輸入向量(每個單詞的詞向量)中生成三個向量。也就是說對於每個單詞,我們創造一個查詢向量、一個鍵向量和一個值向量。這三個向量是通過詞嵌入與三個權重矩陣后相乘創建的。

可以發現這些新向量在維度上比詞嵌入向量更低。他們的維度是64,而詞嵌入和編碼器的輸入/輸出向量的維度是512. 但實際上不強求維度更小,這只是一種基於架構上的選擇,它可以使多頭注意力(multiheaded attention)的大部分計算保持不變。

 

 

X1與WQ權重矩陣相乘得到q1, 就是與這個單詞相關的查詢向量。最終使得輸入序列的每個單詞的創建一個查詢向量、一個鍵向量和一個值向量。

 

參考文獻:

1   經典英文博客中文翻譯: https://zhuanlan.zhihu.com/p/54356280

2  科學:  https://spaces.ac.cn/archives/4765

3  AI機動隊: https://zhuanlan.zhihu.com/p/47282410

4  深度學習中的注意力機制  https://blog.csdn.net/songbinxu/article/details/80739447


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM