# Attention Mechanism in NLP ###### tags: `ML` `DL` `NLP` ## Query, Key-Value pairs 想像一個搜尋引擎,給他一個 query,他就會用這個 query 在他 available 的資料裡,按照相關程度排序你所想要的資料來給你。 Attention 就像是這樣的搜尋引擎:Query 就是搜尋引擎的 query,Key-Value pairs 就是搜尋引擎裡所有可以搜尋到的資料,比對 Query 和 Key 來算出一對 Key-Value pairs 和 Query 的相關程度。 只不過,Attention 到最後會輸出的不只是這個排序,而是一個期望值。也就是說,這些 values 都會是數值的資料,算出每個 key 和一個 query 的相關程度之後,最後得到的期望值就是這些相關程度對 values 的加權平均。 而 Query 和某個 Key 的相關程度,又稱為這個 Query 和 Key-Value pairs 的 attention weight。 ### 舉個例子 假設我們想推測小明 (Query) 每個月在手遊上課金課了多少,而有底下這些資料: | Key | Value | |-----|------:| | 小明的哥哥   | 25 | 小明的大學同學 | 300 | 小明的遊戲隊友 | 1,000 | 小明的同事   | 0 | 路人甲     | 100,000 利用 Query 和這些 Key-Value pairs,我們腦裡可能就會有一個神奇的 KeJinRelatiion 演算法,算出在手遊課金這件事情上面,小明跟這些 Keys 有多大的關聯性: | Key | KeJinRelation(小明, Key) | value | | --- | ----------------------- | -----:| | 小明的哥哥   | 2 ~雖然小明和哥哥感情不錯,但是沒有住在一起,在不同地方各自努力~ | 25 | 小明的大學同學 | 3 ~大學時都和小明一起玩手遊~ | 300 | 小明的遊戲隊友 | 4 ~應該課得差不多才有辦法好好的當隊友不吵架~ | 1,000 | 小明的同事   | 1 ~小明和同事不太熟,但賺得差不多~ |0 | 路人甲     | 0 ~不認識小明~ | 100,000 然後就可以推算出小明每個月的課金量大概是 $$ \frac{2*25+3*300+4*1000+1*0+0*100000}{2+3+4+1+0}=495 $$ 那為什麼會叫 attention (注意力) 呢?就是說我們想辦法知道重要的地方是哪裡(找一個演算法來算 Query-Key 的關係),然後再根據重要程度把部分的注意力放在這些地方(利用 attention weights 做加權平均)。 ## Attention for Sentence Classification 假設我們想做句子的分類,把每個句子分成開心、難過、生氣、驚訝四種情緒。 那麼,開心、難過、生氣、驚訝就可以當作 4 個 Queries,而句子裡的每一個詞就是 Key,Value 就是這些詞的 word vectors。利用 attention,將句子裡所有詞的 word vectors 做加權平均,當成最後整個句子的 feature vector,再利用這個 feature vector 來做最後的分類。 每個 Query, Key 都可以被表示為一個 vector:Query vector 是 model 直接調整的 parameters;Key vector 則是由對應 value 的 word vector 經由某些轉換而來。通常一個 Query vector 會和每個 Key vectors 分別內積後取 softmax 作為加權數。 對一個 Query-Sentence pair,算出 feature vector 的完整步驟如下: 1. 把句子裡的每一個 word vectors 都經過某種相同的轉換,變成跟 query vector 一樣長度的 key vectors。 2. 把 query vector 和每一個 key vectors 做內積,以得到每個 word 對這個 query 的 attention weights。 3. 利用這些 attention weights,對句子裡的所有 word vectors 做加權平均,得到這個 Query 對這個 Sentence 的 feature vector。 ## Self Attention 當 Queries/Keys 是來自同一個 set 的時候,就叫 self attention。比如說,對一個句子做 self attention,就可以是: - 句子裡的每個 word vectors,做轉換 A 得到 Key vectors, - 句子裡的每個 word vectors,做轉換 B 得到 Query vectors。 - 對每個 Query vector - 與每個 Key vector 做內積算出 attention weights - 利用 attention weights 算出 word vectors 的加權平均 最後得到的就是一組新的 word vectors,或者說 context vectors,每個 context vector 都包含了整個句子的資訊,但是又著重在和原本的 word vector 相關的部分。 這個 attention 得到的 context vectors,又可以作為 value vector,經過一樣的步驟再算出下一層的 context vectors,所以 self attention 是可以做為一個 layer,一層一層往上疊的。 ## Masking 在處理長度不同的 sequence 時,如果使用 attention,就要注意不能使用 padding 的 Value vector,要把 padding 處的 attention weights 設成 0。實際做法就是: - 對於每個 input sequence,輸入相同長度的 mask sequence,在 padding 處為 0,其他地方為 1。 - 在算出 attention weights 後,把這些 weights 和 mask 相乘。 這樣就能讓 padding 的 vector 永遠都不會加進最後的 output 裡。 ## Transformer: Multi-Head Self Attention 出自 Paper: Attention is all you need 的 Transformer model,使用了 multi-head self attention: $$ \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \text{head}_2, ..., \text{head}_h)W^o\\ \text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) \\ \text{Attention}(\hat{Q}, \hat{K}, \hat{V}) = \text{softmax}(\frac{\hat{Q}\hat{K}^T}{\sqrt{d_\hat{K}}})\hat{V} $$ 也就是說他總共做了 $h$ 次的 attention,然後把這些都 concat 在一起,再做一次 linear transform 得到最後的 output。 另外,Transformer 計算 attention weight $A$ 的方式是: $$ A_{Q,K}=\frac{QK^T}{\sqrt{d_K}} $$ 也就是 $QK$ 內積之後再除以 $QK$ 的 dimension 開根號,避免當 $QK$ dimension 比較大時,內積也會特別大,softmax 後就變得很接近。 在 transformer encoder layer 中,輸入的 $QKV$ 是一樣的,就是前一層輸出的 word/context vector。在 transformer decoder layer 中,有兩層 multi-head attention,第一層輸入的 $QKV$ 都是 decoder 的 input,第二層輸入的 $QK$ 是 encoder output,$V$ 是第一層的 output。 --- 下一篇:[Transformer 和他的夥伴們](/aWSLT8-jTuGGtWMV5zSBYQ)