# 第五章:自注意力機制 (Self-attention)
>上課筆記
* 上課影片連結
* ==[**自注意力機制 (Self-attention)(上)**](https://youtu.be/OP5HcXJg2Aw)==
* ==[**自注意力機制 (Self-attention)(下)**](https://youtu.be/gmsMY5kc-zw)==
---
## 輸入:向量的集合 (Vector Set as Input)
傳統網路的輸入通常是單一向量,但許多複雜問題的輸入是**一系列的向量 (Sequence of Vectors)**,且向量的數量 (序列長度) 可能會改變。
### 例子:
* **文字處理 (Natural Language Processing, NLP)**: 一個句子由多個詞彙組成,每個詞彙可表示為一個向量,句子的長度不一。
* **詞彙向量化方法**:
* **One-Hot Encoding**: 為每個詞彙創建一個高維稀疏向量,向量長度等於詞彙表大小,只有對應詞彙的維度為 1,其餘為 0。
* **缺點**: 無法表示詞彙之間的語義關係。
* **Word Embedding**: 將每個詞彙映射到一個低維稠密向量,這些向量能捕捉詞彙之間的語義資訊。
* 詞嵌入可從網路上下載。
* 參考[2016上課影片](https://youtu.be/X7PH3NuYW0Q)

* **語音訊號**: 將一段聲音訊號切分成許多小的時間片段 (Window,如 25ms) ,每個片段提取特徵並表示為一個向量 (Frame) ,一段語音即為一系列的 Frame 向量。
* 通常 Window 會以一定的步長 (如 10ms) 滑動。
* 一秒鐘的語音可能包含 100 個 Frame 向量。

* **圖 (Graph)**: 圖中的每個節點可以視為一個向量。
* 節點的向量表示可以包含節點的屬性資訊。
* **例子**: 社群網路 (人是節點,關係是邊) 、分子結構 (原子是節點,化學鍵是邊) 。
* 原子可以用 One-Hot 向量表示 (如氫、碳、氧) 。

---
## 輸出是什麼?
對於輸入為向量集合的模型,可能的輸出有三種:
1. **每個向量都有一個對應的標籤 (Each vector has a label)**: 輸入幾個向量,就輸出幾個標籤,輸入與輸出**長度相同**。
* 標籤可以是數值 (迴歸問題) 或類別 (分類問題) 。
* **應用範例**:
* **詞性標註 (POS Tagging)**: 為句子中的每個詞彙標註其詞性 (名詞、動詞等) 。
* 例如:「I saw a saw」,第一個 "saw" 是動詞,第二個 "saw" 是名詞。
* **語音處理**: 為語音訊號的每個 Frame 向量決定其對應的音標 (Phonetic)。
* **社群網路**: 預測每個節點的特性 (如是否會購買某商品) 。

2. **整個序列有一個標籤 (The whole sequence has a label)**: 輸入一個向量序列,只輸出一個總體的標籤。
* **應用範例**:
* **情感分析 (Sentiment Analysis)**: 判斷一段文字是正面還是負面。
* **語者辨認**: 聽一段聲音判斷是誰說的。
* **分子性質預測**: 給定一個分子結構,預測其毒性或親水性。

3. **模型決定標籤的數量 (Model decides the number of labels itself)**: 輸入 $N$ 個向量,輸出 $N'$ 個標籤,輸出長度由模型決定。
* 這類任務稱為 **序列到序列 (Sequence to Sequence, seq2seq)**。
* **應用範例**:
* **翻譯 (Translation)**: 將一種語言的句子翻譯成另一種語言,輸入和輸出的詞彙數量通常不同。
* **語音辨識 (Speech Recognition)**: 輸入語音訊號,輸出對應的文字。
:::info
本次課程主要討論第一種類型:**序列標註 (Sequence Labeling)**,即輸入與輸出長度相同的狀況。
:::
---
## 序列標註 (Sequence Labeling)
目標是為輸入序列中的每一個向量都給予一個標籤。
### 直覺方法:完全連接網路 (Fully-Connected Network, FC) :x:
* 將序列中的每個向量獨立地輸入到 FC 網路中,各自產生輸出。
* **缺點**: 無法考慮**上下文 (Context)** 的資訊。
* 例如在詞性標註中,「I saw a saw」,兩個 "saw" 是相同的詞彙,FC 網路會輸出相同的詞性,但實際上它們的詞性不同。
### 考慮上下文:滑動視窗 (Window) :x:
* 將目標向量及其前後幾個向量串聯起來,作為 FC 網路的輸入。
* **優點**: 可以讓 FC 網路考慮鄰近向量的資訊。
* **缺點**:
* **視窗大小的限制**: 如果需要考慮整個序列的資訊,視窗需要足夠大以覆蓋整個序列。
* **序列長度可變**: 不同輸入序列的長度可能不同,若要覆蓋最長序列,視窗可能會非常大,導致 FC 網路參數過多,容易**過擬合 (Overfitting)**。
* 難以考慮長距離的依賴關係。
### 自注意力機制 (Self-attention):考慮整個序列的資訊 :heavy_check_mark:
* Self-attention 能夠讀取整個輸入序列的資訊,並為每個輸入向量產生一個新的輸出向量,這個新的輸出向量**考慮了整個輸入序列的資訊**。
* 輸入幾個向量,就輸出幾個向量,但每個輸出向量都包含了全局的上下文資訊 (天涯若比鄰)。
* Self-attention 的輸出可以再輸入到 FC 網路中進行標註。
* 可以**堆疊多個 Self-attention 層**,並與 FC 網路交替使用,以更深入地處理序列資訊。
* **關鍵論文**: "[Attention is all you need.](https://arxiv.org/abs/1706.03762)" 提出了 **Transformer** 網路架構,其中最核心的模組就是 Self-attention。
* Transformer 又稱「變形金剛」。
* 論文標題強調了 Attention 機制的重要性。

* 雖然 "Attention is all you need." 使 Self-attention 發揚光大,但類似的架構在更早的論文中就已出現,可能稱為 Self-Matching 等。
---
## 自注意力機制的運作方式
* **輸入**: 一個由向量組成的序列 $a_1, a_2, a_3, a_4$ (可以是網路的原始輸入或某個隱藏層的輸出)。
* **輸出**: 另一個相同長度的向量序列 $b_1, b_2, b_3, b_4$,其中每個 $b_i$ 都考慮了所有輸入向量 $a_1$ 到 $a_4$ 的資訊。
* **目標**: 對於每個輸入向量 $a_i$,找出序列中與其**相關**的其他向量。
* 相關性用一個數值 $\alpha$ (attention score) 來表示。


### 計算注意力分數 (Calculating Attention Scores)
對於輸入向量 $a_i$,需要計算它與序列中所有其他向量 $a_j$ 的相關性 $\alpha_{ij}$。
* **常用方法:點積 (Dot Product)**
1. 對於每一個輸入向量 $a_i$,學習三個轉換矩陣 $W_q, W_k, W_v$ (query, key, value)。
2. 將 $a_i$ 分別與這三個矩陣相乘,得到對應的:
* query 向量 $q_i = W_q a_i$
* key 向量 $k_i = W_k a_i$
* value 向量 $v_i = W_v a_i$
3. 計算 $a_i$ (其 query 為 $q_i$) 與 $a_j$ (其 key 為 $k_j$) 之間的注意力分數 $\alpha_{ij}$,通常使用點積:$$\alpha_{ij} = q_i \cdot k_j$$
>[!Tip]
>* $q_i$ 就像**搜尋的關鍵字**,而 $k_j$ 就像**被搜尋的內容**。
>* $\alpha_{ij}$ 表示 $a_i$ 和 $a_j$ 之間的**相關程度**。
4. 對於 $a_1$,需要計算其與 $a_1, a_2, a_3, a_4$ 的注意力分數 $\alpha_{11}, \alpha_{12}, \alpha_{13}, \alpha_{14}$。
* **其他計算注意力的方法**: 加法式 (Additive)
* 將 $q_i$ 和 $k_j$ 串聯後通過一個函數 (如 tanh) 和一個線性轉換得到 $\alpha_{ij}$。

### 產生輸出向量 (Generating Output Vectors)
1. 對計算出的注意力分數 $\alpha_{i1}, \alpha_{i2}, \cdots, \alpha_{in}$ 進行 **Softmax 正規化**,得到 $\alpha'_{i1}, \alpha'_{i2}, \cdots, \alpha'_{in}$。$$\alpha'_{ij} = \frac{\exp(\alpha_{ij})}{\sum_{k} \exp(\alpha_{ik})}$$
* Softmax 的作用是將注意力分數轉換為權重,使其總和為 1.
* **注意**: Softmax 不是唯一的選擇,ReLU 等其他激活函數也可能有效。

2. 對於每個輸入位置 $i$,將所有 value 向量 $v_j$ 根據其對應的正規化注意力權重 $\alpha'_{ij}$ 進行**加權求和**,得到輸出向量 $b_i$:$$b_i = \sum_{j} \alpha'_{ij} v_j$$
* 如果 $a_i$ 與 $a_j$ 的相關性很高 ($\alpha'_{ij}$ 很大) ,則 $v_j$ 在計算 $b_i$ 時的影響就越大。
* $b_i$ 可以看作是==根據序列中所有向量的相關性,從所有向量的 value 中提取出的資訊==。

### 矩陣表示 (Matrix Representation)
1. 將輸入序列 $a_1, a_2, a_3, a_4$ 堆疊成一個輸入矩陣 $I$ (每列或每欄代表一個向量)。
2. 計算所有的 query 向量、key 向量和 value 向量可以表示為矩陣乘法:
* $Q = I W_q$ (query 矩陣,每列/欄是一個 $q_i$)。
* $K = I W_k$ (key 矩陣,每列/欄是一個 $k_i$)。
* $V = I W_v$ (value 矩陣,每列/欄是一個 $v_i$)。

3. 計算所有注意力分數可以表示為矩陣乘法:
* 注意力分數矩陣 $A = K^T Q$ (或 $Q K^T$),其中 $A_{ij} = q_i \cdot k_j$。
4. 正規化注意力分數:$A' = \text{softmax}(A)$ (對 $A$ 的每一行/列進行 Softmax)。

5. 計算輸出矩陣 $O$ (每列/欄是一個 $b_i$):$O = V A'$ (或 $A'^T V$)。

* **Self-attention 層中唯一需要學習的參數是 $W_q, W_k, W_v$**。

---
## 多頭注意力機制 (Multi-head Self-attention)
認為相關性有多種不同的形式,單一的注意力機制可能無法捕捉所有類型的相關性。
* 使用多個獨立的 **注意力頭 (Attention Heads)** 平行地進行 Self-attention 計算。
* 對於每個注意力頭 $i$,學習**不同的轉換矩陣** $W_{q,i}, W_{k,i}, W_{v,i}$。
* 輸入向量 $a$ 經過不同的轉換後得到多個 query 頭 ($q_{i,1}, q_{i,2}, \cdots$), key 頭 ($k_{i,1}, k_{i,2}, \cdots$), 和 value 頭 ($v_{i,1}, v_{i,2}, \cdots$)。
* 每個注意力頭獨立地計算注意力分數和輸出,例如:
* 第一個頭只關注 $q_{i,1}$ 和 $k_{j,1}$,並根據 $v_{j,1}$ 計算輸出 $b_{i,1}$。
* 第二個頭只關注 $q_{i,2}$ 和 $k_{j,2}$,並根據 $v_{j,2}$ 計算輸出 $b_{i,2}$。
* 將所有注意力頭的輸出**拼接 (Concatenate)** 在一起,然後通過一個線性轉換矩陣 $W_O$ 得到最終的輸出 $b_i$:
* $b_i = W_O [b_{i,1}; b_{i,2}; \cdots; b_{i,h}]$ (其中 $h$ 是注意力頭的數量)。
* **優點**: 可以捕捉不同種類的相關性。
* **注意力頭的數量** 是一個超參數,需要根據具體任務調整。

---
## 位置編碼 (Positional Encoding)
標準的 Self-attention 機制本身**沒有位置資訊**,它對輸入序列中向量的順序是不敏感的。(例如,對於 Self-attention 來說,$q_1$ 到 $q_4$ 的距離與 $q_2$ 到 $q_3$ 的距離沒有本質區別)。
但在許多任務中,**位置資訊非常重要** (例如,詞性標註中,動詞通常不會出現在句首)。
### 位置編碼 (Positional Encoding)
* **目的**:將序列中每個位置的資訊嵌入到向量表示中。
* **作法**:
1. 為序列中的**每個位置** (例如,第一個位置、第二個位置等) 定義一個**獨特的位置向量 $e_i$**。
2. 將位置向量 $e_i$ **加到** 對應的輸入向量 $a_i$ 上:$a'_i = a_i + e_i$。

### 位置向量的生成方法:
* **手工設計 (Hand-crafted)**: 例如,Transformer 論文中使用基於正弦和餘弦函數的方法生成位置向量。
* 每個位置對應一個獨特的向量。
* **從資料中學習 (Learned from data)**: 將位置向量作為網路的參數進行學習。
* 其他方法,如基於 RNN 或其他網路結構生成位置編碼。
位置編碼仍然是一個活躍的[研究](https://arxiv.org/abs/2003.09229)領域。
---
## 自注意力機制的應用
### 自然語言處理 (NLP):
廣泛應用於各種 NLP 任務。
* **[Transformer](https://arxiv.org/abs/1706.03762):** 基於 Self-attention 的網路架構,是許多現代 NLP 模型的基礎。
* **[BERT](https://arxiv.org/abs/1810.04805):** 一個預訓練的 Transformer 模型,在多個 NLP 任務上取得了巨大成功。
### 語音處理 (Speech):
* **截斷自注意力 ([Truncated Self-attention](https://arxiv.org/abs/1910.12977))**: 由於語音序列通常很長,直接計算全局注意力計算量很大 ($O(L^2)$,L 為序列長度)。
* 截斷自注意力只在一個**有限的範圍**內計算注意力,以減少計算量。
* 這個範圍的大小可以根據對語音問題的理解來設定。

### 圖像處理 (Image):
* 可以將圖像視為一個向量的集合 (每個像素或圖像塊是一個向量)。

* **[Self-Attention GAN](https://arxiv.org/abs/1805.08318)**: 將自注意力機制應用於生成對抗網路 (GAN) 中以生成圖像。
* **[DEtection Transformer (DETR)](https://arxiv.org/abs/2005.12872)**: 使用 Transformer 進行目標檢測。
* **[An Image is Worth 16x16 Words: Transformers for Image Recognition](https://arxiv.org/pdf/2010.11929.pdf)**: 將圖像分割成小的圖像塊 (patch),將每個 patch 視為一個詞彙,然後使用 Transformer 進行圖像分類。
---
## [自注意力機制 vs. 卷積神經網路 (CNN)](https://arxiv.org/abs/1911.03584)
* **CNN**: 每個神經元只關注其**感受野 (Receptive Field)** 內的資訊。
* **Self-attention**: 在計算注意力時,可以考慮**整張圖像**的資訊。
* **關係**:
* **CNN 可以看作是簡化版的 Self-attention**: CNN 的感受野是固定的,而 Self-attention 的注意力範圍是根據資料學習出來的。
* **Self-attention 可以看作是複雜化的 CNN**: Self-attention 具有**可學習的感受野**,網路可以自行決定哪些像素是相關的。
* **彈性 (Flexibility)**: Self-attention 比 CNN 更具彈性。
* **資料需求**:
* **資料量較少時**: CNN 可能表現更好,因為其限制較多,不容易過擬合。
* **資料量較大時**: Self-attention 可以從更多資料中獲益,通常能取得更好的效果。
---
## 自注意力機制 vs. 循環神經網路 (RNN)
* **RNN**: 處理序列資料的另一種常見網路結構,通過**記憶向量 (Memory Vector)** 在時間步之間傳遞資訊。
* **相似之處**: 兩者都用於處理輸入為序列的狀況,並產生一個輸出序列。
* **不同之處**:
* **考慮上下文**: 傳統 RNN 在某個時間步的輸出只考慮了之前輸入的資訊 (單向 RNN)。雙向 RNN 可以同時考慮過去和未來的資訊。 Self-attention 的每個輸出向量都直接考慮了整個輸入序列的所有向量。
* **長距離依賴**: RNN 處理長序列時可能存在**遺忘問題**,難以捕捉長距離的依賴關係。 Self-attention 可以輕鬆地從序列中相距很遠的向量中提取資訊。
* **平行化**: **RNN 無法平行化處理序列**,必須按時間步依次計算。 **Self-attention 可以平行地計算所有位置的輸出**,因此在運算速度上更有效率。
* **趨勢**: 許多應用中,RNN 的架構正逐漸被 Self-attention 取代。

* **[Transformers are RNNs](https://arxiv.org/abs/2006.16236)**: 一篇論文探討了 Self-attention 與 RNN 之間的關係,指出在加入某些機制後,Self-attention 可以轉化為 RNN。
* 參考[2017上課影片](https://youtu.be/xCGidAeyS4M)
---
## 自注意力機制用於圖 (Self-attention for Graph)
圖可以被視為一個向量的集合 (每個節點是一個向量),因此,Self-attention 也可以應用於圖結構。
* **圖的額外資訊:邊 (Edge)**。
* 邊表示節點之間的連接和關係。
* 在使用 Self-attention 處理圖時,可以**僅計算相連節點之間的注意力分數**,不相連的節點之間的注意力分數可以直接設為 0。
* 這樣可以利用圖的結構資訊,避免計算不相關節點之間的注意力。
* 將 Self-attention 以這種方式應用於圖上,是**圖神經網路 (Graph Neural Network, GNN)** 的其中一種。

* GNN 是一個複雜且深入的領域。
* 參考[2020上課影片](https://youtu.be/eybCCtNKwzA)
---
## 總結與展望
* Self-attention 是一種強大的機制,能夠有效地處理序列資料並捕捉長距離的依賴關係,其核心思想是根據輸入序列中不同位置之間的相關性,對資訊進行加權聚合。
* Transformer 架構的成功證明了 Self-attention 的有效性,並在 NLP 等領域取得了突破性進展。
* Self-attention 也被廣泛應用於語音、圖像和圖等其他領域。
* **效率問題**: 標準 Self-attention 的計算複雜度是序列長度的平方 ($O(L^2)$),對於長序列而言計算量很大。
* **高效 Transformer ([Efficient Transformers](https://arxiv.org/abs/2009.06732))**: 目前有許多研究致力於**減少 Self-attention 的計算量**,提出了各種不同的變形 (如 Linformer, Performer, Reformer 等)。
* 這些高效 Transformer 通常在速度上有所提升,但可能犧牲一定的性能。
* 如何設計出既高效又高性能的 Self-attention 機制仍然是一個重要的研究方向。

---
回[主目錄](https://hackmd.io/@Jaychao2099/aitothemoon/)