# Self-attention
## 想解決的問題
現在的問題都是「輸入一個向量,輸出一個數值(回歸)或類別(分類)」。
但如果想解決<span style="color:orange;">輸入是一排向量</span>,而且輸入長度<span style="color:orange;">有可能改變</span>呢?
### 輸入例子一:文字處理
可以將每個單字視為一個向量,有以下方法
- 最簡單的作法是 **One-hot Encoding**,像是以下表達
```none
apple = [1, 0, 0, 0, ...]
bag = [0, 1, 0, 0, ...]
cat = [0, 0, 1, 0, ...]
dog = [0, 0, 0, 1, ...]
```
缺點是「詞彙間沒有關係」,即無法從兩者間看出關係,像是 cat 與 dog 都是動物,以及 apple 是植物,但 cat 是動物的的關聯無法得出。
- 另一個方法是 **Word Embedding**
會給每個詞彙一個向量,這個向量會有語意的資訊的

[Word Embedding 相關課程](https://youtu.be/X7PH3NuYW0Q?si=8E2ci8AhEwojqLXz)
用這些方法後,就能將句子表達成<span style="color:orange;">一排長度不一的向量</span>。
### 輸入例子二:聲音處理
會將一段聲音訊號取一個範圍,稱為 *window* ,*window* 內的資訊會被視為一個向量,稱為 *frame*
*window* 通常都是 25 ms ,而為了覆蓋到全部的聲音訊號,會往右位移 10 ms

有很多方法可以將一個 *window* 內的資訊轉為一個向量 *frame*

### 輸入例子三:Graph
- social network
可以將每個人的 profile 視為一個向量
- 分子
一個原子視為一個向量,可以用 One-hot Encoding 的方法
### 輸出例子
1. 每個向量都有一個對應的 label (本課程只講這一個)

- POS tagging (詞性標註)

- 語音 (判斷音標)
- graph (決定某個 node 是否有某些特性)
2. 只輸出一個 label

- Sentiment analysis (文本情感分析)

- 語音辨識(例如辨識出誰講的)
- 分子預測(親水性等等)
3. 機器自己決定輸出幾個 label (aka [seq2seq](https://youtu.be/n9TlOhRjYoc?si=HoWxKaBkSDfgJpw0) )

- 翻譯
- 語音辨識(語音 to 文字)
## Sequence Labeling
就是上面提到的第一種輸出 (每個向量都有一個對應的 label)
### 使用 fully-connected 的模型?
將每個向量丟進一個 fully-connected 的模型去得到輸出
缺點:以詞性標記為例
如 I saw a saw 應輸出為 N V DET N ,但 fully-connected 的模型<span style="color:#FF3131;">對於相同的輸入會有相同的輸出</span> (在這個例子裡,是輸入 saw 應得到兩個答案) ,所以 fully-connected 無法應用於 Sequence Labeling
#### 讓 fully-connected 考慮上下文資訊?
可以,就將一部分 (如 window 或整個 Sequence ) 的向量都丟進 fully-connected 裡面
但如果一定要考慮整個 Sequence,參數會變很多,會導致<span style="color:#FF3131;">運算量變大,甚至 overfitting</span>
## Self-attention
<span style="color:#89CFF0;">Self-attention 是 Transformer 裡最重要的 module</span>
會吃一整個 Sequence 的資訊,並且輸入幾個向量,就輸出幾個向量

可以疊加很多次,也可以 fully-connected 與 Self-attention 交替使用
### 怎麼考慮一整個 Sequence 的資訊
#### 抽象表達:

#### 操作:
1. 先找出 Sequence 內相關的向量
- 定義「相關度」基準
以 $\alpha$ 來表示相關度
而從兩個向量得出 $\alpha$ 的方式有 *Dot-product* (較常見,用在 Transformer),以及 *Additive*

- 計算 $\alpha$
先計算 $q^{i} = W^{q}a^{i}$ ,象徵「搜尋」
再計算其他向量如 $k^{j} = W^{k}a^{j}$ ,象徵「關鍵字」
將 $q^{i}$ 與 $k^{j}$ 丟進第一步提到的「相關度」模組進行計算,得出 attention score
計算與其他的向量 (<span style="color:orange;">包括自己</span>) 的 attention score

2. 應用 $\alpha$
將計算出來的 $\alpha_{i, j}$ 通過 Soft-max 得出 $\alpha'_{i, j}$
可以將 soft-max 替換掉,如 ReLU 之類的

3. 根據關聯性抽取重要資訊
將每個向量乘以 $W^{v}$ 這個矩陣,得到對應的 $v^{i}$
將 $v^{i}$ 與 $\alpha'_{i, j}$ 相乘,並將所有的結果相加,得出 Self-attention 的結果 $b^{i}$

### 矩陣運算表達
上面提到的 $q$ 、 $k$ 、 $v$ 的計算都<span style="color:orange;">可以平行</span>,不用等前面的算完才開始算
1. 算出 $q$ 、 $k$ 、 $v$
已知 $q^{i} = W^{q} a^{i}$ ,既然每個向量都要乘以 $W^{q}$ 這個矩陣,那我們可以將所有向量組合成另一個矩陣 $I$ ,並乘以 $W^{q}$ ,就能算出新的矩陣 $Q$ ,而矩陣 $Q$ 內的每個 column 就是 $q^{i}$
同理,可以通過這種計算得出所有 $k^{i}$ 的 $K$ ,以及所有 $v^{i}$ 的 $V$

2. 算出 $\alpha'$
接著, attention score 是由 $q$ 乘上 $k$ 得出的,我們同樣可以通過上面的邏輯得出類似的結論
所以我們會得出一個 attention score 的矩陣 $A = K^{T} Q$ ,如果還有做 normalize 如 soft-max 之類的,還會得出一個矩陣 $A'$

3. 算出 $b$
同樣的,最後的 $b^{i} = v_{j} \alpha'_{i, j}$ 可以透過 $VA'$ 得出,也就是 $O = VA'$

#### 矩陣總結
只有 $W^q$ 、 $W^k$ 、 $W^v$ 是需要透過 train 出來的,其他的都不用

### Multi-head Self-attention
翻譯、語音辨識使用更多的 head 會有更好的表現
#### 操作
1. 計算出 $q$ 、 $k$ 、 $v$
$q$ 再乘以兩個(這邊以 2 head 為例子)不同的矩陣,得到 $q^{i, 1}$ 以及 $q^{i, 2}$ 兩個向量,以此類推,計算 $k^{i, 1}$ 、 $qk^{i, 2}$ 、 $v^{i, 1}$ 以及 $v^{i, 2}$
2. 計算 $\alpha$
$q^{i, 1}$ 與 $k^{i, 1}$ 進行計算,不管 $k^{i, 2}$ ,以此類推,計算 $q^{i, 2}$ 與 $k^{i, 2}$
3. 取得 $b$
剛剛的計算得出的 attention score 再乘以 $v^{i, 1}$ (以 $q^{i, 1}$ 與 $k^{i, 1}$ 為例) 得出 $b^{i, 1}$ ,同樣的操作,計算出 $b^{i, 2}$
最後,將 $b^{i, 1}$ 與 $b^{i, 2}$ 相接後,與矩陣 $W^O$ 計算,得出 $b^i$

### Positional Encoding
Self-attention 的輸入向量<span style="color:orange;">沒有位置的資訊</span>,也就是說,向量間的距離是一樣的,因為每個向量都會被其他向量計算到
但像某些情境,位置的資訊也很重要,如詞性標註的話,可以知道動詞可能不會放在最一開頭
解法:
為每一個位置設定一個 vector $e^{i}$ ,並加到 $a^{i}$ 上面

通常 position vector 都是人設定的,也有人用其他方法產生,如數學函數 sin 、 cos ,或者 RNN 等機器學習方法
# 應用情境
經典如:Transormer 、 BERT
## Speech
聲音訊號所表達出來的向量可能很多,用上面的 25ms window 計算,幾秒的語音訊息就會有上千個向量
向量越多代表運算量增多,也需要更多的記憶體去儲存,導致不容易處理與訓練

### Truncated Self-attention
在做 Self-attention 時,不看整句話,只看前幾筆或後幾筆的向量,取多長就基於對問題的理解

## image
前面的 CNN 提到,一個 image 可以被表示為一個 Tensor ,以 5 x 10 的 rgb image 舉例,可以將一個 pixel 的 3 個 channel 視為一個向量 ,就能得出一個 vector set 是 5 x 10 的大小
### 實例

### Self-attention v.s. CNN
Self-attention 的每個 pixel 會<span style="color:#32CD32;">考慮到整張圖</span>,而 CNN 的一個神經元<span style="color:#32CD32;">只會考慮 Receptive field 的大小</span>
function set:

CNN 是簡化版的 Self-attention,Self-attention 是複雜化的 CNN
Self-attention 擁有比 CNN 更高的彈性 && 資料量小的話,彈性較大的模型更容易 overfitting $\rightarrow$ 資料量小的情境, Self-attention 更容易 overfitting

### Self-attention v.s. RNN
RNN 相對於 Self-attention <span style="color:#32CD32;">更難去「記得」或「考慮」</span>前面的向量
RNN <span style="color:#32CD32;">無法平行計算</span>,但 Self-attention 可以

## graph
將 node 看做向量,而 edge 的資訊可以為 attention score 服務
node 間有 edge 代表那兩個 node 有相關,因此在計算 attention score 時<span style="color:#32CD32;">只需要計算有 edge(相關) 的 node(向量) </span>就行了

# Self-attention 變形與比較
Self-attention 的<span style="color:#32CD32;">缺點是運算量大</span>,因此有許多人去研究 Self-attention 的變形
雖然速度有上去了,但表現卻比原先的 Transformer 差
