論文: [Attention Is All You Need](https://arxiv.org/abs/1706.03762) ## N-to-N Problem 大部分處理的資料都是一組向量(一張影像)對應到一個數值或類別的輸出;假設輸出不變,但輸入變成一排向量(一段聲音、一部影片、一個句子)呢? 例如: 處理一個句子,可以將每個詞轉為一個 One-hot encoding 向量,再去做 Word embedding;也有可能是一段聲音,透過 Sliding window 將固定長度訊號轉換為可用特徵(MFCC、SFFT...等)。 <div class="text-center"> <img src="https://hackmd.io/_uploads/S1qbcCvUR.png" style="width: 355px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/H1dzcAP8R.png" style="width: 355px; object-fit: cover;"> </div> &nbsp; 在實際應用上可以分為 * N 排向量、N 個數值 / 類別 * POS tagging: 輸入是一個詞向量、輸出是詞性 * 異常偵測: 輸入是固定長度聲音訊號、輸出是類別或分數 <div class="text-center"> <img src="https://hackmd.io/_uploads/rJcHpCDLR.png" style="width: 480px; object-fit: cover;"> </div> * N 排向量、一個數值 / 類別 * 語意分析: 輸入是一個句子(多個詞向量)、輸出是類別 * 語者辨認: 輸入是一段聲音(多個固定長度聲音訊號)、輸出是類別 <div class="text-center"> <img src="https://hackmd.io/_uploads/rJxO6CvUC.png" style="width: 480px; object-fit: cover;"> </div> * N 排向量、M 排向量(Sequence to sequence) * 序列生成、機器翻譯: 輸入是一個句子、輸出是一個句子 <div class="text-center"> <img src="https://hackmd.io/_uploads/BJNZ11_L0.png" style="width: 480px; object-fit: cover;"> </div> 首先,著重在第一類 N-to-N 的問題,假設要處理 Sequence labeling,每一個詞向量都對應到一個標籤,可以透過 FC layer 搭配窗格考慮上下文的關係;然而,若想要考慮不僅僅是上下文,而是整個 Sequence,如果此時仍然使用 FC layer 去處理,必須將 Window size 開得很大,導致需要學習的參數量很多,容易造成 Overfitting: <div class="text-center"> <img src="https://hackmd.io/_uploads/HJoObJOI0.png" style="width: 600px; object-fit: cover;"> </div> ## Attention Mechanism 為了讓模型能夠考慮到上下文,注意力機制想在做的事情就是==先以 Self-attention 來處理全局資訊,此時每一排輸入向量依然會對應到一排輸出向量,接著再用 FC layer 對輸出向量再做一次局部資訊處理==,如左下圖所示,也可以疊多個 Self-attention 去處理資訊,如右下圖所示: <div class="text-center"> <img src="https://hackmd.io/_uploads/rkwZmkdLR.png" style="width: 355px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/HJdFQkOUA.png" style="width: 355px; object-fit: cover;"> </div> &nbsp; ==Attention block 實際在做的事情就是將每一排向量和其他排向量產生關聯==,舉例來說,$b^1$ 是考慮了 $a^1,a^2,a^3,a^4$ 所產生的,其中,$b^1$ 是如何產生的? 1. 根據 $a^1$,在很長的 Sequence 中找出和它相關的向量,並且計算一個分數 $\alpha$,用這個分數來決定哪些詞向量與 $a^1$ 強相關 <div class="text-center"> <img src="https://hackmd.io/_uploads/HyF5zbOLA.png" style="width: 480px; object-fit: cover;"> </div> 其中,計算分數的方式有二種: 點乘(Dot product)和點加(Additive) * 點乘: $\alpha=q \cdot k=(W^q a^q) \cdot (W^k a^k)$ * 點加: $\alpha=W \cdot tanh(q+k)=W \cdot tanh(W^q a^q+W^k a^k)$ <div class="text-center"> <img src="https://hackmd.io/_uploads/SksGmWOU0.png" style="width: 480px; object-fit: cover;"> </div> 2. 更詳細來說,我們會稱 Query $=a^1$、Key $=a^2,a^3,a^4$;Query 會和自己,以及所有的 Key 都計算一個分數,再經過 Softmax 輸出 Attention score: \begin{gathered} a_{1,1}=q^1 \cdot k^1 \\ a_{1,2}=q^1 \cdot k^2 \\ a_{1,3}=q^1 \cdot k^3 \\ a_{1,4}=q^1 \cdot k^4 \\ a_{1,1}^\prime,a_{1,2}^\prime,a_{1,3}^\prime,a_{1,4}^\prime=softmax(a_{1,1},a_{1,2},a_{1,3},a_{1,4}) \end{gathered} <div class="text-center"> <img src="https://hackmd.io/_uploads/HJT-NbOL0.png" style="width: 480px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/r1mdVbuIC.png" style="width: 480px; object-fit: cover;"> </div> 3. 最後,每一排詞向量都還會和各別矩陣相乘得到 Value,再由剛才計算出的分數來給予權重、分配資訊重要性,因此分數越高者,和 $a^1$ 的關聯性就會由它的向量來主導 \begin{gathered} b^1=a_{1,1}^\prime v^1+a_{1,2}^\prime v^2+a_{1,3}^\prime v^3+a_{1,4}^\prime v^4 \end{gathered} <div class="text-center"> <img src="https://hackmd.io/_uploads/rJlEB-u8R.png" style="width: 480px; object-fit: cover;"> </div> 其中,$b^1$ 到 $b^4$ 並不需要依序產生,是可以一次同時做計算: <div class="text-center"> <img src="https://hackmd.io/_uploads/SJyfOE5LC.png" style="width: 600px; object-fit: cover;"> </div> 假設我們由 $q,k,v$ 三組向量的計算角度出發,$q^i=W^q a^i$ 其實都是共用一組 $W^q$,那麼矩陣運算可排列如下: <div class="text-center"> <img src="https://hackmd.io/_uploads/HJ6Wkrq8C.png" style="width: 355px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/SJkhyrqIR.png" style="width: 355px; object-fit: cover;"> </div> 同理,$k^i=W^k a^i$、$v^i=W^v a^i$ 也都可以矩陣表示如下: \begin{gathered} \ [q^1~q^2~q^3~q^4]=W^q[a^1~a^2~a^3~a^4] \rightarrow Q=W^q I \\ \ [q^1~q^2~q^3~q^4]=W^k[a^1~a^2~a^3~a^4] \rightarrow K=W^k I \\ \ [q^1~q^2~q^3~q^4]=W^v[a^1~a^2~a^3~a^4] \rightarrow V=W^v I \end{gathered} <div class="text-center"> <img src="https://hackmd.io/_uploads/BJyEmS5IC.png" style="width: 600px; object-fit: cover;"> </div> 分數的部分,也可以將 $k^1,k^2,k^3,k^4$ 拼成一個矩陣,乘上 $q^1$ 向量去做計算: \begin{gathered} \begin{bmatrix} a_{1,1} \\ a_{1,2} \\ a_{1,3} \\ a_{1,4} \end{bmatrix}= \begin{bmatrix} k^1 \\ k^2 \\ k^3 \\ k^4 \end{bmatrix} q^1 \end{gathered} <div class="text-center"> <img src="https://hackmd.io/_uploads/HkPQEH5IR.png" style="width: 600px; object-fit: cover;"> </div> 除了 $q^1$ 外,$q^2,q^3,q^4$ 也都要計算,讓他們排排站相乘後,就可以得到一個 Attention score 的矩陣;其中,不一定是取 $softmax(‧)$,其餘 Activation function 也都可以: \begin{gathered} A^\prime=\begin{bmatrix} a_{1,1}^\prime~~ a_{2,1}^\prime~~ a_{3,1}^\prime~~ a_{4,1}^\prime \\ a_{1,2}^\prime~~ a_{2,2}^\prime~~ a_{3,2}^\prime~~ a_{4,2}^\prime \\ a_{1,3}^\prime~~ a_{2,3}^\prime~~ a_{3,3}^\prime~~ a_{4,3}^\prime \\ a_{1,4}^\prime~~ a_{2,4}^\prime~~ a_{3,4}^\prime~~ a_{4,4}^\prime \end{bmatrix} \xleftarrow{softmax} A= \begin{bmatrix} a_{1,1}~~ a_{2,1}~~ a_{3,1}~~ a_{4,1} \\ a_{1,2}~~ a_{2,2}~~ a_{3,2}~~ a_{4,2} \\ a_{1,3}~~ a_{2,3}~~ a_{3,3}~~ a_{4,3} \\ a_{1,4}~~ a_{2,4}~~ a_{3,4}~~ a_{4,4} \end{bmatrix}= \begin{bmatrix} k^1 \\ k^2 \\ k^3 \\ k^4 \end{bmatrix} [q^1~q^2~q^3~q^4] \end{gathered} <div class="text-center"> <img src="https://hackmd.io/_uploads/ByNxLHqI0.png" style="width: 355px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/B1f6SH5U0.png" style="width: 355px; object-fit: cover;"> </div> &nbsp; 最後,根據 Attention score 去分配 $v^i$ 的權重並輸出: \begin{equation} \begin{cases} b^1=a_{1,1}^\prime v^1+a_{1,2}^\prime v^2+a_{1,3}^\prime v^3+a_{1,4}^\prime v^4 \\ b^2=a_{2,1}^\prime v^1+a_{2,2}^\prime v^2+a_{2,3}^\prime v^3+a_{2,4}^\prime v^4 \\ b^3=a_{3,1}^\prime v^1+a_{3,2}^\prime v^2+a_{3,3}^\prime v^3+a_{3,4}^\prime v^4 \\ b^4=a_{4,1}^\prime v^1+a_{4,2}^\prime v^2+a_{4,3}^\prime v^3+a_{4,4}^\prime v^4 \end{cases} \rightarrow O= \begin{array} \ [b^1~b^2~b^3~b^4]=[v^1~v^2~v^3~v^4] \begin{bmatrix} a_{1,1}^\prime~~ a_{2,1}^\prime~~ a_{3,1}^\prime~~ a_{4,1}^\prime \\ a_{1,2}^\prime~~ a_{2,2}^\prime~~ a_{3,2}^\prime~~ a_{4,2}^\prime \\ a_{1,3}^\prime~~ a_{2,3}^\prime~~ a_{3,3}^\prime~~ a_{4,3}^\prime \\ a_{1,4}^\prime~~ a_{2,4}^\prime~~ a_{3,4}^\prime~~ a_{4,4}^\prime \end{bmatrix} \end{array} \end{equation} <div class="text-center"> <img src="https://hackmd.io/_uploads/SkDRhSq8R.png" style="width: 355px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/Hkk-aHcUR.png" style="width: 355px; object-fit: cover;"> </div> &nbsp; 整體矩陣運算流程如下圖,其中真正要訓練的只有權重矩陣 $W^q,W^k,W^v$: <div class="text-center"> <img src="https://hackmd.io/_uploads/rkWgD89IA.png" style="width: 600px; object-fit: cover;"> </div> ## Multihead Attention 上述介紹的都是單一 Head,通常在翻譯或語音辨識領域,多頭注意力機制會有比較好的表現,可以視為多個 $q$ 代表著多個種類的相關性計算,而要有幾個 Head 則是可以調整的超參數: <div class="text-center"> <img src="https://hackmd.io/_uploads/HkYjnNGDR.png" style="width: 600px; object-fit: cover;"> </div> &nbsp; 舉例來說,如果想要有二個 $q^{i,1},q^{i,2}$,則各自都會有自己的權重矩陣 $W^{q,1},W^{q,2}$,而在計算的時候,1 和 1 自己計算、2 和 2 自己計算: <div class="text-center"> <img src="https://hackmd.io/_uploads/rk61ANfDC.png" style="width: 355px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/rJyxANMDR.png" style="width: 355px; object-fit: cover;"> </div> &nbsp; 而最後的輸出則是將 $b^{i,1}, b^{i,2}$ 向量排列後,乘上輸出矩陣 $W^o$ 即可: <div class="text-center"> <img src="https://hackmd.io/_uploads/Sk207PGDA.png" style="width: 600px; object-fit: cover;"> </div> ## Encoder 上述為 Transformer 最主要計算的自注意力機制,而整個 Transformer 基本上是一組 Encoder 和 Decoder 的架構: <div class="text-center"> <img src="https://hackmd.io/_uploads/rkNxDKxW1g.png" style="width: 550px; object-fit: cover;"> </div> &nbsp; 其實,Encoder 也可以是 CNN 或 RNN 的架構,端看藥用怎麼設計去達成上下文關聯,而 Transformer 用的是 Attention 機制: <div class="text-center"> <img src="https://hackmd.io/_uploads/rJ-UDFlZke.png" style="width: 550px; object-fit: cover;"> </div> 在上圖的 Encoder 中,$N\times$ 的意思代表含有多個 Attention block,每一個 Attention block 在做的事情包含以下: * 將輸入送進 Self-attention -> 輸出 $a$ * Residual connection -> 輸出 $a+b$ * 對 $a+b$ 做 Layer normalization -> 輸出 $c$ * 將 $c$ 送進 FC layer -> 輸出 $d$ * Residual connection -> 輸出 $d+e$ * 對 $d+e$ 做 Layer normalization -> 輸出 $f$ <div class="text-center"> <img src="https://hackmd.io/_uploads/H1FhoYeW1e.png" style="width: 550px; object-fit: cover;"> </div> &nbsp; 再將上述的操作流程對照一下原始論文架構圖,而實際上再將輸入送進 Encoder 前還會加入 Positional encoding 讓向量間也學習到順序關係: <div class="text-center"> <img src="https://hackmd.io/_uploads/r1pShFlWyl.png" style="width: 550px; object-fit: cover;"> </div> <blockquote> * Positional encoding Attention block 主要就是計算向量間的相似度關係,但並沒有順序或空間上的概念,因此實務上會在輸入向量 $a^i$ 前加入 $e^i$ 的位置向量,這個位置向量長度和 $a^i$ 相同,讓模型自己學習上下文之間的關聯: <div class="text-center"> <img src="https://hackmd.io/_uploads/BJdLhD6s0.png" style="width: 500px; object-fit: cover;"> </div> * Layer normalization(平均數=0、標準差=1) 模型中並不是使用一般的 BN,先用一般的二維資料來做說明,水平方向是不同的 Feature、垂直方向是資料筆數: * (藍色)BN 是針對每個 Feature,對所有資料正規化 * (黃色)LN 是針對每筆資料,對所有 Feature 做正規化 <div class="text-center"> <img src="https://hackmd.io/_uploads/B1Mnlh6eJl.png" style="width: 500px; object-fit: cover;"> </div> 而目前碰到的文字資料是屬於三維資料,水平方向是文字數量、垂直方向是資料筆數、入平面方向是不同的 Feature(每一個字詞都是一條向量): * BN 是針對每個 Feature 做正規化,也就是在一個 Feature dimension 上切一個面 * LN 是針對每筆資料做正規化,也就是在一筆資料上去切一個面 <div class="text-center"> <img src="https://hackmd.io/_uploads/Sy0tM2pe1x.png" style="width: 500px; object-fit: cover;"> </div> 會這樣做的最主要原因是: * 每個句子的長度不同,通常會以最長的句子作為標準,而長度不足的地方就補零,假設今天句子長度變化較大、且又是小批量訓練的狀況下,==用 BN 算出的平均值和標準差會有明顯的震盪,有可造成訓練困難== * 在推論時會使用到學習的平均值和標準差,==假設今天預測的樣本是一個長度更長的句子,是在訓練上沒有看過的樣本長度,那麼訓練的平均值和標準差,在預設上就不會起到很好的效果== 然而,在 LN 就沒有這種問題,因為訓練時是針對各別資料去做的,得到的平均值和標準差和長度的相依關係就沒那麼明顯。 * Scaled Dot-product 實務上,在送入 Softmax 去得到 Attention score 前,還會除以 $\sqrt{(d_k)}$: * 樣本長度短的時候,有沒有除上這組係數沒有差別 * 樣本長度長的時候,因為向量長度長,做點積運算後累積的值容易變得更大或更小,在 Softmax 函數終究會往二端跑,容易有 Gradient vanish 的問題 <div class="text-center"> <img src="https://hackmd.io/_uploads/SkBCA3Tl1l.png" style="width: 650px; object-fit: cover;"> </div> </blockquote> ## Decoder - Masked Attention 接下來則是 Decoder 的部分,先再看一次架構圖: <div class="text-center"> <img src="https://hackmd.io/_uploads/HklAlo-Wke.png" style="width: 600px; object-fit: cover;"> </div> &nbsp; 假設我們將 Decoder 中間的 Multi-Head Attention 拿掉,其實 Decoder 和 Encoder 幾乎是一模一樣的結構: <div class="text-center"> <img src="https://hackmd.io/_uploads/BJN3loWb1g.png" style="width: 600px; object-fit: cover;"> </div> 此外,Decoder 和 Encoder 有一個很大的差別,==在於 Encoder 的訓練是看全部的上下文去找出關聯,而常見的的 Decoder 是只看目前僅有的向量去推論下一個向量出現的機率,是有順序性的==,也就是採用 Autoregreesive 的方式。 此外,輸出的結果可以是一個單字、字母、字根或是其他組合,端看如何設計(假設是英文,輸出字母只有 26 個維度可能還行,但輸出單字可能就有趨近無限種可能): <div class="text-center"> <img src="https://hackmd.io/_uploads/ry1SPwTzkx.png" style="width: 600px; object-fit: cover;"> </div> 除了訓練的資料外,也還會加入 BEGIN(Begin of sentence, BOS)和 END(End of sentence, EOS)這樣的 Token 去幫助模型得知開始和結束,整體訓練的狀況如下: * 看到 [BOS],預測 [機] * 看到 [BOS, 機],預測 [器] * 看到 [BOS, 機, 器],預測 [學] * ... <div class="text-center"> <img src="https://hackmd.io/_uploads/SyDxIoZWJx.png" style="width: 320px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/Sywg8sbbyg.png" style="width: 320px; object-fit: cover;"> </div> &nbsp; Decoder 看到的輸入,是自己在前一個時間點看到的輸出,==也就是 Decoder 會把自己的輸出當成接下來的輸入==,因此 Decoder 在推論時,是有可能看到錯誤的輸入,因為都是自己在前一個時間點輸出的,也就是一步錯步步錯的概念: <div class="text-center"> <img src="https://hackmd.io/_uploads/HkSRSoWWkx.png" style="width: 600px; object-fit: cover;"> </div> &nbsp; 然而,訓練時如何讓 Decoder 按照順序去產生呢? 可以看到 Decoder 架構圖中的 Mask Multi-Head Attention,==在做前 N 個維度的輸出時,把包含 N+1 維度以後的輸出資訊都遮住==,也就是 Mask 的意思,只讓前 N 個維度的輸出和前 N 個維度做關聯: <div class="text-center"> <img src="https://hackmd.io/_uploads/BJN3loWb1g.png" style="width: 600px; object-fit: cover;"> </div> &nbsp; 也就是計算 Attetnion score 時參考的輸入向量不同,一般的 Attention 在任何階段都是參考全部的上下文,可以用到完整的 Input sequence 資訊,而 Masked attention 僅參考上文做下文的推論: <center> | | Attention | Masked attention| | --- | --- | --- | | $b^1$ | $[a^1,a^2,a^3,a^4]$ | $[a^1]$ | | $b^2$ | $[a^1,a^2,a^3,a^4]$ | $[a^1,a^2]$ | | $b^3$ | $[a^1,a^2,a^3,a^4]$ | $[a^1,a^2,a^3]$ | | $b^4$ | $[a^1,a^2,a^3,a^4]$ | $[a^1,a^2,a^3,a^4]$ | </center> <div class="text-center"> <img src="https://hackmd.io/_uploads/SyIIvsBZJg.png" style="width: 300px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/ByUUPjS-kg.png" style="width: 300px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/HkyhKoSW1g.png" style="width: 300px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/rJJ3FsrZke.png" style="width: 300px; object-fit: cover;"> </div> &nbsp; 上述的 Decoder 是屬於 Autoregressive(AT),也有另一種是 Non-autoregressive(NAT),它能夠一次將整個輸出都生成出來而非有順序性的生成,例如一次性吃四個 BEGIN 的 Token,再一次性得到四個輸出來組成一個 Sequence。然而,輸出的長度要如何控制呢? 要怎麼知道要輸入幾個 BEGIN 給 Decoder? * 第一種作法,可能是另外學習一個 Predictor 吃 Encoder 的輸入,拿來預測輸出的長度 * 第二種作法,是先確認輸出長度不會大於多少,就丟這麼多 Token 給 Decoder,最後只拿 END 之前的輸出組成 Output sequence NAT 的好處在於: * 效率提升(平行計算) * 能控制輸出的長度,例如想要用更少的句子去做文章摘要,將 Predictor 輸出數值除以二即可 <div class="text-center"> <img src="https://hackmd.io/_uploads/BksyhAcWyx.png" style="width: 600px; object-fit: cover;"> </div> ## Decoder - Cross Attention Cross Attention 發生在 Encoder 與 Decoder 之間。在 Decoder 在做完 Masked attention 後,會搭配 Encoder 的輸出做 Cross attention: <div class="text-center"> <img src="https://hackmd.io/_uploads/BkLO-1iW1l.png" style="width: 600px; object-fit: cover;"> </div> &nbsp; 以 AT Decoder 為例,操作步驟如下: 1. Encoder 吃一排輸入向量做 Attention 後輸出 $[a^1,a^2,a^3]$,再經過矩陣計算轉成一組 $Key$ 2. Decoder 吃一個 BEGIN Token,經過 Masked attetion 和矩陣計算轉成一個 $q$ 3. 拿 $q$ 和 $[k^1,k^2,k^3]$ 關聯並過 Softmax 去得到 Attention score,也就是 $[\alpha_1^\prime,\alpha_2^\prime,\alpha_3^\prime]$ 4. 將 $[a^1,a^2,a^3]$ 經過矩陣計算轉成一組 $Value$ 5. 依照 Attention score 去做權重得到 $v$ 7. 後續會再將 $v$ 丟到一個 Fully connected network 去得到輸出 <div class="text-center"> <img src="https://hackmd.io/_uploads/rkJPK1oZ1x.png" style="width: 320px; object-fit: cover;"> <img src="https://hackmd.io/_uploads/Sk8tSJsZ1g.png" style="width: 380px; object-fit: cover;"> </div> &nbsp; ==上述步驟稱作 Cross attention,也就是 $q$ 來自 Decoder、$[k,v]$ 來自 Encoder,意即 Decoder 依照 $q$ 去 Encoder 當中抽取資訊出來==,假設 Decoder 第一步的輸出為「機」,第二步 Decoder 的輸入就會變為「BEGIN、機」,然後按照上述步驟再做 Cross attention: <div class="text-center"> <img src="https://hackmd.io/_uploads/rJveFyi-1x.png" style="width: 600px; object-fit: cover;"> </div> &nbsp; 在 Transformer 的原始設計中,Decoder 只使用了 Encoder 最後一層輸出,事實上,兩者之間的互動可以發生在不同層之間。 ## Decoder - Training Decoder 在訓練時的 Input 是吃 GT,而非自身按順序生成的前項結果,稱作是 Teacher forcing: * 給 GT=[BOS],輸出向量和 [機] 做 CE loss * 給 GT=[BOS, 機],輸出向量和 [器] 做 CE loss * 給 GT=[BOS, 機, 器],輸出向量和 [學] 做 CE loss * ... <div class="text-center"> <img src="https://hackmd.io/_uploads/BJpD6Ppz1e.png" style="width: 600px; object-fit: cover;"> </div> &nbsp; 然而,實際上在使用 Decoder 做推論的時候並沒有 GT 當作輸入,而是按自身順序生成的前項結果,顯然在訓練和推論上有輸入上的落差,因此在訓練時會加入一些技巧: * Copy mechanism * Copy 原本輸入的一部分作為輸出,有些詞彙的出現次數不多或沒有特別意義,例如人名 <div class="text-center"> <img src="https://hackmd.io/_uploads/SJVpfpfXyg.png" style="width: 480px; object-fit: cover;"> </div> * 或者在做文章摘要時,如何正確複製某段資訊也是很重要的事情 <div class="text-center"> <img src="https://hackmd.io/_uploads/HJZAf6G7Jl.png" style="width: 480px; object-fit: cover;"> </div> * Guided attention * Attention 太過彈性,導致輸出結果不盡人意,可以加入一些限制,例如強迫 Attention 的權重峰值,落在相對應的位置 <div class="text-center"> <img src="https://hackmd.io/_uploads/rk6vXaz7kl.png" style="width: 480px; object-fit: cover;"> </div> * 修正 Decoder 產生序列輸出的方法 * Brutal force * 計算所有可能輸出的機率,最後挑選機率最大的 * 可得到最佳解,但是計算量太大,難以實現 * Greedy * 只選擇當前機率最大的結果 * 難以得到最佳解 相較於一般 Greedy 不一定有機會找到最佳解,可以使用 Beam search 這樣的搜尋方式: * 保留幾個最佳的候選結果作後續計算,最後挑選機率最大的 * 近似最佳解,計算量也可接受 <div class="text-center"> <img src="https://hackmd.io/_uploads/B1q-r6Mmkl.png" style="width: 480px; object-fit: cover;"> </div> 另外,也可以使用 Sampling 的方法: * 根據輸出的概率,取樣得到輸出 * 輸出帶有隨機性 <div class="text-center"> <img src="https://hackmd.io/_uploads/rk0zr6fmkx.png" style="width: 480px; object-fit: cover;"> </div> 其中,Beam search 和 Sampling 各有適合的應用場景,前者適合答案明確的任務,像是語音辨識或文件搜尋,而後者適合需要隨機性的任務,像是文本創作、TTS。 * 修改 Evaluation metric * 模型的訓練損失與評估,使用的是不同的衡量基準,可能造成模型優化的方向,不是以最大化 BLEU score,因此可以針對驗證集設計不同的 Evaluation 方式 <div class="text-center"> <img src="https://hackmd.io/_uploads/Sk61Ppz71g.png" style="width: 480px; object-fit: cover;"> </div> * Exposure bias * 是由 Teacher forcing 中,訓練與推論不一致所產生,可以在 Teacher forcing 中加入一些雜訊(稱為 Schedule sampling) <div class="text-center"> <img src="https://hackmd.io/_uploads/SJtnDaMmkl.png" style="width: 480px; object-fit: cover;"> </div> * Schedule sampling 的技巧最早被用於 RNN,但當用於 Transformer 時會降低其平行化的能力,因此有其他修改版本 <div class="text-center"> <img src="https://hackmd.io/_uploads/rytpwpMQke.png" style="width: 480px; object-fit: cover;"> </div> ## Reference * [Transformer论文逐段精读](https://www.youtube.com/watch?v=nzqlFIcCSWQ&ab_channel=%E8%B7%9F%E6%9D%8E%E6%B2%90%E5%AD%A6AI) * [[課程筆記] 機器學習2021(李弘毅) L13. Transformer (下)](https://blog.csdn.net/JYLin_master/article/details/124699353) * [【機器學習2021】Transformer (上)](https://www.youtube.com/watch?v=n9TlOhRjYoc&ab_channel=Hung-yiLee) * [【機器學習2021】Transformer (下)](https://www.youtube.com/watch?v=N6aRv06iv2g&t=811s&ab_channel=Hung-yiLee) * [【機器學習2021】自注意力機制 (Self-attention) (上)](https://www.youtube.com/watch?v=hYdO9CscNes&t=1375s&ab_channel=Hung-yiLee) * [【機器學習2021】自注意力機制 (Self-attention) (下)](https://www.youtube.com/watch?v=gmsMY5kc-zw&ab_channel=Hung-yiLee)