# 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)