# 第五章:自注意力機制 (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) ![image](https://hackmd.io/_uploads/r1G4KrHn1g.png) * **語音訊號**: 將一段聲音訊號切分成許多小的時間片段 (Window,如 25ms) ,每個片段提取特徵並表示為一個向量 (Frame) ,一段語音即為一系列的 Frame 向量。 * 通常 Window 會以一定的步長 (如 10ms) 滑動。 * 一秒鐘的語音可能包含 100 個 Frame 向量。 ![image](https://hackmd.io/_uploads/BJ1PFrS3kg.png) * **圖 (Graph)**: 圖中的每個節點可以視為一個向量。 * 節點的向量表示可以包含節點的屬性資訊。 * **例子**: 社群網路 (人是節點,關係是邊) 、分子結構 (原子是節點,化學鍵是邊) 。 * 原子可以用 One-Hot 向量表示 (如氫、碳、氧) 。 ![image](https://hackmd.io/_uploads/ByDBcBShJx.png) --- ## 輸出是什麼? 對於輸入為向量集合的模型,可能的輸出有三種: 1. **每個向量都有一個對應的標籤 (Each vector has a label)**: 輸入幾個向量,就輸出幾個標籤,輸入與輸出**長度相同**。 * 標籤可以是數值 (迴歸問題) 或類別 (分類問題) 。 * **應用範例**: * **詞性標註 (POS Tagging)**: 為句子中的每個詞彙標註其詞性 (名詞、動詞等) 。 * 例如:「I saw a saw」,第一個 "saw" 是動詞,第二個 "saw" 是名詞。 * **語音處理**: 為語音訊號的每個 Frame 向量決定其對應的音標 (Phonetic)。 * **社群網路**: 預測每個節點的特性 (如是否會購買某商品) 。 ![image](https://hackmd.io/_uploads/HkJesHHhye.png) 2. **整個序列有一個標籤 (The whole sequence has a label)**: 輸入一個向量序列,只輸出一個總體的標籤。 * **應用範例**: * **情感分析 (Sentiment Analysis)**: 判斷一段文字是正面還是負面。 * **語者辨認**: 聽一段聲音判斷是誰說的。 * **分子性質預測**: 給定一個分子結構,預測其毒性或親水性。 ![image](https://hackmd.io/_uploads/BJ4VjBrhJx.png) 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 機制的重要性。 ![image](https://hackmd.io/_uploads/rJaLhBHnJg.png) * 雖然 "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) 來表示。 ![image](https://hackmd.io/_uploads/HJuVASBh1g.png) ![image](https://hackmd.io/_uploads/SJ9FRSS2kl.png) ### 計算注意力分數 (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}$。 ![image](https://hackmd.io/_uploads/HyO4U5ikxx.png) ### 產生輸出向量 (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 等其他激活函數也可能有效。 ![image](https://hackmd.io/_uploads/rJJEJIH2kx.png) 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 中提取出的資訊==。 ![image](https://hackmd.io/_uploads/HkcBeUShJg.png) ### 矩陣表示 (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$)。 ![image](https://hackmd.io/_uploads/Sk4RgIrnyl.png) 3. 計算所有注意力分數可以表示為矩陣乘法: * 注意力分數矩陣 $A = K^T Q$ (或 $Q K^T$),其中 $A_{ij} = q_i \cdot k_j$。 4. 正規化注意力分數:$A' = \text{softmax}(A)$ (對 $A$ 的每一行/列進行 Softmax)。 ![image](https://hackmd.io/_uploads/SkeSZIr3ye.png) 5. 計算輸出矩陣 $O$ (每列/欄是一個 $b_i$):$O = V A'$ (或 $A'^T V$)。 ![image](https://hackmd.io/_uploads/rJxoZIrnyx.png) * **Self-attention 層中唯一需要學習的參數是 $W_q, W_k, W_v$**。 ![image](https://hackmd.io/_uploads/S1ubzLSn1e.png) --- ## 多頭注意力機制 (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$ 是注意力頭的數量)。 * **優點**: 可以捕捉不同種類的相關性。 * **注意力頭的數量** 是一個超參數,需要根據具體任務調整。 ![image](https://hackmd.io/_uploads/SyE0MUB2Jl.png) --- ## 位置編碼 (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$。 ![image](https://hackmd.io/_uploads/Hy3kEIHnye.png) ### 位置向量的生成方法: * **手工設計 (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](https://hackmd.io/_uploads/rkT9VUSn1x.png) ### 圖像處理 (Image): * 可以將圖像視為一個向量的集合 (每個像素或圖像塊是一個向量)。 ![image](https://hackmd.io/_uploads/rkVBBUS2Jg.png) * **[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 取代。 ![image](https://hackmd.io/_uploads/rJcSU8r3kg.png) * **[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)** 的其中一種。 ![image](https://hackmd.io/_uploads/HJ3GPIS3yg.png) * 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 機制仍然是一個重要的研究方向。 ![image](https://hackmd.io/_uploads/BJLwPIr31g.png) --- 回[主目錄](https://hackmd.io/@Jaychao2099/aitothemoon/)