感謝Jay Alammar,圖源自他的文章[17]。
文章目錄
1. Transformer原理
1.1 高層Transformer
Transformer最初是在機器翻譯中提出,所以我們以機器翻譯爲例。任何一個神經網絡模型都可以認爲是一個黑箱,Transformer也不例外。
再往裏面一層,Transformer是一個Encoder-Decoder結構,結構如下圖所示:
每一個Encoder是由self-attention+Feed Forward NN構成,如下圖所示,所以我們首先要理解self-attention。
每一個Decoder是由Self-Attention+Encoder-Decoder Attention+Feed Forward NN構成,結構如下圖所示:
1.2 Encoder輸入:
假設我們的輸入三個詞,三個詞通過Embedding層後,每個詞變成一個向量,如下圖所示:
除了最底層輸入是詞的Embedding,其他層的輸入是上一層的輸出。這三個詞在Encoder中的變換是:
Self-Attention是輸入的第一層NN,比較難理解,卻是模型的核心組成部分。所以我們單獨拿出來講。
2 Self-Attention:
關於注意力機制詳細可以看張俊林博士的文章[3],此處講解self-attention,更簡單易懂。
以機器翻譯爲例,假設我們的輸入是:
“The animal didn't cross the street because it was too tired
”
在翻譯的是時候我們希望將it
和The animal
聯繫起來,通過注意力機制可以實現這個需求。可以在Tensor2Tensor notebook 進行測試,觀察每個詞和其他詞的對應關係(連接權重)。
2.1 Self-Attention步驟:
- 將輸入詞轉變成詞向量,即得到Embedding層;
- 每個詞向量得到一個向量, 向量和向量(下面說如何得到);
- 爲每一個詞向量計算一個 ;
我們需要計算句子中的每一個詞對當前詞的。這個決定對句子的其他部分注意力是多少,也就是如何用句子的其他部分類表徵當前詞。
- 對進行歸一化(爲了穩定),即除以,然後對求:
- 和向量點積,然後對其求和:;
完結撒花,一圖以蔽之:
2.2 、、:
剛纔挖下的坑,現在來填。剛纔我們提到這三個向量但是沒有說如何得到的。
將我們的詞向量矩陣和權重矩陣相乘,即可得到、、向量。
接下來這張圖可以清晰的說明白、、三個向量的關係。
2.3 Multi-Head Attention:
- 將詞向量數據分別輸入到8個不同的Self-Attention中,得到8個特徵矩陣:
- 8個矩陣無法直接與前饋全連接相乘,所以對8個矩陣拼接,然後與一個權重矩陣相乘:
- 一圖總結:
Multi-Head Attention的優點:
- 擴展模型能力可以注意到不同位置,一個注意力模型的關注點也許是錯的,通過多個注意力模型可以提高這種泛化能力;
- 使得注意力層具有多個表示子空間,比如說上文的8個注意力模型,經過訓練後,我們就可以將輸入的詞嵌入映射到8個不同的表示子空間;
2.4 位置嵌入來表示序列的順序信息:
Transformer模型的一大缺點是不能捕捉句子的位置信息。試想我們的句子不管如何打亂,從剛纔的原理可以看出,Transformer的結果都是相同的。爲了解決這個問題,論文中在編碼詞向量時引入了位置編碼(Position Embedding),詞的位置信息通過位置編碼來表示。
論文中令位置嵌入的維度和詞向量的維度相同,然後與詞向量相加。位置嵌入,可以幫我們判斷每個詞的位置和詞向量之間的距離。
論文中的位置嵌入公式是:
以上便是Slef-Attention的全部內容。
3 殘差網絡(Residuals Network):
構成Transformer的Encoder除了上述部分還有殘差網絡和一層歸一化,通過圖可以更容易明白。
4. Keras實現:
4.1 自注意力機制:
2.1中詳細介紹的Self-Attention可以通過下列代碼實現。忘記的可以和前面的公式去對應。
class ScaledDotProductAttention():
def __init__(self, d_model, attn_dropout=0.1):
self.temper = np.sqrt(d_model)
self.dropout = Dropout(attn_dropout)
def __call__(self, q, k, v, mask):
attn = Lambda(lambda x:K.batch_dot(x[0],x[1],axes=[2,2])/self.temper)([q, k])
if mask is not None:
mmask = Lambda(lambda x:(-1e+10)*(1-x))(mask)
attn = Add()([attn, mmask])
attn = Activation('softmax')(attn)
attn = self.dropout(attn)
output = Lambda(lambda x:K.batch_dot(x[0], x[1]))([attn, v])
return output, attn
4.2 求位置嵌入向量:
詳細公式可以見2.4,以下爲keras實現:
def GetPosEncodingMatrix(max_len, d_emb):
pos_enc = np.array([
[pos / np.power(10000, 2 * (j // 2) / d_emb) for j in range(d_emb)]
if pos != 0 else np.zeros(d_emb)
for pos in range(max_len)
])
pos_enc[1:, 0::2] = np.sin(pos_enc[1:, 0::2]) # dim 2i
pos_enc[1:, 1::2] = np.cos(pos_enc[1:, 1::2]) # dim 2i+1
return pos_enc
未完待續…有空繼續更新
參考資料:
[1]AllenNLP 使用教程
[2]從Word Embedding到Bert模型—自然語言處理中的預訓練技術發展史
[3]深度學習中的注意力模型(2017版)
[4]模型彙總24 - 深度學習中Attention Mechanism詳細介紹:原理、分類及應用
[5]Tensorflow源碼解讀(一):Attention Seq2Seq模型
[6]基於Attention Model的Aspect level文本情感分類—用Python+Keras實現
[7]完全圖解RNN、RNN變體、Seq2Seq、Attention機制
[8]淺談Attention-based Model【原理篇】
[9] 淺談 NLP 中的 Attention 機制
[10]Deep Learning基礎–理解LSTM/RNN中的Attention機制
[11]Attention? Attention!
[12]詳解Transformer (Attention Is All You Need)
[13]The Annotated Transformer-Harvard出品
[14] 聊聊 Transformer
[15]Transformer Translation Model-TensorFlow官方實現
[16] BERT大火卻不懂Transformer?讀這一篇就夠了
[17] The Illustrated Transformer
[18] Visualizing A Neural Machine Translation Model (Mechanics of Seq2seq Models With Attention)
[19] Transformer註解及PyTorch實現(上)