文章目錄
文爲李弘毅老師【Transformer】的課程筆記,課程視頻youtube地址,點這裏👈(需翻牆)。
下文中用到的圖片均來自於李宏毅老師的PPT,若有侵權,必定刪除。
1 內容簡述
拋開Transformer的內部結構,Transformer其實就是一個seq2seq的模型,其中用到了大量的self-attention layer。本文會試圖講明白什麼是self-attention layer。
2 seq2seq的常用模塊
之前使用最廣泛的seq2seq的模塊就是RNN。RNN可以分爲單向的和雙向的。如果是單向的RNN,輸出中的每個time step會有一些信息丟失,比如單向的RNN在下圖中產生的時候就只考慮了。而雙向的RNN輸出的每個time step都考慮了輸入的所有信息,比如雙向的RNN在下圖中產生的時候就考慮了和。
但是RNN有一個不好的地方就是它的計算很難並行化,比如我要算的時候,就要等前幾個結果都出來了,才能算。爲了解決這個問題,就有人提出了CNN來替換RNN。
1-D CNN的模塊介紹可以參見這裏。雖然CNN的計算可以並行處理,但是,CNN的kernel_size一般會比較小,輸出的某個time step想要考慮到全局的信息,就要把CNN疊很多層。
然後本文的重點就由此引出了,self-attention可以同時解決這兩個問題,也就是既可以讓每個time step的輸出考慮了全局的輸入,又可以並行計算。
3 Self-attention
self-attention最早出自google的這篇Attention Is All You Need,這篇文章比較難讀懂,但它本身並不是那麼神祕,一個非常直觀的理解就是,self-attention是一個可以替代RNN的東西。下面就來剖析一下這個self-attention。我們的目的是輸入一個序列的到一個序列。
假設我們的輸入是,首先要對進行一次embedding,讓它變到我們需要的維度,我們記這個embedding的結果爲。
然後,我們要讓這個再分別乘以三個矩陣,self-attention中最爲重要的三個東西query, key和value。
然後,我們會把每一個q去對k做attention,所謂的attention就是塞兩個向量進去,然後吐出來一個表示兩個向量相關性的數值。attention的方法有很多種,在Attention Is All You Need中,所使用的叫做scaled dot-product attention。
爲什麼要除以這個呢?因爲當和的維度很大時,它們內積的variance就會很大,所以要除以一個來scale一下。
最後還要對做一個softmax,得到。大致的流程如下圖所示。
這個其實就是每一個time step的value的重要性。用這個對每個time step的value進行一個加權,就得到了self-attention的結果。比如就可以通過下式計算得到
這樣得到的是考慮了所有的輸入的,而且無視輸入之間的遠近,完全通過學習attention來獲取需要的value,其示意圖如下所示。
更重要的是,以上的過程都是可以並行計算的。因爲每個time step的計算都是獨立的,我們可以把它們concat到一個大的矩陣裏,然後一起計算,示意圖如下所示。
4 Multi-head Self-attention
self-attention是可以做成multi-head的,所謂multi-head,其實就是把,,分裂成多個,然後每個分別在自己的head內做self-attention,然後把結果再concat起來,如果得到的結果維度不是我們想要的,那麼再乘以一個矩陣就可以了。
做成Multi-head的目的是讓不同的head去學到不同的東西,比如有的head學局部的信息,有的head學全局的信息。
5 Positional Encoding
然而,從之前的整個流程可以看出來,self-attention是不會去關心輸入的time step順序的,任何一個輸出,time step是還是,對self-attention來說都是一樣的,李老師很形象地稱之爲“天涯若比鄰”。
爲了增加位置的信息,就會給加上一個神奇的人爲預先設定好的向量,有了這個之後,模型就可以知道輸入的位置信息了。
那爲什麼是,這樣不是把的信息給攪亂了嗎?會什麼不是直接concat上去變成呢?我們不妨來試試concat的話會如何,不過既然是位置信息,我們需要concat到上。假設我們有一個和位置有關的向量,是一個one-hot的向量,表示當前的是在第個tme step上。那麼在做embedding的時候,我們也需要把embedding的矩陣變大,而又可以拆成和。根據矩陣的計算方法,其結果就相當於給加了一個值,這個值也就是之前提到的的。可見,和對進行concat是等效的。
這裏有一個比較神奇的地方,就是這個是個什麼東西,爲啥這麼靈?換成其他的靈不靈?這就不得而知了。
6 Transformer
從上文中可以看出,self-attention是可以替代RNN的,實際操作中,也就是把RNN替換成self-attention就結束了。
接下來讓我們來看看下面這幅經典的Transformer的圖,現在看起來應該是親切了不少。這個圖的左半個結構是Encoder,右半個結構是Decoder。把圖中的Multi-Head Attention想象成RNN就可以了。Emmm…感覺也不需要額外的說明了。值得注意的是,這裏的Masked Multi-Head Attention就是指是對已經產生的序列做attention,比如我們翻譯的時候,是塞一個起始符進去,然後一個字一個字生成,直到遇到終止符。