# Seq2seq Model(Transformer)筆記 先閱讀:[Self Attention 筆記](https://hackmd.io/@wilson920430/rkHQMjmF6) ## Sequence-to-sequence (Seq2seq) 在先前 Self Attention 筆記中,有幾種Model輸出的模式 其中有一個就是 Seq2seq: ![Screenshot_20240124_155441](https://hackmd.io/_uploads/S1yLGHRKa.png) ![Screenshot_20240124_154940](https://hackmd.io/_uploads/rkef7bBCtp.png) 輸入一個 Sequence(一串 Vectors,總長未知) Model 也輸出一個 Sequence,但長度是 Model 決定的 可以應用於:語音辨識、翻譯、語音生成、ChatBot、文法分析、物件偵測等等。 ## Seq2seq Model structure ![Screenshot_20240124_161221](https://hackmd.io/_uploads/HymOUSRKT.png) 基本包含 Encoder 和 Decoder 兩個部份 ### Legacy Encoder ![Screenshot_20240124_163204](https://hackmd.io/_uploads/HJMzjHRKp.png) 在 Transformer 出現之前,Encoder 用的大多為 RNN 或 CNN ### Transformer Encoder ![Screenshot_20240124_163431](https://hackmd.io/_uploads/ryQosHAt6.png) Google 於 2017 年提出 Self Attention 機制和 Transformer 將 Self Attention 引入 Seq2seq model 中 但是除了常規的 Self Attention,還會加入以下處理: ![Screenshot_20240124_163926](https://hackmd.io/_uploads/BkoanS0Ka.png) 1. Residual:將輸入的 Vector 與 Self-Attention 相加 2. Layer Norm:與 [Feature Norm](https://hackmd.io/@wilson920430/B19I3vmF6) 不同,這裡是對一個 Vector 做 Normalization 經過 Self Attention、Residual Network + Norm 後 還會經過 Feed Forword Layer(Linear Fully Connected) 其中,也一樣會做 Residual 和 Layer Norm 以上經過 Self Attention 和 Feed Forword Layer 的處理為一個 Block 這樣的 Block 可以經過數次,即為 Transformer Encoder ### Decoder #### **Autoregressive** 從 Start token 開始,輸出是有順序性的,會把前一個輸出當作下一個輸入 最後會輸出一個 End Token 讓輸出停止 ![Screenshot_20240125_091335](https://hackmd.io/_uploads/H1BeU4yq6.png) ![Screenshot_20240125_085221-1](https://hackmd.io/_uploads/H1yBb4J9T.png) Block 與 Encoder 相近,除了以下幾點不同: 1. [Masked Attention](#%E7%AC%AC%E4%B8%80%E5%B1%A4%EF%BC%9A%E2%80%9CMasked%E2%80%9D-Attention%EF%BC%9A) 2. [Cross Attention with Encoder](#%E7%AC%AC%E4%BA%8C%E5%B1%A4%EF%BC%9ACross-Attention%EF%BC%9A) #### 第一層:"Masked" Attention: ![Screenshot_20240125_090131](https://hackmd.io/_uploads/HkOb7EJqT.png) 所謂的 Mask,就是假設在產生 $b^2$ 時,只考慮 $a^1$ 和 $a^2$ (只考慮左邊的輸入) 因為輸出的順序性,在產生 $b^2$ 時,還沒有 $a^3$ 和 $a^4$ 如下圖所示:input vector 會 feed 給右邊的 output ,但不會 feed 給左邊 ![Screenshot_20240125_090427](https://hackmd.io/_uploads/H1u6Q4kcp.png) **在 [訓練階段](#Training) 時,會直接把正確答案當作 Decoder input** **但是一樣會經過 Mask 處理,只考慮比自己左邊的 input,不會看到右邊的** #### 第二層:Cross Attention: ![Screenshot_20240125_094418](https://hackmd.io/_uploads/BJClp419p.png) 參考 Encoder 的輸出:query 來自 decoder 上一層的 output、key 來自 encoder 的 output #### 動態圖像 這裡以圖像展示 Encoding 和 Autoregressive decoding 的流程(來源:[Tensorflow](https://www.tensorflow.org/text/tutorials/transformer)): ![apply_the_transformer_to_machine_translation](https://hackmd.io/_uploads/Sy5lGcy5a.gif) #### **Non-Autoregressive** ![Screenshot_20240125_095129](https://hackmd.io/_uploads/SkgnAEkq6.png) * 方法一:會有一個 Predictor 來預測輸出長度,並且依照預測的長度輸入一堆 Start Token * 方法二:直接輸入很多 Start Token(數量就是輸出長度的上限),如果Model在中間生成 End Token,就直接忽略 End Token 之後的結果 **優點:輸出不需前後等待,而是平行處理,且可以控制輸出長度上限** **缺點:因為同步生成而無法將前面的output納入考量,有 multi-modality 問題** (如下圖翻譯,用 NAT 輸出可能會因為輸出的機率分佈相近而混雜各種結果) ![Screenshot_20240125_102210](https://hackmd.io/_uploads/HkgyLryq6.png) ## Training 訓練階段時,會直接將正確答案當作 Decoder input,稱為 Teacher Forcing: ![Screenshot_20240125_102626](https://hackmd.io/_uploads/S1uyDHy9p.png) 但是訓練時如果都只看過正確的答案,生成時可能會因為某一步錯誤而造成之後有錯誤的預測。 如下圖,在訓練階段,機器如果生成錯誤的字「氣」,下一個輸入依舊是給他正確的字「器」來繼續往後生成。但是實際使用時就不同了,Model 要用錯誤的「氣」來往後生成(Exposure Bias): ![Screenshot_20240125_103519](https://hackmd.io/_uploads/HyZa9H15p.png) 所以在訓練時可以隨機加入一些錯誤的資訊,此方法稱為 Schedule Sampling: ![Scheduled_Sampling](https://imgur-backup.hackmd.io/Z7SoqKe.png) 訓練時的輸入有一定比例使用自己生成的資料,而這個比例是動態調整的 在訓練一開始時用比較多正確答案,訓練到越後面用越多自己生成的結果 ## Tip: Beam Search ![Screenshot_20240125_111028](https://hackmd.io/_uploads/r1WE-81cT.png) 先前的機制都是直接選最好的路徑,稱作 Greedy Decoding(圖中紅色路徑) 但是有時候如果某幾步不選最好的,反而可以讓最後生成最佳的 output Beam Search(來源:[hackmd](https://hackmd.io/@shaoeChen/S1K4VwbOH#Beam-Search1)): ![Screenshot_20240125_111748](https://hackmd.io/_uploads/ryzgmLy9T.png) 在測試時需要考慮,訓練時不需要 * 定義Beam size * 在所有可能路徑中,保留幾條最好的 * 範例為2,代表保留兩條 * 第一步 * 有可能是A、B,剛好兩條,都保留 * 計算AA、AB、BA、BB四條路徑,保留兩條最好的 * 假設是AB、BB * 計算ABA、ABB、BBA、BBB四條路徑,取最好的 這種方式或許可以得到比Greedy Search還要好的結果