# Transformer ## Attention is all you need  **Attention** 架構即為模仿人類專注的行為,有點類似挑重點,目的是為了讓電腦能更專心地在處理目前任務的中心。舉例來說 <font color="red">[ 胖虎叫大雄去買漫畫,回來慢了就打他 ]</font> ,這句話最後的他在我們人類的看法裡是指大雄,但對電腦來說文章中有三個名詞,它不知道 <font color="red">[ 他 ]</font> 指的是誰,這時就需要注意力機制讓電腦去觀察上下文。  >本句的 **self-Attention(自專注)** 結果,從圖中可以看到,電腦認為 <font color="red">[ 他 ]</font> 跟 <font color="red">[ 雄 ]</font> 的關係最為接近(顏色也最深)。 論文中提到的 **Scaled Dot-Product Attention** 的算法:  ### Abstract **Transformer** 的主要架構分為 **Encoder** 跟 **Decoder** ,粗淺的說 **Encoder** 的功能為編碼, **Decoder** 為解碼。 **Encoder** : **Encoder** 的任務是將輸入轉化為語意向量,透過 **self-Attention** 的機制,讓向量中包含的語意能更完整,在後續的解碼中,也能更精確。 **Decoder** : (以語言翻譯為例) **Decoder** 在接收到 **Encoder** 輸出的語意向量後藉由 **Multi-head Attention** 選擇出字典中 **Decoder** 認為機率高的單字或詞。 ### Input : Input Embedding, Positional Encoding 在進入主要模型前,<font color="red">我們需要先讓文字轉換成電腦能看懂的表示方式。</font>在這裡我們會處理文字本身和順序的意義。 #### Input Embedding :  > 每個 **Row** 儲存 **Vocabulary** 中對應字詞的 **Embedding** 。 **Vocabulary Size** 和 **Embedding Size** 會隨著不同模型有所變化。 > > 圖片出處https://jalammar.github.io/illustrated-gpt2/ 文字在到這之前,需<font color="red">先經過 **Tokenization** (文字斷詞 => ID)</font>。 再由<font color="red">ID對應 **Row** 取得 **Embedding** 。 **Embedding** 會隨著模型訓練逐漸完善</font>,可以想像成每個字的 **Embedding** 都是由n個神經元來做紀錄,而 **Token Embedding** 則是裝著整個 **Vocabulary Embedding** 的矩陣。 每次ID對應到的 **Row** 因為被啟動,資料通過,會在 **Backpropagation** 被更新。 #### Positional Encoding :  > **Row**儲存對應順序的**Embedding**。**Context Size**和**Embedding Size** 同樣會隨著不同模型有所變化。 > > 圖片出處https://jalammar.github.io/illustrated-gpt2/ <font color="red">因為 **Attention** 是一次處理整個輸入,沒有前後關係,所以在這裡我們需要自己加上去。</font> 取得序意義很簡單,由文字先後順序對應 **Row** 取得 **Embedding** 。不過要注意一點,<font color="red">這裡的 **Embedding Size** 要和先前 **Token Embedding** 相同。</font>我們會<font color="red">做相加的動作</font>,將先前的 **Token Embedding** 和 **Positional Encoding** 加起來(第一維和第一維相加...)。 <font color="red">這樣Input就有了文字本生和順序的意義。(非常神奇:open_mouth:)</font> **Positional Encoding** 同樣也會隨著模型訓練逐漸完善。 ### # **Encoder**  >Encoder主體為灰色框框的範圍。 ## Abstract 如同一開始所說,**Encoder** 主要功能為分析語意,利用 **Self-Attention** 找出文字之間的關西,再經過 **Feed-Forward** 調適,讓語意更為飽滿,以下會解釋是如何達成的。 ## Self-Attention 開使講解實際操作以前,我們先將主要概念講清楚。 我們先回顧一下先前 **Input** 那邊的概念。<font color="red">我們為了讓電腦看得懂文字,每個字都由 **n** 維的向量表示</font>(**n = Embedding size**),再來<font color="red">為了賦予順序的意義</font>,我們<font color="red">將 **Position Encoding** 以加法的方式加上去</font>,至此那些文字就擁有了順序意義。 <font color="red">這裡的重點是加法這個動作</font>,想要讓他有順序意義,就<font color="red">先產生了單純表示順序的 **Embedding** ,再合原資料作相加賦予上去。</font> 到了 **Self-Attention** 這裡,<font color="red">我們想讓資料加上字和字之間的關西</font>,從而讓電腦理解類似於"他"這種文字,在文章中出現時到底在指什麼事物。 延續賦予 **Position Encoding** 的想法。假如我們想要讓<font color="red">[ 胖虎叫大雄去買漫畫,回來慢了就打他 ]</font> 之中的 <font color="red">[ 他 ]</font>,有和其他字的關係,只要有每個字的 **Embedding** ,還有他們對於[ 他 ]的權重,在和權重相乘後,和[ 他 ]的 **Embedding** 做相加便是賦予了[ 他 ]和其他字之間的關係。 實際操作共有三個步驟: 1. 產生 **Query、Key、Value**。 2. **Query** 和 **Key** 做點積得到每個 **Key** 對於 **Query** 的 **權重**。 3. **Value** 和 **權重** 做點積後和 **Query** 相加得到 **Self-Attention** 結果。 **Query** : 我們想賦予關系的字詞。 **Key、Value** : **Query**所在的文章or句子or前後文...。 ### 1. Create Query、Key、Value **Query、Key、Value** 分別有各自對應的 **Weight Matrix** ,用來對 **Embedding** 做調適。(同樣會隨著模型訓練成長) 和對應的資料作點積後得到正式的 **Query、Key、Value**。  >**x1~x4** 為字詞的語意向量。因為我們其實要對每個字都賦予字詞之間的關西,所以大家都會有一組**Q、K、V**。 > >圖片出處https://jalammar.github.io/illustrated-gpt2/ ### 2. Score **Query** 和 **Key** 做點積得到每個 **Key** 對於 **Query** 的 **權重(Score)**。 會經過 **Softmax** 讓加總為 **100%**。  > >圖片出處https://jalammar.github.io/illustrated-gpt2/ ### 3. Sum **Value** 和對應的 **權重** 做相乘,再將他們做總和(**Z**),也就是我們計算出的字詞關西。之後把它和 **X** 相加就是賦予意義了(**Add & Norm**)。  > 有一排 **Value** 深淺不一,用來表示他們在最終結果所佔的比例。 > > 圖片出處https://jalammar.github.io/illustrated-gpt2/ 以上都是以單一字詞做舉例,實際上是一次處理全部,**Query、Key、Value** 都是矩正,不過步驟是一樣的。  >**Attention** 的計算(以陣列表示) > >圖片出處https://jalammar.github.io/illustrated-transformer/ ### Multi-head Attention **Encoder** 的圖上寫的是 **Multi-head Attention** ,我們到目前說的都是單一 **Head** 的處理方式,不過 **Multi-head** 實際上也是做一樣的事,只是在做上續處理的時候,會先 **Reshape Q、K、V**,原本每個字都是 **1 x N** 維表示,改成 **Heads x (N / Heads)**。  >這裡 **Heads** = 12,原 **Embedding size** = 768 > >圖片出處https://jalammar.github.io/illustrated-gpt2/ 完事後再 **Reshape** 回去。  > >圖片出處https://jalammar.github.io/illustrated-gpt2/ 不過其實 **Reshape** 不能算是真的復原,畢竟就只是把已經分開處理的東西頭尾相接而已,**Embedding** 要再經過調適才可以。(調適用的 **Weight Martix** 同樣會隨著訓練成長)  > >圖片出處https://jalammar.github.io/illustrated-gpt2/ ## Feed Forward 經過 **Attention** 之後,**Encoder** 會利用 **Feed Forward** 部分再次對 **Embedding** 做調適。 **Feed Forward** 分為兩個部分: 1. 將 **Embedding** 擴充到四倍大的 **Weight Matrix**。用以分析、調適前面 **Attention** 所學知識。  >圖片出處https://jalammar.github.io/illustrated-gpt2/ 2. 將 **Embedding** 復原成正常大小的 **Weight Matrix**,做最後的整合。  >這裡的結果會再次以相加的動作將所學賦予到資料上(**Add & Norm**) > >圖片出處https://jalammar.github.io/illustrated-gpt2/ 到這裡 **Encoder** 就算是結束了。輸出的資料看是要接到下一個 **Encoder**,精益求精。還是將這經過多次優化的語意向量拿來做後續運用就看各人了。 ## Model Implementation : BERT # **Decoder**  >Decoder主體為灰色框框的範圍。 ## Abstract **Decoder** 和 **Encoder** 的架構差不多,只是多了一層的 **Attention** 。**Decoder** 接收到 **Encoder** 所產生的語意空間 **(所有的)** 後, **Decoder** 會透過 **Multi-Head Attention** 決定產生哪些新的句子,並決定 **Encoder** 傳過來的資訊那些部分是重要的。 **Decoder** 的運作: 1. **輸入** : **Decoder** 有兩端輸入,<font color='red'>一端來自 **Encoder** 輸出的 **Key** 跟 **Value**,一端則為跟 **Encoder** 一樣的原資料。</font>來自 **Encoder** 的資料輸入中間的 **Attention Section**,而 **Query** 則來自 **Decoder** 的原生資料 (前一個 **Attention** ,訓練時帶有答案,預測並沒有) 。 2. **解碼** : 在實務的解碼上,<font color='red'>訓練和預測不一樣。</font>訓練時將資料一次解碼出來,因為解碼出來的資料是整筆的,所以會用 **Mask** 遮蔽未來的答案。而預測沒有答案,所以會一個一個預測。 3. **輸出** : 輸出則隨著 **time_step** <font color='red'>逐步輸出</font>,以中文處理為例,則為一個詞一個詞輸出。 >詳細的模型運作請見 **Output** ## Mask **Mask** 的主要功用是將陣列中的某部分 **Vector** 遮蔽,就像考試的時候不會知道正確答案一樣,將一部分的答案失效。在 **Transformer** 中有兩種 **Mask** ,分別為在 **Encoder** **Scaled Dot-Product Attention** 區塊中的 **Padding-Mask** 跟 **Decoder Self-Attention** 的 **Sequence Mask**。總而言之, **Mask** 的主要功用為 <font color="red">**1. 處理非特定長度的資料 2. 遮蔽特定標籤**。</font> 1. **Padding Mask(處理非特定長度)** 在處理資料的時候常會遇到非特定長度的資料 (e.g. 語言) ,神經元的數量是特定的,以文章為例,第一句話為10個字,第二句話為15個字,但是神經元有15個,那在處理第一句話的時候就會出錯。**Padding** 就是為了處理上述情況而誕生。 在實務上的實現方式就是在不足的地方補0。 **Padding Mask** 中的值皆為布林值,false即為資料存在的地方。 2. **Sequence Mask(遮蔽特定資料)** **Sequence Mask** 的目的是為了讓模型不能參考未來的資訊,在訓練的時候, **Decoder** 會將所有的資訊先解碼,造成模型能夠參考,但是基於順序,模型不該在時間 **T** 的時候就知道時間 **T+1** 的內容,就像人在讀書的時候,還在讀第一章的內容不可能知道第二章的內容。 在實務上我們會先生成一個矩陣,將上三角的值全部設為0,再將這個矩陣套用在每一筆資料上。   >實際的 **Sequence Mask** 應用範例。 > >圖片出處https://zhuanlan.zhihu.com/p/139595546 ## Output  >圖片出處http://jalammar.github.io/illustrated-transformer/ 當 **Encoder** 處理完語意的包裝,會將數據傳送給 **Decoder** 中間的 **Multi-Head Attention** ,成為 **Key** 和 **Value** ,而 **Multi-Head Attention** 的 **Query** 則由上一級的 **Masked Multi-Head Attention** 提供 **Decoder** 的 **Self-Attention**,最後再由 **Feed Forward** 做調適。 以上就是 **Decoder** 模型中的數據流,但是 **Decoder** 最後的輸出是一個向量,要怎麼成為我們所看到的句子呢? <font color='red'>**所以我們會在後端接上一個Linear和Softmax。**</font>  >**Linear** : 通常為一個 **Fully Connected Layer(全連接層)** 在 **Transformer** 中的功能就像分類器一樣,決定在時間 **T** 的格子應該填入哪組詞。 > >圖片出處https://kknews.cc/code/bmmxp5m.html  >**Softmax** : 激活函數,將前端神經元的輸出轉成0到1之間的數值,目的是將輸入映射為輸出,它會將 **Linear** 算出的概率轉換為0到1之間。例如我的字典中有100個詞,則 **Linear** 會算出100個數字,在藉由 **Softmax** 轉換成機率。( 100個數字經由 **Softmax** 轉換以後加起來為1,視為機率 )  >不管是 **Encoder** 還是 **Decoder** 都不是孤軍奮戰。上述都是在說當 **Encoder** 和 **Decoder** 只有一層的情況,其實 **Encoder** 和 **Decoder** 可以多層疊加,以增加精準度。 > >圖片出處http://jalammar.github.io/illustrated-transformer/ ## Model Implementation : GPT-2! ```python= import os print("hello") ``` ###### tags: `AI`
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.