【NLP】Day 20: 放點注意力在多頭上(NLP也有多頭啊!):Transformer(下)

空頭不死,多頭不止;多頭不死,空頭不止
不詳

在股票市場中,人人著稱的一句話:「空頭不死,多頭不止;多頭不死,空頭不止。」意思是,如果股價在下降的趨勢時中,如果想一直有抄底,期望做反彈的人不斷進場的話,那麼市場就會不斷下跌。我想我在這裡可以再多加一句:

單頭一有,強到流油;注意多頭,更上層樓!
By me

只是差別是,一個在講的是股市走向及股民心理,另一個則是在講 Attention Is All You Need 論文的 Transformer 模型,以及在其中所運用的自注意力機制(Self-attention Mechanism)。昨天的文章中,我們已經簡單地了解何謂自注意力機制。在同一篇文章中,作者又針對這個自注意力機制再次進行了改良 完全不給其他人優化的機會喔,也就是將原本提出的單一自注意力機制,在模型中改良成多頭自注意力機制(Multi-head Self-attention Mechanism)。今天,就讓我們一起來看看 Multi-head Self-Attention Mechanism 跟原本的有什麼不一樣呢?接著,再把剩下的 Encoder 以及 Decoder 走完吧!

Multi-head Self-attention Mechanism

若你還記得的話,在昨天的文章,【NLP】Day 19: 注意!謝謝你的注意!Transformer (上)之中,曾經提到 Transformer 會將每一個字的向量(也就是Word-embedding)乘上一個權重 https://chart.googleapis.com/chart?cht=tx&chl=W 之後,會得到三個不同的向量,分別是 https://chart.googleapis.com/chart?cht=tx&chl=Qhttps://chart.googleapis.com/chart?cht=tx&chl=K 以及 https://chart.googleapis.com/chart?cht=tx&chl=V ,也就是 queue vector、key vector,以及value vector。那 Multi-head Self-attention Mechanism 其實就是不同的字要乘上不同的權重 https://chart.googleapis.com/chart?cht=tx&chl=W ,也就是說,不同的字會有不同的https://chart.googleapis.com/chart?cht=tx&chl=Qhttps://chart.googleapis.com/chart?cht=tx&chl=K 以及 https://chart.googleapis.com/chart?cht=tx&chl=V 。我們可以先看看下圖:

在這邊再強調一次,這邊的 https://chart.googleapis.com/chart?cht=tx&chl=Qhttps://chart.googleapis.com/chart?cht=tx&chl=K 以及 https://chart.googleapis.com/chart?cht=tx&chl=V 三個向量,是 https://chart.googleapis.com/chart?cht=tx&chl=X 分別與 https://chart.googleapis.com/chart?cht=tx&chl=W_%7Bi%5EQ%7Dhttps://chart.googleapis.com/chart?cht=tx&chl=W_%7Bi%5Ek%7D
以及 https://chart.googleapis.com/chart?cht=tx&chl=W_%7Bi%5Ev%7D 內積所得的結果。有幾個維度,就有幾個 Head;同理,若訓練資料的 Word Embedding 總共有 8 個維度,那麼就會有 8 個不同的 Head。最後我們就會得到 8 個 https://chart.googleapis.com/chart?cht=tx&chl=Z矩陣。 但是問題在於,接下來要將資料餵入的模型事前饋神經網路(Feed-forward Neural Network),吃的是每個 一個 向量。這時候就是要再乘上 https://chart.googleapis.com/chart?cht=tx&chl=W_o 將這一大串的矩陣再轉回成一個字一個向量(因為在圖中是兩個字,所以會變成是兩個矩陣)。

那我們綜觀下來,self-attention 的機制就如下圖運作。

Multi-head Self-attention Mechanism 哪裡比較好?

  1. Multi-head 的機制更可以讓模型專注在一句話中的不同字上。雖然說在 Single-head 的機制底下,對其中一個字來說,一句話的其他字在這個字的編碼中會含有一點點的權重,但在某些情況下,還是有可能會特別側重在某個字上。但 Multi-head 就可以淡化這個問題。

  2. 若你還記得的話,Multi-head 的機制針對一句話中的不同字,各自會有不同的 https://chart.googleapis.com/chart?cht=tx&chl=W_%7Bi%5EQ%7Dhttps://chart.googleapis.com/chart?cht=tx&chl=W_%7Bi%5Ek%7D
    以及 https://chart.googleapis.com/chart?cht=tx&chl=W_%7Bi%5Ev%7D 權重,這麼一來也可以提供模型的語意空間更高的彈性。(這是我的理解,若有錯誤還請前輩不吝指正。)

位置編碼(Positional Encoding)

要知道字在文中的不同位置對於語意理解上也扮演著很重要的角色,所以我們必須在模型中加入位置的資訊,也就是所謂的位置編碼(Positional Encoding),這可以幫助模型理解一個字在資料中的位置,以及與其他字的距離

實際上會長這樣:

殘差標準化(Residual & Normalization)

因為在運算資料的過程中會產生殘差,所以也要經過標準化。這層標準化層,在編碼器以及解碼器中都會加入。

解碼器(decoder)

在編碼器,我們將文本序列作為輸入資料,在最後一個編碼器會得到兩個 attention vector,分別是 https://chart.googleapis.com/chart?cht=tx&chl=K 以及 https://chart.googleapis.com/chart?cht=tx&chl=V 。 這兩個向量可以幫助在每個解碼器中的 encoder-decoder attention 了解輸入序列中這些字的資訊。

在接下來的解碼中,除了前面兩個 attention vector 的幫助,同樣也會在解碼器端加入前文的 word embedding 以及 positional encoding,同樣也是為了要幫助模型了解語意距離、位置資訊等等,以利模型進行解碼。

最終輸出層(Final Linear and Softmax Layer)

最後一哩路啦!在解碼器的尾端,我們最後得到的輸出是由浮點數所組成的向量,但我們需要文字輸出的話,該怎麼辦?所以最後就會需要線性層(Linear Layer)以及激勵函數層(Softmax Layer)來幫助模型將這些數值資料轉回文字。

線性層是一個完全連接的神經網路。簡單的說,線性層可以將解碼器的輸出向量轉化成另外一種可以「儲存字彙」的向量,文中稱為 Logits vector。假如說今天模型在訓練資料中學習了 10000 個字,那麼在這個叫 Logits vector 的向量中就會有 10000 個元素,這些元素分別又代表了不同分數(score),這些分數都可以對應回去每一個字。

Softmax 則會在這10000個元素中的每一個元素各分配一個概率,讓模型用這個概率決定該以哪個字作為最後的輸出。

問題與討論

  1. 解釋力偏低:由於 Transformer 算是深度學習模型的其中一種,所以通常解釋力都比較低。我們沒有辦法跟人解釋模型是如何運算得出某個特定的輸出結果。其實無論是 Transformer 還是前面介紹的 RNN,還有接下來要介紹的 BERT,都有一樣的問題。
  2. 難以控制自注意力機制的運作:因為自注意力的運算機制,導致模型有漏字的可能。舉例來說,我們透過Google翻譯 one one one one two two one one twenty two 可以得到 一一一二二一一二二 ,但我們都知道少了一個Source
  3. 訓練時間長:我們用了好多attention head、好多的參數、好多的運算,那訓練一個模型的時間就會拉的特別長。一天兩天已算少,一週兩週剛剛好。

結語

好!既然我們已經了解了什麼是 Transformer,就代表我們已經做好萬全準備進入現在最強最常用的語言模型 BERT 啦!我們明天見!

參考資料:

  1. The Illustrated Transformer
  2. 謦伊的閱讀筆記