關於Transformer模型中的各種細節詳解


概述

Transformer是2017年的一篇論文《Attention is All You Need》提出的一種模型架構,這篇論文里只針對機器翻譯這一種場景做了實驗,全面擊敗了當時的機器翻譯各個benchmark(基准)上的SOTA。其優點除了效果好之外,由於encoder端是並行計算的,訓練的時間也被大大縮短了

它開創性的思想,顛覆了以往序列建模和RNN划等號的思路,現在被廣泛應用於NLP的各個領域。目前在NLP各業務全面開花的語言模型如GPT, BERT等,都是基於Transformer模型的。因此弄清楚Transformer模型內部的每一個細節就顯得尤為重要。

鑒於寫Transformer的中英文各類文章非常之多,一些重復的、淺顯的東西在本文里都不再贅述。在本文中,我會盡可能地去找一些很核心也很細節的點去剖析,並且將細節和整體的作用聯系起來解釋

本文盡量做到深入淺出,力求覆蓋我自己學習時的每一個困惑,做到“知其然,且知其所以然”。我相信通過我抽絲剝繭的分析,大家會對Transformer每個部分的作用有一個更加深入的認識,從而對這個模型架構整體的認知上升到一個新的台階,並且能夠深刻理解Transformer及其延伸工作的動機。

Transformer中的各個細節

Transformer整體架構

image

Attention的背景溯源:為什么要有attention?

想要深度理解Attention機制,就需要了解一下它產生的背景在哪類問題下產生,以及最初是為了解決什么問題而產生
首先回顧一下機器翻譯領域的模型演進歷史。機器翻譯是從RNN開始跨入神經網絡機器翻譯時代的,幾個比較重要的階段分別是: Simple RNN, Contextualize RNN, Contextualized RNN with attention, Transformer(2017),下面來一一介紹。

  • Simple RNN:這個encoder-decoder模型結構中,encoder將整個源端序列(不論長度)壓縮成一個向量(encoder output),源端信息和decoder之間唯一的聯系只是: encoder output會作為decoder的initial states的輸入。這樣帶來一個顯而易見的問題就是,隨着decoder長度的增加,encoder output的信息會衰減
    image
    這種模型有2個主要的問題:

    • 源端序列不論長短,都被統一壓縮成一個固定維度的向量,並且顯而易見的是這個向量中包含的信息中,關於源端序列末尾的token的信息更多,而如果序列很長,最終可能基本上“遺忘”了序列開頭的token的信息
    • 第二個問題同樣由RNN的特性造成: 隨着decoder timestep的信息的增加,initial hidden states中包含的encoder output相關信息也會衰減,decoder會逐漸“遺忘”源端序列的信息,而更多地關注目標序列中在該timestep之前的token的信息
  • Contextualized RNN:為了解決上述第二個問題,即encoder output隨着decoder timestep增加而信息衰減的問題,有人提出了一種加了context的RNN sequence to sequence模型:decoder在每個timestep的input上都會加上一個context。為了方便理解,我們可以把這看作是encoded source sentence。這樣就可以在decoder的每一步,都把源端的整個句子的信息和target端當前的token一起輸入到RNN中,防止源端的context信息隨着timestep的增長而衰減
    image
    但是這樣依然有一個問題: context對於每個timestep都是靜態的(encoder端的final hidden states,或者是所有timestep的output的平均值)。但是每個decoder端的token在解碼時用到的context真的應該是一樣的嗎?在這樣的背景下,基於Attention的方法就應運而生了。

  • Contextualized RNN with soft align (Attention) : Attention在機器翻譯領域的應用,最早的提出來自於2014年的一篇論文 Neural Machine Translation by Jointly Learning to Align and Translate
    image
    在每個timestep,輸入到decoder RNN結構中之前,會用當前的輸入token的vector與encoder output中的每一個position的vector作一個"attention"操作,這個"attention"操作的目的就是計算當前token與每個position之間的"相關度",從而決定每個position的vector在最終該timestep的context中占的比重有多少。最終的context即encoder output每個位置vector表達的加權平均。
    image

Attention的細節:attention是什么?

上面這一章節講了attention機制的歷史,幫助讀者更加清楚地理解attention的作用,下面我們就來展開講講attention的細節.

點積attention

我們來介紹一下attention的具體計算方式。attention可以有很多種計算方式: 加性attention、點積attention,還有帶參數的計算方式。我着重介紹一下點積attention的公式,這也是Transformer模型中所使用的attention公式:
image

一個小問題,為什么有縮放因子\(\frac{1}{\sqrt{d_k}}\)?

  • 先一句話回答這個問題: 縮放因子的作用是歸一化
  • 假設\(Q,K\)里的元素的均值為0,方差為1,那么\(A=QK^T\)中元素的均值為0,方差為d. 當d變得很大時,\(A\)中的元素的方差也會變得很大,如果\(A\)中的元素方差很大,那么\(softmax(A)\)的分布會趨於陡峭(分布的方差大,分布集中在絕對值大的區域)。

總結一下就是\(softmax(A)\)的分布會和d有關。因此\(A\)中每一個元素乘上\(\frac{1}{\sqrt{d_k}}\)后,方差又變為1。這使得\(softmax(A)\)的分布“陡峭”程度與d解耦,從而使得訓練過程中梯度值保持穩定

Attention機制涉及到的參數

一個完整的attention層涉及到的參數有:

  • \(q,k,v\)分別映射到\(Q,K,V\)的線性變換矩陣\(W^Q(d_{model}*d_k),W^K(d_{model}*d_k),W^V(d_{model}*d_v)\)
  • 把輸出的表達\(O\)映射為最終輸出\(o\)的線性變換矩陣\(W^O(d_v*d_{model})\)

Query, Key, Value

Query和Key作用得到的attention權值會作用到Value上。因此它們之間的關系是:

  • \(Query(M*d_k)\)\(Key(N*d_k)\)的維度必須一致,\(Value(N*d_v)\)和Query/Key的維度可以不一致。
  • \(Key(N*d_k)\)\(Value(N*d_v)\)的長度必須一致。Key和Value本質上對應了同一個Sequence在不同空間的表達
  • Attention得到的Output\(M*d_v\)的維度和Value的維度一致,長度和Query一致。
  • Output每個位置 i 是由value的所有位置的vector加權平均之后的向量;而其權值是由位置為i 的query和key的所有位置經過attention計算得到的 ,權值的個數等於key/value的長度。
    image

在經典的Transformer模型中,我們記線性映射之前的Query, Key, Value為q, k, v,映射之后為Q, K, V。那么:

  • self-attention的q, k, v都是同一個輸入, 即當前序列由上一層輸出的高維表達
  • cross-attention(encoder-decoder-attention)的q代表當前序列,k,v是同一個輸入,對應的是被編碼的序列,也即encoder最后一層的輸出結果(對decoder端的每一層來說,k和v保持不變)

而每一層線性映射參數矩陣都是獨立的,所以經過映射后的Q, K, V各不相同,模型參數優化的目標在於將q, k, v被映射到新的高維空間,使得每層的Q, K, V在不同抽象層面上捕獲到q, k, v之間的關系一般來說,底層layer捕獲到的更多是lexical-level的關系,而高層layer捕獲到的更多是semantic-level的關系

Attention的作用

下面這段我會以機器翻譯為例,用通俗的語言闡釋一下attention的作用,以及query, key, value的含義。
image
query對應的是需要被表達的序列(稱為序列A),key和value對應的是用來表達A的序列(稱為序列B)。其中key和query是在同一高維空間中的(否則無法用來計算相似程度),value不必在同一高維空間中,最終生成的output和value在同一高維空間中。
-Encoder部分中只存在self-attention,而Decoder部分中存在self-attention和cross-attention(encoder-decoder-attention).

  • encoder中的self-attention的query, key, value都對應了源端序列(即A和B是同一序列),decoder中的self-attention的query, key, value都對應了目標端序列。
  • decoder中的cross-attention的query對應了目標端序列,key, value對應了源端序列(每一層中的cross-attention用的都是encoder的最終輸出)

多頭Attention(Multi-head Attention)

Attention是將query和key映射到同一高維空間中去計算相似度,而對應的multi-head attention把query和key映射到高維空間\(\alpha\)的不同子空間\((\alpha_1,\alpha_2,...,\alpha_h)\)中去計算相似度。

為什么要做multi-head attention?論文原文里是這么說的:

Multi-head attention allows the model to jointly attend to information from different representation subspaces at different positions. With a single attention head, averaging inhibits this.

也就是說,這樣可以在不改變參數量的情況下增強每一層attention的表現力

Multi-head Attention的本質是,在參數總量保持不變的情況下,將同樣的query, key, value映射到原來的高維空間的不同子空間中進行attention的計算,在最后一步再合並不同子空間中的attention信息。

  • 這樣降低了計算每個head的attention時每個向量的維度,在某種意義上防止了過擬合;
  • 由於Attention在不同子空間中有不同的分布,Multi-head Attention實際上是尋找了序列之間不同角度的關聯關系,並在最后concat這一步驟中,將不同子空間中捕獲到的關聯關系再綜合起來。

從上圖可以看出,\(q_i\)\(k_j\)之間的attention score從1個變成了h個,這就對應了h個子空間中它們的關聯度

Attention層的公式

image
如上是Transformer中Attention層的完整公式。在經過並行的多個head的q,k,v計算后,它們的結果被拼接在一起,再經過\(W^O\)的線性映射,得到最終的結果。

Decoder端的Mask

Transformer模型屬於自回歸模型,也就是說后面的token的推斷是基於前面的token的Decoder端的Mask的功能是為了保證訓練階段和推理階段的一致性
論文原文中關於這一點的段落如下:

We also modify the self-attention sub-layer in the decoder stack to prevent from attending to subsequent(隨后的) positions. This masking, combined with the fact that the output embeddings are offset by one position, ensures that the predictions for position i can depend only on the known outputs at positions less than i.

在推理階段,token是按照從左往右的順序推理的。也就是說,在推理timestep=T的token時,decoder只能“看到”timestep < T的 T-1 個Token, 不能和timestep大於它自身的token做attention(因為根本還不知道后面的token是什么)。為了保證訓練時和推理時的一致性,所以,訓練時要同樣防止token與它之后的token去做attention

Transformer模型架構中的其他部分

除了最有特色的Attention層之外,Transformer還應用了一些之前的技術,比如Layer NormalizationResidual Connection,還有為了在並行編碼同時捕獲位置信息的Positional Embedding。在這個部分中,我會深入細節進行介紹。

Layer Normalization

在每個block中,最后出現的是Layer Normalization。Layer Normalization是一個通用的技術,其本質是規范優化空間,加速收斂

當我們使用梯度下降法做優化時,隨着網絡深度的增加,數據的分布會不斷發生變化,假設feature只有二維,那么用示意圖來表示一下就是:
image
為了保證數據特征分布的穩定性(如左圖),我們加入Layer Normalization,這樣可以加速模型的優化速度

Feed Forward Network

每一層經過attention之后,還會有一個FFN,這個FFN的作用就是空間變換FFN包含了2層linear transformation層,中間的激活函數是ReLu

公式是:image

一個問題:attention層的output最后會和\(W^O\)相乘,為什么這里又要增加一個2層的FFN網絡?

其實,FFN的加入引入了非線性(ReLu激活函數),變換了attention output的空間, 從而增加了模型的表現能力。把FFN去掉模型也是可以用的,但是效果差了很多。

Positional Encoding

位置編碼層只在encoder端和decoder端的embedding之后,第一個block之前出現,它非常重要,沒有這部分,Transformer模型就無法用。位置編碼是Transformer框架中特有的組成部分,補充了Attention機制本身不能捕捉位置信息的缺陷
image
Positional Embedding的成分直接疊加於Embedding之上,使得每個token的位置信息和它的語義信息(embedding)充分融合,並被傳遞到后續所有經過復雜變換的序列表達中去。

優勢1

不得不說,使用Positional Encoding作為每個token位置的唯一表示,這一思路很NB,為什么呢?

模型輸入Encoder的每個token對應的向量有2部分:

  • Positional Encoding
  • Embedding Output

Transformer的特性使得encoder的輸入向量之間完全平等(不存在RNN那種recurrent結構),token的實際位置和positional encoding唯一綁定,我們可以通過對positional encoding進行操作來改變token在序列中的實際位置
image

對inference階段而言
下圖[b]中的輸入Embedding部分沒有變化,但是Positional Encoding部分被打亂了順序.下圖[c]中的Positional Encoding部分沒有變化,但是Embedding部分被打亂了順序.實際上[b][c]完全等價,因為在2種輸入中E1-P5, E2-P1, E3-P3, E4-P2, E5-P4這個對應關系恆定
image
image

對train階段而言(針對learned postional encoding的情況)
由於positional encoding是訓練出來的,那么它在inference階段代表哪個位置,完全由訓練時的實際位置決定.舉個例子,在decoder中,self-attention模塊是有mask的,目的是防止token與它之后的token去做attention,也就是left-to-right模型。如果這時我突然想要訓一個right-to-left的模型,那么做法1是在預處理階段將序列翻轉過來(比較簡單也比較容易想到);做法2是在訓練時將mask策略換一下
image
image
做法1和做法2訓練出來的positional encoding是等價的,有興趣可以看看XLNet是如何利用mask來實現Permuted Language Model的.

優勢2

論文中使用的Positional Encoding(PE)是正余弦函數,位置(pos)越小,波長越長,每一個位置對應的PE都是唯一的。同時作者也提到,之所以選用正余弦函數作為PE,是因為這可以使得模型學習到token之間的相對位置關系:因為對於任意的偏移量k, \(PE_{pos+k}\)可以由 \(PE_{pos}\)的線性表示
image
image


免責聲明!

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



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