self-attention與transformer講解
論文:attention is all you need.
參考
文章目錄
1 self-attention具體
self-attention即K=V=Q。例如輸入一個句子,那麼裏面的每個詞都要和該句子中所有的詞進行Attention計算。目的是學習句子內部的詞依賴關係,捕獲句子的內部結構。
1.1 過程
- 從每個endoer的輸入向量創建三個向量
- 對每個單詞,創建query, key, value。這些向量通過講embedding * 訓練得到的矩陣而來。
大部分的NLP中,Key和Value常常是同一個,即Key=Value。
- 新向量維度比embdding小,維度爲64。這是一種架構選擇,可以使multi-head attention計算大部分保持不變。
- query, key, value與計算分數
- 評分是通過query向量與評分的單詞的key向量的點擊來計算。
位置1單詞的的分數就是dot(q1,k1), 第二個分數是dot(q1,k2)
-
將分數/8(論文中是key向量的維數(dk)的平方根,也就是sqrt(64))
爲了得到更穩定的梯度。
-
softmax傳遞操作結果。
標準化,和爲1.決定了每個單詞在這個位置的表達量,很明顯這個位置的單詞有最高的softmax分數,但有時關注與當前單詞相關的另一個單詞是有用的。
-
每個value向量 * softmax分數
保持想要關注的詞不變,去掉無關單詞。
-
加權求和value向量。
將在此位置生成self-attention層的輸出
得到的向量是可以發送到feed forward network的向量。實際中是用矩陣形式進行的,所以看看矩陣形式的self-attention。
1.2 矩陣的self-attention
過程:
- 計算query, key, value矩陣。
將embedding打包到矩陣X中,並乘以訓練過的權重矩陣(WQ, WK, WV)。
X矩陣中的每一行對應於輸入句子中的一個單詞。
- 濃縮步驟2-6
1.3 Scaled Dot-Product Attention
以上過程中的:使用點積進行相似度計算的Attention就是Scaled Dot-Product Attention。只是多除了一個sqrt(dk)來起到調節作用,值得內積不至於太大。
2 transformer結構
總結:
- 編碼器和解碼器都使用了多頭注意力機制(Multi-Head Attention)來學習文本的表示, 特別的這裏Q=K=V,是自注意力機制(self-attention).
- 利用編碼器和解碼器Attention來進行翻譯對齊,編碼器輸出的K和V以及解碼器的輸入Q作爲Multi-Head Attention的輸入
- 使用Positional Encoding來引入位置信息
- Masked Multi-Head Attention採用0-1mask消除右側單詞對當前單詞的影響
- 殘差網絡連接和規範化(Add & Norm)使得深度網絡更優化
2.1 Encoder與Multi-headed Attention
提高:
- 拓展了模型聚焦不同位置的能力。
- 賦予attention層多個“表示子空間”。
①有多個query\key\value權重矩陣集(transformer使用8個注意頭,因此最終爲每個encoder/decoder提供8個注意頭集)
②每個集合都是隨機初始化的。
③經過訓練,每個集合用於將輸入embeddings (or來自較低encoder/decoder的向量)投影到不同的表示子空間中。
2.1.1 multi-headed具體
在多頭 attention的情況下,我們對每個頭保持獨立的Q/K/V權重矩陣,從而得到不同的Q/K/V矩陣。和之前一樣,我們用X乘以WQ/WK/WV矩陣得到Q/K/V矩陣。
也是就:Queries, Keys, Values。
如果做上面列出的同樣的self-attention計算,只是8次不同的加權矩陣,能得到8個不同的Z矩陣。
說的attention heads也就是產生的不同的Z矩陣。
前饋層不需要8個矩陣——它只需要一個矩陣(每個單詞對應一個向量)。所以我們需要一種方法把這8個壓縮成一個矩陣。
矩陣簡化
- concatenate all the attention heads
- 乘以一個額外的權值矩陣W0。
- 得到結果Z矩陣,它能從所有attention heads裏捕獲到信息,從而把這個句子餵給FFNN
以上就是multi-headed self-attention。
以上過程:
如果可視化multi-headed,可以看到模型對target詞的表達,在其他source word的一些表達中都有體現。
2.1.2 Positional Encoding 使用位置編碼表示序列的順序
目前爲止,我們所描述的模型缺少的一件事是解釋輸入序列中單詞順序的方法。
transformer向每個輸入的embedding添加一個向量——positional encoding。這些向量遵循模型學習的特定模式,這有助於確定每個單詞的位置,或序列中不同單詞之間的距離。
這裏的直覺是,將這些值添加到embedding中,在embedding向量被投影到Q/K/V向量和點積attention期間,它們之間提供了有意義的距離。
如果我們假設embedding的維數是4,那麼實際的位置編碼應該是這樣的:
位置編碼向量的左半部分由一個函數(使用正弦)生成,右半部分由另一個函數(使用餘弦)生成,連接起來後,就形成每個位置編碼向量。
這種編碼方法的優勢是可以拓展到不可見的序列長度,比如如果我們的訓練模型被要求翻譯一個比訓練集中任何一個句子都長的句子。
實際的位置編碼示例:是embedding大小爲20 * 512。它從中間一份爲二。每一行對應一個向量的位置編碼。
2.1.3 殘差連接
需要在編碼器體系結構中提到的一個細節是,每個編碼器中的每個子層(self-attention, ffnn)周圍都有一個殘差連接,也就layer-normalization。
如圖:
這也適用於解碼器的子層。如果我們考慮一個由兩個堆疊的編碼器和解碼器組成的Transformer,它應該如上。
2.2 Decoder部分
2.2.1 解碼器具體
編碼器會將頂層編碼器的輸出轉換爲一組attention向量K和v,分別由其“encoder-decoder attention”層中的各個解碼器使用,過程見下動圖:
以下步驟重複此過程,直到到達一個特殊符號,表示transformer解碼器已完成其輸出。
每一步的輸出在下一個時間步中被提供給底層解碼器,解碼器就像編碼器一樣彈出解碼結果。就像我們處理編碼器輸入一樣,我們嵌入並添加位置編碼到那些解碼器輸入中來表示每個單詞的位置。
圖2:https://jalammar.github.io/images/t/transformer_decoding_2.gif)
解碼器中的self attention層的工作方式與編碼器中的略有不同:
- 在decoder中,self-attention層只允許處理輸出序列中較早的位置,這是通過在self-attention計算softmax(我猜是score的時候k不是all key)之前屏蔽將來的位置(將他們設置爲-inf)來實現的!
- Encoder-Decoder Attention層的工作原理與multi-headed self attention類似,只是它從其下一層創建queries矩陣,並從編碼器堆棧的輸出中獲取keys和values矩陣。
最後的Linear and Softmax層
解碼器堆棧輸出浮點數向量。我們怎麼把它變成一個單詞呢?這是最後一個線性層的工作,然後是一個Softmax層。
線性層是一個簡單的全連接的神經網絡,它將解碼堆棧產生的向量投射到一個更大的向量上,稱爲logits向量。
這將使logits向量寬詞典數量個單元格——每個單元格對應一個惟一單詞的得分。這就是我們如何解釋線性層之後的模型輸出。
然後softmax層將這些分數轉換爲概率(所有爲正,所有加起來等於1.0)。選擇概率最高的單元格,並生成與之關聯的單詞作爲這個時間步驟的輸出。