Attention機制之Transformer

Attention機制 – Transformer

0. 代碼

聊聊 Transformer

基於代碼的運算順序理解Transformer

The Annotated Transformer

Bert-pytorch裏面的實現

1. Scaled Dot-product Attention

上圖表示的計算流程如下:

  • 首先,Query向量與Key相乘進行點積操作(MatMul),即Attention機制中的score函數。

  • 爲防止結果過大,然後對結果除以dk\sqrt{d_k},其中dkd_k表示Query向量的某一維度,從而防止梯度爆炸。(Scale)

  • 由於輸入的句子長短不同,需要進行padding操作,以統一句子長度,此外爲了避免補齊的數據會影響我們Attention的計算,因此需要將補齊的數據設置爲負無窮,這樣經過後面的softmax後接近於0,這樣就不會對結果產生影響了。

  • 然後通過SoftMax對上述結果進行歸一化。(SoftMax)

  • 最後對結果加權求和。(MatMul)

我們可以看到,這個依舊沿襲的是Attention的經典思想,不過在其中添加了一些操作Scale, Mask,這意味着對於Attention而言,其只有核心思想不變,適當的調整數據能夠獲得更好的結果,其公式如下:
Attention(Q,K,V)=softmax(QKTdk)V Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_k}})V
這裏解釋一下Scaled Dot-product Attention在本文中的應用,也稱爲self-attention的原因所在,這裏的Q,K,V都是同源的

2. Multi-head Attention

這裏的多頭注意力指的是同時使用多個(h=8)注意力,對於每個注意力,使用的V,K,Q是相同的,V,K,Q分別經過Linear層,然後將結果輸入到Scaled Dot-Product Attention層,最後將8個注意力結果進行Concat操作,並通過一個Linear層計算出最後一個結果。

其中,每個注意力的Wv,Wk,WqW_v, W_k, W_q是不同的,而且都參與訓練。
headi=Attention(QWiQ,KWiK,VWiV)MultiHead(Q,K,V)=Concat(head1,...,headn)W  (n=8) head_i=Attention(QW_i^Q,KW_i^K,VW_i^V)\\ MultiHead(Q,K,V)=Concat(head_1,...,head_n)W\,\,(n=8)

3.殘差網絡,Normalization與feed-forward network

  • 首先,Encoder和Decoder有着大量的殘差網絡,殘差網絡可以彌補深層網絡的信息損失。

  • 其次,有一個Layer Normalization過程。

  • 然後,數據經過一個前饋神經網絡,該前饋神經網絡採用了兩個線性變換,激活函數爲Relu,如下

FFN(x)=Relu(xW1+b1)W2+b2 FFN(x)=Relu(xW_1+b_1)W_2+b_2

4. Transformer中使用Multi-head Attention的細節

Transformer中使用多頭注意力機制需要注意一下幾點:

  • 在Encoder和Decoder中的黑色框中,採用的Self-attention,即Q,K,V是同源的。
  • 只有在Decoder中的Multi-head中才使用Sequencing Mask操作,而在Encoder中不使用Sequencing Mask操作,這是因爲在預測第t時刻的詞時,只能知道它之前時刻的信息,不能知道它以後的信息,因此需要將t時刻以及之後的詞遮住,只對前面的詞進行self-attention,這點不理解的話可以回想一下Sequence-to-Sequence那篇文章中對機器翻譯的訓練過程
  • 在黃色框中,Q來自Decoder層,K, V來自Encoder的輸出
    在這裏插入圖片描述
    如圖,在self-attention中,K Q V向量都是通過輸出的詞向量X產生的,即
    K=XWK,Q=XWQ,V=XWV K=X*W_K,Q=X*W_Q,V=X*W_V
    這裏爲了使decoder獲取encoder的信息,Q向量的產生用Decoder上層的輸出X進行計算:Q=XWQQ=X*W_Q,但K V向量由Encoder的輸出向量M(即attention vector)產生:K=MWK,V=MWVK=M*W_K,V=M*W_V

5. Positional encoding 淺談 Transformer-based 模型中的位置表示

由於self-attention捕捉不到句子中單詞的位置信息,因此Transformer添加Positional encoding進行彌補。論文中採用了正餘弦函數的方式,本質核心思想是:通過藉助位置的編碼公式(在偶數位置,使用正弦編碼,在奇數位置,使用餘弦編碼),讓模型學習到相對位置的信息
PE(pos,2i)=sin(pos/100002i/dmodel)PE(pos,2i)=cos(pos/100002i/dmodel) PE(pos, 2i)=sin(pos/10000^{{2i}/{d_{model}}})\\ PE(pos, 2i)=cos(pos/10000^{{2i}/{d_{model}}})
其中,pos指的是token的位置。設句子的長度爲L,那麼pos=0,1…L-1,i是向量的某一維度,例如dmodeld_{model}=512時,i=0,1,…255。

通過上式,我們可以得出:
PE(pos+k,2i)=PE(pos,2i)PE(k,2i+1)+PE(pos,2i+1)PE(k,2i)PE(pos+k,2i+1)=PE(pos,2i+1)PE(k,2i+1)PE(pos,2i)PE(k,2i) PE(pos+k,2i)=PE(pos,2i)*PE(k,2i+1)+PE(pos,2i+1)*PE(k,2i)\\ PE(pos+k,2i+1)=PE(pos,2i+1)*PE(k,2i+1)-PE(pos,2i)*PE(k,2i)
如此獲得的position embedding,兩者之間的點積能夠反映相對距離。

計算實例:
在這裏插入圖片描述

不同位置的詞得到的position embedding不一樣,從而區分出不同詞的位置。同時position embedding好像是可以隨着訓練調整的
在這裏插入圖片描述
我們可以用過兩個向量的點積來判斷它們之間的關係,如上圖,距離越近的兩個詞對應的詞向量點積值越大。

參考Self-Attention與Transformer:第60分鐘視頻講解

6.最後的Linear和softmax

在最後一層加一個前饋神經網絡來增加模型的泛化能力,最後用一個softmax來進行預測,如下圖,即對logits(元素取值可能爲負的,也可能超過1)進行歸一化,得到log_probs(元素取值爲0-1,且元素之和爲1).
在這裏插入圖片描述

7. 訓練小技巧

如下圖:
在這裏插入圖片描述

  • label smothing是爲了防止over fitting

    具體例子,如
    在這裏插入圖片描述

    對於位置1,target爲[0 0 1 0 0 0],比如我們覺得“I”對應位置取0.9就可以了,那麼其它位置就取(1-0.9)/5=0.02,所以經過平滑以後變爲[0.02 0.02 0.9 0.02 0.02]

  • norm learning rate schedule

    如圖,前5000步爲預熱階段,學習率從0開始線性增長,達到最大值0.0014後,開始指數衰減。

迴歸到整體

  • Encoder是由一個Stack組成,Stack中有6個相同的Layer,每個Layer的結構如圖3所示。
  • Decoder同樣由一個Stack組成,Stack中有6個相同的Layer,但是與Encoder中的Layer不同,主要是多了一個將Encoder輸出引入的Multi-Head機制,如圖3所示。
  • 使用的是交叉熵損失函數。

Reference

[1] The Illustrated Transformer
[2] 老宋的倉庫

QA

1. Mask三連問

mask操作是什麼?

mask是對某些值進行掩蓋,使得其在參數更新時不產生效果

它是怎麼做?

把需要被遮住的部分設置爲負無窮,然後經過softmax以後這些位置對應的概率就會變成接近於0,這樣就不會對結果產生影響了

爲什麼要mask?

Transformer中的mask分爲兩種:

  • Padding mask:考慮到每個批次中輸入序列的長度是不一樣的,而往往我們要先進行對其,對不足長度的文本進行 padding, 而這些padding 的詞其實是沒有意義的, 因此我們在做 Self-attention 的時候應該忽略它。

  • Sequence mask:在Decoder中,其不應該看到未來的信息,即對一個序列,當位於第t個時間步時,Decoder的輸出應該之和t時刻之前的輸入有關,而不應該依賴於t時刻之後的輸入。

具體做法是,產生一個上三角矩陣,上三角的值全爲1,下三角的值全爲0,對角線也是0。

2. Scaled Dot-Product Attention中的Scaled是啥,有啥用?

Scaled就是縮放數據

  • 比較大的輸入會使得sfotmax的梯度(梯度不是導數嗎?導數不是固定的嗎?指的應該是損失吧?)變得很小,當數量級較大時,softmax將幾乎全部的概率分佈都分配給了最大值對應的標籤,此時梯度消失爲0,參數更新會變得困難
  • 假設Q,K的各個分量是相互獨立的隨機變量,均值爲0,方差爲1,那麼點積QK的均值爲0,方差爲dkd_k方差越大,說明點積的數量級越大,通過除以dk\sqrt{d_k}將方差穩定到1,可以有效的控制前面提到的梯度消失問題。

3. 爲什麼Position embedding 採用正餘弦函數?

因爲有:
PE(pos+k)=PE(pos)+PE(k) PE(pos+k)=PE(pos)+PE(k)
這樣使得模型可以記住相對位置信息。但是還是沒有用,見 淺談 Transformer-based 模型中的位置表示

4. 爲什麼在激活函數前加Layer normalization?

Normalization 有很多種,但是它們都有一個共同的目的,那就是把輸入轉化成均值爲 0 方差爲 1 的數據。我們在把數據送入激活函數之前進行 normalization(歸一化),因爲我們不希望輸入數據落在激活函數的飽和區。常見的有BN與LN,這裏採用的是LN,,如下所示:
在這裏插入圖片描述

u是樣本均值,σ\sigma是樣本方差,當g=1,b=0時,樣本數據的均值就變爲0,方差變爲1,然後這種情況可能不是最好的,比如b=0.5更加合適等,於是就多設兩個參數g和b讓網絡自動去學習該參數值。

同時Batch Normalization的效果與batch的大小具有強相關,而LN只關注每條樣本自己。

5. RNN到Attention

RNN存在梯度消失或者梯度爆炸的問題,LSTM或者GRU只是一定程度上緩解了這個問題。

6. Decoder細節

  • Decoder中除了使用Multi-head attention外,還是用了Encoder-Decoder Attention
    在這裏插入圖片描述
  • Decoder向Encoder傳輸了Attention Vector(即K,V向量)
    在這裏插入圖片描述
    同時需要注意Previous Outputs是指第t-1時刻Decoder的輸出,即已經預測到的單詞,作爲下一時刻t的輸入,與經典的SeqtoSeq模型一樣,只是SeqtoSeq的特徵抽取器一般使用的是RNN。

7. 爲什麼使用殘差網絡?

因爲通過梯度下降求得誤差向後傳播,隨着網絡加深損失傳播越來越弱。通過連接殘差網絡(跳躍某些層進行連接),可以使得有多條路徑到達相對底層的網絡,緩解損失傳播越來越弱的問題。

8. Transformer的優點與缺點

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章