【NLP】Transformer详解
【NLP】Transformer詳解
? Transformer在Google的一篇論文Attention is All You Need被提出,為了方便實現調用Transformer Google還開源了一個第三方庫,基于TensorFlow的Tensor2Tensor,一個NLP的社區研究者貢獻了一個Torch版本的支持:guide?annotating the paper with PyTorch implementation。Transformer模型最早是用于機器翻譯任務,當時達到了SOTA效果。Transformer改進了RNN最被人詬病的訓練慢的缺點,利用self-attention機制實現快速并行。并且Transformer可以增加到非常深的深度,充分發掘DNN模型的特性,提升模型準確率。
編碼器
一、Transformer
1、結構圖
(1)首先將這個模型看成是一個黑箱操作。在機器翻譯中,就是輸入一種語言,輸出另一種語言。
(2)黑箱由編碼組件、解碼組件和它們之間的連接組成。
(3)編碼組件部分由一堆編碼器(encoder)構成(論文中是將6個編碼器疊在一起——數字6沒有什么神奇之處,你也可以嘗試其他數字)。解碼組件部分也是由相同數量(與編碼器對應)的解碼器(decoder)組成的。
(4)進一步對編碼器進行分解。所有的編碼器在結構上都是相同的,但它們沒有共享參數。每個解碼器都可以分解成兩個子層。從編碼器輸入的句子首先會經過一個自注意力(self-attention)層,這層幫助編碼器在對每個單詞編碼時關注輸入句子的其他單詞。
自注意力層的輸出會傳遞到前饋(feed forward neural network)神經網絡中。每個位置的單詞對應的前饋神經網絡都完全一樣(譯注:另一種解讀就是一層窗口為一個單詞的一維卷積神經網絡)。
(5)進一步對解碼器進行分解。解碼器中也有編碼器的自注意力(self-attention)層和前饋(feed-forward)層。除此之外,這兩個層之間還有一個注意力層,用來關注輸入句子的相關部分(和seq2seq模型的注意力作用相似)。
2、將張量引入模型結構
我們已經了解了模型的主要部分,接下來我們看一下各種向量或張量(譯注:張量概念是矢量概念的推廣,可以簡單理解矢量是一階張量、矩陣是二階張量。)是怎樣在模型的不同部分中,將輸入轉化為輸出的。
(1)首先將每個輸入單詞通過詞嵌入算法轉換為詞向量。每個單詞都被嵌入為512維的向量,我們用這些簡單的方框來表示這些向量。
詞嵌入過程只發生在最底層的編碼器中。所有的編碼器都有一個相同的特點,即它們接收一個向量列表,列表中的每個向量大小為512維。在底層(最開始)編碼器中它就是詞向量,但是在其他編碼器中,它就是下一層編碼器的輸出(也是一個向量列表)。向量列表大小是我們可以設置的超參數——一般是我們訓練集中最長句子的長度。
(2)將輸入序列進行詞嵌入之后,每個單詞都會流經編碼器中的兩個子層。在這里輸入序列中每個位置的單詞都有自己獨特的路徑流入編碼器。在自注意力層中,這些路徑之間存在依賴關系。而前饋(feed-forward)層沒有這些依賴關系。因此在前饋(feed-forward)層時可以并行執行各種路徑。
3、多個編碼器結構
如上述已經提到的,一個編碼器接收向量列表作為輸入,接著將向量列表中的向量傳遞到自注意力層進行處理,然后傳遞到前饋神經網絡層中,將輸出結果傳遞到下一個編碼器中。輸入序列的每個單詞都經過自編碼過程。然后,他們各自通過前向傳播神經網絡(這個過程可以并行)——完全相同的網絡,而每個向量都分別通過它。
二、自注意力機制(seft-attention)
1、從宏觀視角看自注意力機制
例如,下列句子是我們想要翻譯的輸入句子:The animal didn’t cross the street because it was too tired.
- 當模型處理這個單詞“it”的時候,自注意力機制會允許“it”與“animal”建立聯系。
- 隨著模型處理輸入序列的每個單詞,自注意力會關注整個輸入序列的所有單詞,幫助模型對本單詞更好地進行編碼。
- RNN維持隱藏層的處理方法,是將它已經處理過的前面的所有單詞/向量的表示與它正在處理的當前單詞/向量結合起來。而自注意力機制會將所有相關單詞的理解融入到正在處理的單詞中。
2、seft-attention原理
(1)從每個編碼器的輸入向量(每個單詞的詞向量)中生成三個向量。
也就是說對于每個單詞,我們創造一個查詢向量、一個鍵向量和一個值向量。這三個向量是通過詞嵌入與三個權重矩陣后相乘創建的。
可以發現這些新向量在維度上比詞嵌入向量更低。他們的維度是64,而詞嵌入和編碼器的輸入/輸出向量的維度是512。但實際上不強求維度更小,這只是一種基于架構上的選擇,它可以使多頭注意力(multiheaded attention)的大部分計算保持不變。
(2)計算每個詞與Thinking得分
假設計算第一個詞“Thinking”的自注意力向量,需要拿輸入句子中的每個單詞對“Thinking”打分。這些分數決定了在編碼單詞“Thinking”的過程中有多重視句子的其它部分。
這些分數是通過打分單詞(所有輸入句子的單詞)的鍵向量與“Thinking”的查詢向量相點積來計算的。所以如果我們是處理位置最靠前的詞的自注意力的話,第一個分數是q1和k1的點積,第二個分數是q1和k2的點積。
(3)將分數除以8
8是論文中使用的鍵向量的維數64的平方根,這會讓梯度更穩定。這里也可以使用其它值,8只是默認值
(4)softmax歸一化
然后通過softmax傳遞結果。softmax的作用是使所有單詞的分數歸一化,得到的分數都是正值且和為1。
(5)值向量與softmax分數相乘
將每個值向量乘以softmax分數(這是為了準備之后將它們求和)。得到每個詞的甲醛值向量。這里的直覺是希望關注語義上相關的單詞,并弱化不相關的單詞(例如,讓它們乘以0.001這樣的小數)。
(6)對加權值向量求和
自注意力的另一種解釋就是在編碼某個單詞時,就是將所有單詞的表示(值向量)進行加權求和,而權重是通過該詞的表示(鍵向量)與被編碼詞表示(查詢向量)的點積并通過softmax得到。然后即得到自注意力層在該位置的輸出(Thinking).
自注意力的矩陣表示
3、“多頭”注意力機制
“多頭”注意機制下,我們為每個頭保持獨立的查詢/鍵/值權重矩陣,從而產生不同的查詢/鍵/值矩陣。和之前一樣,我們拿X乘以WQ/WK/WV矩陣來產生查詢/鍵/值矩陣。經過八次不同的權重矩陣運算,會得到八個不同的Z矩陣。自注意力的輸出只有一個Z。所以引入權重矩陣W。
(1)將多個注意力頭進行矩陣拼接
(2)拼接后乘以權重矩陣W。得到與輸入矩陣X相同維度的輸出矩陣Z
(3)Z融合所有注意力頭信息,作為注意力的輸出,傳入到前饋神經網絡
多個注意力頭的矩陣形式:
三、輸入詞向量引入位置編碼
為了讓模型理解單詞的順序。除了詞嵌入向量,Transformer為每個詞嵌入增加了位置向量,位置向量采用余弦、正弦函數對句子進行編碼得到。
如果假設詞嵌入的維數為4,則實際的位置編碼如下:
如,20字(行)的位置編碼,詞嵌入大小為512(列),位置編碼的顏色表示如下圖。每行包含512個值,每個值介于-1到1之間。他們從中間分裂成涼拌,第一行有250個0,256個1。這是因為左半部分的值有正弦函數生產,右半部分由余弦函數生產,將他們拼接在一起得到每一個位置向量編碼。
四、殘差
編碼器架構中的細節:在每個編碼器中的每個子層(自注意力、前饋網絡)的周圍都有一個殘差連接,并且都跟隨著一個“層-歸一化”步驟。
進一步展開求和與歸一化層:
解碼器
頂端編碼器的輸出之后會變轉化為一個包含向量K(鍵向量)和V(值向量)的注意力向量集 。這些向量將被每個解碼器用于自身的“編碼-解碼注意力層”,而這些層可以幫助解碼器關注輸入序列哪些位置合適:
模型訓練
1、解碼器輸入
模型的輸出詞表在訓練治安的預處理流程中就被設定了。使用一個相同狂賭的向量表示詞表中的每一個單詞(one-hot編碼)。
2、模型輸出
這個模型一次只產生一個輸出,假設模型只選擇概率最高的單詞,并把剩下的詞拋棄(貪婪編碼)。在一個足夠大的訓練集上充分訓練后,模型輸出的概率分布:
損失函數
一個簡單的例子——把“merci”翻譯為“thanks”。
1、模型的參數(權重)隨機初始化生成
2、(未經訓練的)模型產生的概率分布在每個單詞的詞向量單元格里都賦予了隨機的數值。
3、用真實的輸出與預測數據進行交叉熵損失計算。
4、用反向傳播算法調整所以模型參數權重
5、參數不斷迭代,生產更接近結果的輸出。
參考文獻:
1、The Illustrated Transformer:https://jalammar.github.io/illustrated-transformer/
2、圖解Transformer(完整版):https://blog.csdn.net/longxinchen_ml/article/details/86533005
總結
以上是生活随笔為你收集整理的【NLP】Transformer详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: The Annotated Transf
- 下一篇: 【机器翻译】transformer