# 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** 會給每個詞彙一個向量,這個向量會有語意的資訊的 ![image](https://hackmd.io/_uploads/Sk0t-AGiA.png) [Word Embedding 相關課程](https://youtu.be/X7PH3NuYW0Q?si=8E2ci8AhEwojqLXz) 用這些方法後,就能將句子表達成<span style="color:orange;">一排長度不一的向量</span>。 ### 輸入例子二:聲音處理 會將一段聲音訊號取一個範圍,稱為 *window* ,*window* 內的資訊會被視為一個向量,稱為 *frame* *window* 通常都是 25 ms ,而為了覆蓋到全部的聲音訊號,會往右位移 10 ms ![image](https://hackmd.io/_uploads/ryvw7AfoC.png) 有很多方法可以將一個 *window* 內的資訊轉為一個向量 *frame* ![image](https://hackmd.io/_uploads/B1x6fRzs0.png) ### 輸入例子三:Graph - social network 可以將每個人的 profile 視為一個向量 - 分子 一個原子視為一個向量,可以用 One-hot Encoding 的方法 ### 輸出例子 1. 每個向量都有一個對應的 label (本課程只講這一個) ![image](https://hackmd.io/_uploads/SJbCERMsR.png) - POS tagging (詞性標註) ![image](https://hackmd.io/_uploads/BkceBRGo0.png) - 語音 (判斷音標) - graph (決定某個 node 是否有某些特性) 2. 只輸出一個 label ![image](https://hackmd.io/_uploads/rJTjHCzoA.png) - Sentiment analysis (文本情感分析) ![image](https://hackmd.io/_uploads/B1TPrAfiC.png) - 語音辨識(例如辨識出誰講的) - 分子預測(親水性等等) 3. 機器自己決定輸出幾個 label (aka [seq2seq](https://youtu.be/n9TlOhRjYoc?si=HoWxKaBkSDfgJpw0) ) ![image](https://hackmd.io/_uploads/r1jZLCfjA.png) - 翻譯 - 語音辨識(語音 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 的資訊,並且輸入幾個向量,就輸出幾個向量 ![image](https://hackmd.io/_uploads/B1NSLems0.png) 可以疊加很多次,也可以 fully-connected 與 Self-attention 交替使用 ### 怎麼考慮一整個 Sequence 的資訊 #### 抽象表達: ![image](https://hackmd.io/_uploads/SkuZwg7sA.png) #### 操作: 1. 先找出 Sequence 內相關的向量 - 定義「相關度」基準 以 $\alpha$ 來表示相關度 而從兩個向量得出 $\alpha$ 的方式有 *Dot-product* (較常見,用在 Transformer),以及 *Additive* ![image](https://hackmd.io/_uploads/Bk_-ZQmoA.png) - 計算 $\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 ![image](https://hackmd.io/_uploads/Syqscx7oR.png) 2. 應用 $\alpha$ 將計算出來的 $\alpha_{i, j}$ 通過 Soft-max 得出 $\alpha'_{i, j}$ 可以將 soft-max 替換掉,如 ReLU 之類的 ![image](https://hackmd.io/_uploads/rkjZixmjA.png) 3. 根據關聯性抽取重要資訊 將每個向量乘以 $W^{v}$ 這個矩陣,得到對應的 $v^{i}$ 將 $v^{i}$ 與 $\alpha'_{i, j}$ 相乘,並將所有的結果相加,得出 Self-attention 的結果 $b^{i}$ ![image](https://hackmd.io/_uploads/S16fhgXoA.png) ### 矩陣運算表達 上面提到的 $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$ ![image](https://hackmd.io/_uploads/BJRUE77iC.png) 2. 算出 $\alpha'$ 接著, attention score 是由 $q$ 乘上 $k$ 得出的,我們同樣可以通過上面的邏輯得出類似的結論 所以我們會得出一個 attention score 的矩陣 $A = K^{T} Q$ ,如果還有做 normalize 如 soft-max 之類的,還會得出一個矩陣 $A'$ ![image](https://hackmd.io/_uploads/r1TwHm7i0.png) 3. 算出 $b$ 同樣的,最後的 $b^{i} = v_{j} \alpha'_{i, j}$ 可以透過 $VA'$ 得出,也就是 $O = VA'$ ![image](https://hackmd.io/_uploads/BkgtL7QoC.png) #### 矩陣總結 只有 $W^q$ 、 $W^k$ 、 $W^v$ 是需要透過 train 出來的,其他的都不用 ![image](https://hackmd.io/_uploads/SkdyvQXoR.png) ### 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$ ![image](https://hackmd.io/_uploads/SJ9DF7miA.png) ### Positional Encoding Self-attention 的輸入向量<span style="color:orange;">沒有位置的資訊</span>,也就是說,向量間的距離是一樣的,因為每個向量都會被其他向量計算到 但像某些情境,位置的資訊也很重要,如詞性標註的話,可以知道動詞可能不會放在最一開頭 解法: 為每一個位置設定一個 vector $e^{i}$ ,並加到 $a^{i}$ 上面 ![image](https://hackmd.io/_uploads/H1PZa7msR.png) 通常 position vector 都是人設定的,也有人用其他方法產生,如數學函數 sin 、 cos ,或者 RNN 等機器學習方法 # 應用情境 經典如:Transormer 、 BERT ## Speech 聲音訊號所表達出來的向量可能很多,用上面的 25ms window 計算,幾秒的語音訊息就會有上千個向量 向量越多代表運算量增多,也需要更多的記憶體去儲存,導致不容易處理與訓練 ![image](https://hackmd.io/_uploads/ByJjCmQo0.png) ### Truncated Self-attention 在做 Self-attention 時,不看整句話,只看前幾筆或後幾筆的向量,取多長就基於對問題的理解 ![image](https://hackmd.io/_uploads/r1mAR7moR.png) ## image 前面的 CNN 提到,一個 image 可以被表示為一個 Tensor ,以 5 x 10 的 rgb image 舉例,可以將一個 pixel 的 3 個 channel 視為一個向量 ,就能得出一個 vector set 是 5 x 10 的大小 ### 實例 ![image](https://hackmd.io/_uploads/HycIyNmiC.png) ### Self-attention v.s. CNN Self-attention 的每個 pixel 會<span style="color:#32CD32;">考慮到整張圖</span>,而 CNN 的一個神經元<span style="color:#32CD32;">只會考慮 Receptive field 的大小</span> function set: ![image](https://hackmd.io/_uploads/r13zl4Xi0.png) CNN 是簡化版的 Self-attention,Self-attention 是複雜化的 CNN Self-attention 擁有比 CNN 更高的彈性 && 資料量小的話,彈性較大的模型更容易 overfitting $\rightarrow$ 資料量小的情境, Self-attention 更容易 overfitting ![image](https://hackmd.io/_uploads/rJCf-NQi0.png) ### Self-attention v.s. RNN RNN 相對於 Self-attention <span style="color:#32CD32;">更難去「記得」或「考慮」</span>前面的向量 RNN <span style="color:#32CD32;">無法平行計算</span>,但 Self-attention 可以 ![image](https://hackmd.io/_uploads/HJEabVmiR.png) ## graph 將 node 看做向量,而 edge 的資訊可以為 attention score 服務 node 間有 edge 代表那兩個 node 有相關,因此在計算 attention score 時<span style="color:#32CD32;">只需要計算有 edge(相關) 的 node(向量) </span>就行了 ![image](https://hackmd.io/_uploads/S165GN7o0.png) # Self-attention 變形與比較 Self-attention 的<span style="color:#32CD32;">缺點是運算量大</span>,因此有許多人去研究 Self-attention 的變形 雖然速度有上去了,但表現卻比原先的 Transformer 差 ![image](https://hackmd.io/_uploads/rJcxXNXoR.png)