學習的博客(在此致謝):
初識CV - Transformer模型詳解(圖解最完整版)
1 整體結構
Transformer由Encoder和Decoder組成,分別包含6個block。
Transformer的工作流程大體如下:
- 獲取每個單詞的embedding vector X X X, X X X由詞嵌入(word embedding)和位置編碼(Positional Encoding)得到。
- 將得到的單詞 X X X傳入Encoder中,經過6個Encoder block后可以得到句子所有單詞的編碼信息矩陣 C C C。單詞向量矩陣可以用 X n × d X_{n\times d} Xn×d?表示,其中 n n n為單詞數, d d d為向量維度(論文中為512)。每個Encoder block輸出的矩陣維度與輸入完全一致。
- 將 C C C傳遞到Decoder中,Decoder會根據翻譯過的單詞 1 , ? , i 1,\cdots,i 1,?,i翻譯單詞 i + 1 i+1 i+1。翻譯 i + 1 i+1 i+1時需要用mask蓋住 i + 2 , ? , n i+2,\cdots,n i+2,?,n。
2 Transformer的輸入
X X X由詞嵌入(word embedding)和位置編碼(Positional Encoding)得到。
2.1 詞嵌入
輸入的是一句話,比如:“我 愛 自然語言處理”,每個詞會被映射成一個向量,叫詞嵌入(word embedding)。
“我” → [0.2, 0.5, ..., -0.1] (一個 d_model 維的向量)
“愛” → [...]
“自然語言處理” → [...]
2.2 位置編碼
Transformer除了詞嵌入,還需要位置編碼(Positional Encoding, PE) 來表示單詞在句子中出現的位置。由于Transformer不采用RNN結構,而是使用全局信息,不能利用單詞的順序信息,而這部分信息對于NLP來說非常重要。 所以Transformer中使用位置編碼來保存單詞在序列中的相對/絕對位置。
Transformer中計算PE的公式如下:
PE ( pos , 2 i ) = sin ? ( pos / 10000 2 i / d ) \text{PE}_{(\text{pos},2i)}=\sin(\text{pos}/10000^{2i/d}) PE(pos,2i)?=sin(pos/100002i/d)
PE ( pos , 2 i + 1 ) = cos ? ( pos / 10000 2 i / d ) \text{PE}_{(\text{pos},2i+1)}=\cos(\text{pos}/10000^{2i/d}) PE(pos,2i+1)?=cos(pos/100002i/d)
其中, pos \text{pos} pos表示單詞在句子中的位置, d d d表示PE的維度(與詞嵌入的維度相同)。
對于每個位置 pos \text{pos} pos,我們計算 d d d維向量(其中一半維度是 sin ? \sin sin,另一半是 cos ? \cos cos)。所以每個位置的PE也是長度為 d d d的向量。
2.3 Transformer的輸入
有了詞嵌入 input_embedding \text{input\_embedding} input_embedding和位置編碼 positional_encoding \text{positional\_encoding} positional_encoding(即 PE \text{PE} PE),我們有
X = input_embedding + positional_encoding X=\text{input\_embedding}+\text{positional\_encoding} X=input_embedding+positional_encoding
為什么是相加而不是連接(concat)?
- 加法不增加維度,后面的模型結構無需改動。
- PE被視為微調詞語的表示,可以看作是在詞向量的基礎上“注入一點位置感知”。比如“I saw a cat.” 中的 “cat” 在句首或句尾含義不同,但你不需要讓兩個“cat”產生完全不同的表示,只需加一點“位置信息”做微調。
- Attention中的縮放點積更適合加法式表示。
- 原論文實驗驗證:加法的效果已經很好,因此選擇加法方案。
3 Self-Attention 自注意力機制
上圖為論文中Transformer的內部結構圖,左側為Encoder block,右側為Decoder block。紅色圈中的部分為Multi-Head Attention,由多個Self-Attention組成。
還可以發現,Encoder block包含一個Multi-Head Attention,而Decoder block包含兩個,其中一個用到了mask。
還可以發現,Multi-Head Attention上方還包括一個Add & Norm層,Add表示殘差鏈接(Redidual Connection),用于防止網絡退化;Norm表示Layer Normalization,用于對每一層的激活值進行歸一化。
3.1 Self-Attention結構
上圖為Self-Attention結構,計算時需要用到矩陣Q(Query, 查詢), K(Key, 鍵值), V(Value, 值)。Self-Attention接收的是輸入(第2章中的矩陣 X X X) 或者上一個Encoder block的輸出。
而Q,K,V正是通過Self-Attention的輸入進行線性變換得到的。
3.2 Q, K, V
已知 X ∈ R n × d X\in\mathbb{R}^{n\times d} X∈Rn×d。定義三個參數矩陣: W Q ∈ R d × d Q W_Q\in\mathbb{R}^{d\times d_Q} WQ?∈Rd×dQ?, W K ∈ R d × d K W_K\in\mathbb{R}^{d\times d_K} WK?∈Rd×dK?, W V ∈ R d × d V W_V\in\mathbb{R}^{d\times d_V} WV?∈Rd×dV?。對于每個輸入 X X X:
Q = X W Q , K = X W K , V = X W V Q=XW_Q,\ K=XW_K,\ V=XW_V Q=XWQ?,?K=XWK?,?V=XWV?
得到的矩陣: Q ∈ R n × d Q Q\in\mathbb{R}^{n\times d_Q} Q∈Rn×dQ?, K ∈ R n × d K K\in\mathbb{R}^{n\times d_K} K∈Rn×dK?, V ∈ R n × d V V\in\mathbb{R}^{n\times d_V} V∈Rn×dV?。通常, d Q , d K , d V d_Q,d_K,d_V dQ?,dK?,dV?是相同的。
在注意力機制中,每個詞會
- 用 Q Q Q詢問別的詞的 K K K,來判斷該關注誰;
- 用 V V V提供實際信息,如果我關注你,要拿到你的什么內容。
注意力公式如下:
Attention ( Q , K , V ) = softmax ( Q K ? d K ) V \text{Attention}(Q,K,V)=\text{softmax}(\frac{QK^\top}{\sqrt{d_K}})V Attention(Q,K,V)=softmax(dK??QK??)V
最后輸出的矩陣 Z ∈ R n × d V Z\in\mathbb{R}^{n\times d_V} Z∈Rn×dV?。
3.3 Multi-head Attention
假設 X X X經過QKV計算后得到 Z Z Z。上圖可以看出Multi-head Attention包含多個Self-Attention層。首先將輸入 X X X分別傳遞到 h h h個不同的Self-Attention中,計算得到 h h h個輸出矩陣 Z = [ Z 1 , ? , Z h ] Z=[Z_1,\cdots,Z_h] Z=[Z1?,?,Zh?]。Multi-head Attention將其連接(concat)起來,得到 Z ′ ∈ R n × ( h ? d K ) Z'\in\mathbb{R}^{n\times (h\cdot d_K)} Z′∈Rn×(h?dK?)。
最后再經過一層 R ( h ? d K ) × d \mathbb{R}^{(h\cdot d_K)\times d} R(h?dK?)×d的線性層,得到最終的輸出 Z ∈ R n × d Z\in\mathbb{R}^{n\times d} Z∈Rn×d,和輸入 X X X的維度相同。
4 Encoder
上圖紅色部分是Transformer的Encoder block結構,可以看到是由Multi-Head Attention, Add & Norm, Feed Forward, Add & Norm組成的。剛剛已經了解了Multi-Head Attention的計算過程,現在了解一下Add & Norm和Feed Forward部分。
4.1 Add & Norm
Add & Norm層由Add和Norm兩部分組成,其計算公式如下:
LayerNorm ( X + MultiHeadAttention ( X ) ) \text{LayerNorm}(X+\text{MultiHeadAttention}(X)) LayerNorm(X+MultiHeadAttention(X))
LayerNorm ( X + FeedForward ( X ) ) \text{LayerNorm}(X+\text{FeedForward}(X)) LayerNorm(X+FeedForward(X))
其中 X X X表示Multi-Head Attention或者Feed Forward的輸入,MultiHeadAttention(X)和 FeedForward(X) 表示輸出(輸出與輸入X維度是一樣的,所以可以相加)。
Add指X+MultiHeadAttention(X),是一種殘差連接,通常用于解決多層網絡訓練的問題,可以讓網絡只關注當前差異的部分,在 ResNet 中經常用到:
Norm指Layer Normalization,通常用于RNN結構,Layer Normalization會將每一層神經元的輸入都轉成均值方差都一樣的,這樣可以加快收斂。
4.2 Feed Forward
Feed Forward層比較簡單,是一個兩層的全連接層,第一層的激活函數為Relu,第二層不使用激活函數:
max ? ( 0 , X W 1 + b 1 ) W 2 + b 2 \max(0,XW_1+b_1)W_2+b_2 max(0,XW1?+b1?)W2?+b2?
X是輸入,Feed Forward最終得到的輸出矩陣的維度與X一致。
最后, X X X經過一連串Encoder得到編碼信息矩陣 C C C。
5 Decoder
上圖紅色部分為Transformer的Decoder block結構,與Encoder block相似,但是存在一些區別:
- 包含兩個Multi-Head Attention層。
- 第一個Multi-Head Attention層采用了Masked操作。
- 第二個Multi-Head Attention層的K, V矩陣使用Encoder的編碼信息矩陣 C C C進行計算,而Q使用上一個Decoder block的輸出計算。
- 最后有一個Softmax層計算下一個翻譯單詞的概率。
5.1 Masked Multi-Head Attention (1st)
Decoder block 的第一個Multi-Head Attention采用了Masked操作,因為在翻譯的過程中是順序翻譯的,即翻譯完第 i 個單詞,才可以翻譯第i+1個單詞。通過Masked操作可以防止第i個單詞知道i+1個單詞之后的信息。
下面的描述中使用了類似Teacher Forcing的概念。在 Decoder 的時候,是需要根據之前的翻譯,求解當前最有可能的翻譯,如下圖所示。首先根據輸入"Begin"預測出第一個單詞為 “I”,然后根據輸入"Begin I"預測下一個單詞 “have”。
**第一步:**是 Decoder 的輸入矩陣和 Mask 矩陣,輸入矩陣包含 “(begin) I have a cat” (0, 1, 2, 3, 4) 五個單詞的表示向量,Mask 是一個 5×5 的矩陣。在 Mask 可以發現單詞 0 只能使用單詞 0 的信息,而單詞 1 可以使用單詞 0, 1 的信息,即只能使用之前的信息。
第二步:接下來的操作和之前的 Self-Attention 一樣,通過輸入矩陣 X X X計算得到 Q , K , V Q,K,V Q,K,V矩陣。然后計算 Q Q Q和 K ? K^\top K?的乘積 Q K ? QK^\top QK?。
第三步:在得到 Q K ? QK^\top QK?之后需要進行 Softmax,計算 attention score,我們在 Softmax 之前需要使用Mask矩陣遮擋住每一個單詞之后的信息,遮擋操作如下:
得到Mask Q K ? QK^\top QK?之后在Mask Q K ? QK^\top QK?上進行Softmax,每一行的和都是1,但是單詞0在單詞1,2,3,4上的attention score都為0。
第四步:使用Mask Q K ? QK^\top QK?與矩陣 V V V相乘得到 Z Z Z,則單詞1的輸出向量 Z 1 Z_1 Z1?是只包含單詞1的信息的。
第五步:通過上述步驟就可以得到一個Masked Self-Attention的輸出矩陣 Z i Z_i Zi?,然后和Encoder類似,通過Multi-Head Attention拼接多個輸出 Z i Z_i Zi?,然后計算得到第一個Multi-Head Attention的輸出 Z Z Z, Z Z Z與輸入 X X X的維度相同。
5.2 Multi-Head Attention (2nd)
Decoder block 第二個 Multi-Head Attention 變化不大, 主要的區別在于其中 Self-Attention 的 K, V矩陣不是使用 上一個Decoder block的輸出計算的,而是使用Encoder 的編碼信息矩陣C計算的。
根據Encoder的輸出 C C C計算得到 K , V K, V K,V,根據上一個Decoder block的輸出 Z Z Z計算 Q Q Q (如果是第一個Decoder block則使用輸入矩陣 X 進行計算),后續的計算方法與之前描述的一致。
這樣做的好處是在Decoder的時候,每一位單詞都可以利用到Encoder所有單詞的信息 (這些信息無需Mask)。
5.3 Softmax預測輸出單詞
Decoder block 最后的部分是利用 Softmax 預測下一個單詞,在之前的網絡層我們可以得到一個最終的輸出 Z Z Z,因為 Mask 的存在,使得單詞0的輸出 Z 0 Z_0 Z0? 只包含單詞0的信息,如下:
Softmax 根據輸出矩陣的每一行預測下一個單詞:
這就是Decoder block的定義,與Encoder一樣,Decoder是由多個Decoder block組合而成。