iT邦幫忙

2021 iThome 鐵人賽

DAY 28
0
自我挑戰組

新手也想開始認識機器學習系列 第 28

Day 28 自注意力(Self-Attention) 機制

我們昨天介紹了 Transformer 的結構,但是並沒有介紹到 Transformer 內最神祕的 Self-Attention 層。究竟 Transformer 是怎麼憑藉著 Self-Attention 來對輸入序列進行平行運算?又要怎麼做到解決預測結果和關鍵訊息的位置過於遙遠的問題?

PS:接下來介紹的教材來源皆為台大李宏毅教授的網路教學,有興趣的話可以去聽詳細內容,相信一定能有所收穫。

介紹


由於人類語言具有前後順序、上下文關係,對於這種時間序列的資料很常使用 RNN 進行處理,像是文章分類、語意分析...等。

但是 RNN 有個問題就是它並不容易被平行運算,假如今天我們輸入一個 Sequence https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E1%24 ~ https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E4%24 ,而我們想算出 https://chart.googleapis.com/chart?cht=tx&chl=%24b%5E4%24 的話,我們就必須先從 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E1%24https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E2%24https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E3%24 → 直到 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E4%24,才能把 https://chart.googleapis.com/chart?cht=tx&chl=%24b%5E4%24 算出來

因此有人提出用 CNN 取代 RNN 的方法,一個三角形代表一個 filter,每個 filter 的輸入就是 Sequence 的其中一小段,不同的 filter 對應 Sequence 中不同的部分。但是 CNN 需要疊很多層的才能涵蓋句子的所有資訊,而且後來的表現也不比 RNN 佳,因此出現了Self-Attention 機制。


Self-Attention 想要做的事情就是取代 RNN 可以做的事情
它的輸出/入跟 RNN 一樣的,它的最大優勢在於:

  1. 可以平行化運算
  2. 每一個輸出的向量,都看過整個輸入的序列。因此不用像 CNN 那樣堆好幾層。

運算過程

現在我們假設輸入https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E1%24 ~ https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E4%24 四個向量,而 Self-Attention 要輸出另外一排 b 向量,而每一個 b 都是考慮了所有的 a 以後才生成出來的

要算出 https://chart.googleapis.com/chart?cht=tx&chl=%24b%5E1%24 ,第一個步驟是根據 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E1%24 找出這個 sequence 裡面跟 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E1%24 相關的其他向量,而每一個向量跟 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E1%24 的關聯的程度,我們用一個數值叫 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Calpha%24 來表示。

在這裡必須先提一下 Self-Attention 機制裡面有3個非常重要的值: Query, Key, Value 。分別表示用來匹配的值、被匹配的值、以及抽取出來的資訊。

至於決定兩個向量之間的關聯性 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Calpha%24 最常用的方法就是dot product (內積)。它就是拿兩個向量作為輸入,分別乘上兩個不同的矩陣,左邊的向量乘上 https://chart.googleapis.com/chart?cht=tx&chl=%24W%5Eq%24 矩陣、右邊的向量乘上 https://chart.googleapis.com/chart?cht=tx&chl=%24W%5Ek%24 矩陣 ( https://chart.googleapis.com/chart?cht=tx&chl=%24W%5Eq%24 就是 Query 矩陣 ,而 https://chart.googleapis.com/chart?cht=tx&chl=%24W%5Ek%24 就是 Key 矩陣,他們的值都是隨機初始化後通過訓練得到 )

接下來得到 https://chart.googleapis.com/chart?cht=tx&chl=%24q%24https://chart.googleapis.com/chart?cht=tx&chl=%24k%24 這兩個向量後再做內積,全部加起來以後就得到一個 scalar (純量),而這個純量就是 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Calpha%24 ,我們就把它當作兩個向量關聯的程度。


接下來我們把剛才介紹的套用在 Self-Attention 裡面。

  1. 首先將 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E1%24https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E2%24 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E3%24 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E4%24 分別都去計算他們之間的關聯性 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Calpha%24 。把 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E1%24 乘上 https://chart.googleapis.com/chart?cht=tx&chl=%24W%5Eq%24 得到 https://chart.googleapis.com/chart?cht=tx&chl=%24q%5E1%24 ,再將 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E2%24 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E3%24 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E4%24 都去乘上 https://chart.googleapis.com/chart?cht=tx&chl=%24W%5Ek%24 ,再透過內積計算出 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E1%24 跟每一個向量的關聯性 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Calpha%24
  2. 執行 Soft-Max 函式得到 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Calpha%5E%7B'%7D%24
  3. 得到這個 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Calpha%5E%7B'%7D%24 後,我們就能根據這個 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Calpha%5E%7B'%7D%24 去抽取出這個 Sequence 裡面重要的資訊了!


怎麼用 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Calpha%5E%7B'%7D%24 抽取重要的資訊呢?步驟如下:

  1. 先把 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E1%24 ~ https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E4%24 都乘上 https://chart.googleapis.com/chart?cht=tx&chl=%24W%5Ev%24 得到新的向量,分別就是用 https://chart.googleapis.com/chart?cht=tx&chl=%24v%5E1%24https://chart.googleapis.com/chart?cht=tx&chl=%24v%5E2%24 https://chart.googleapis.com/chart?cht=tx&chl=%24v%5E3%24 https://chart.googleapis.com/chart?cht=tx&chl=%24v%5E4%24 來表示( https://chart.googleapis.com/chart?cht=tx&chl=%24W%5Ev%24 就是 Value 矩陣)
  2. 接下來把這邊的 https://chart.googleapis.com/chart?cht=tx&chl=%24v%5E1%24 ~ https://chart.googleapis.com/chart?cht=tx&chl=%24v%5E4%24 每一個向量都去乘上 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Calpha%5E%7B'%7D%24 後進行相加,就可以得到輸出的 https://chart.googleapis.com/chart?cht=tx&chl=%24b%5E1%24 了。 (公式寫在圖片右上角)

如果某一個向量它得到的分數越高,假如說 https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E1%24https://chart.googleapis.com/chart?cht=tx&chl=%24a%5E2%24 的關聯性很強、這個 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Calpha%5E%7B'%7D%24 得到的值很大,那我們今天在做權重總和以後得到的 https://chart.googleapis.com/chart?cht=tx&chl=%24b%5E1%24 的值就可能會比較接近 https://chart.googleapis.com/chart?cht=tx&chl=%24v%5E2%24

現在,既然我們已經知道如何計算出 https://chart.googleapis.com/chart?cht=tx&chl=%24b%5E1%24 ,那麼自然也能根據同樣的方法推算出 https://chart.googleapis.com/chart?cht=tx&chl=%24b%5E2%24https://chart.googleapis.com/chart?cht=tx&chl=%24b%5E3%24https://chart.googleapis.com/chart?cht=tx&chl=%24b%5E4%24。 至此,我們已經將 Self-Attention 的內部的計算方式講解完畢。明天來聊聊使用了 Transformer 中 Encoder 架構的自然語言處理模型 BERT 吧!


上一篇
Dat 27 Transformer
下一篇
Day 29 BERT
系列文
新手也想開始認識機器學習30

尚未有邦友留言

立即登入留言