Transformer是谷歌大腦在2017年底發表的論文
attention is all you need 中所提出的seq2seq模型. 現在已經取得了大範圍的應用和擴展, 而BERT就是從transformer中衍生出來的預訓練語言模型。在NLP領域目前已經成了標配,語言模型, 命名實體識別, 機器翻譯, 可能很多人想到的
LSTM等循環神經網絡 , 但目前其實LSTM起碼在自然語言處理領域已經過時了, 在Stanford閱讀理解數據集**(SQuAD2.0)
榜單裏, 機器的成績已經超人類表現, 這很大程度要歸功於 transformer的BERT預訓練模型**。
一. transformer encoder
t r a n s f o r m e r transformer t r a n s f o r m e r 模型的直覺, 建立直觀認識;
p o s i t i o n a l e n c o d i n g positional \ encoding p o s i t i o n a l e n c o d i n g , 即位置嵌入 (或位置編碼);
s e l f a t t e n t i o n m e c h a n i s m self \ attention \ mechanism s e l f a t t e n t i o n m e c h a n i s m , 即自注意力機制 與注意力矩陣可視化 ;
L a y e r N o r m a l i z a t i o n Layer \ Normalization L a y e r N o r m a l i z a t i o n 和殘差連接.
t r a n s f o r m e r e n c o d e r transformer \ encoder t r a n s f o r m e r e n c o d e r 整體結構.
0. Tansformer 整體感受
首先來說一下transformer 和LSTM 的最大區別, 就是LSTM的訓練是迭代的, 是一個接一個字的來, 當前這個字過完LSTM單元, 纔可以進下一個字, 而transformer的訓練是並行了, 就是所有字是全部同時訓練的, 這樣就大大加快了計算效率, transformer使用了位置嵌入( p o s i t i o n a l e n c o d i n g ) (positional \ encoding) ( p o s i t i o n a l e n c o d i n g ) 來理解語言的順序, 使用自注意力機制和全連接層來進行計算, 這些後面都會詳細講解.
transformer模型主要分爲兩大部分 , 分別是編碼器 和解碼器 , 編碼器 負責把自然語言序列映射成爲隱藏層 (下圖中第2步 用九宮格比喻的部分), 含有自然語言序列的數學表達. 然後解碼器把隱藏層再映射爲自然語言序列, 從而使我們可以解決各種問題, 如情感分類, 命名實體識別, 語義關係抽取, 摘要生成, 機器翻譯等等, 下面我們簡單說一下下圖的每一步都做了什麼:
輸入自然語言序列到編碼器: Why do we work?(爲什麼要工作);
編碼器輸出的隱藏層, 再輸入到解碼器;
輸入< s t a r t > <start> < s t a r t > (起始)符號到解碼器;
得到第一個字"爲";
將得到的第一個字"爲"落下來再輸入到解碼器;
得到第二個字"什";
將得到的第二字再落下來, 直到解碼器輸出< e n d > <end> < e n d > (終止符), 即序列生成完成.
1. p o s i t i o n a l e n c o d i n g positional \ encoding p o s i t i o n a l e n c o d i n g , 即位置嵌入 (或位置編碼);
由於transformer模型沒有 循環神經網絡的迭代操作, 所以我們必須提供每個字的位置信息給transformer, 才能識別出語言中的順序關係.
現在定義一個位置嵌入的概念, 也就是p o s i t i o n a l e n c o d i n g positional \ encoding p o s i t i o n a l e n c o d i n g , 位置嵌入的維度爲[ m a x s e q u e n c e l e n g t h , e m b e d d i n g d i m e n s i o n ] [max \ sequence \ length, \ embedding \ dimension] [ m a x s e q u e n c e l e n g t h , e m b e d d i n g d i m e n s i o n ] , 嵌入的維度同詞向量的維度, m a x s e q u e n c e l e n g t h max \ sequence \ length m a x s e q u e n c e l e n g t h 屬於超參數, 指的是限定的最大單個句長.
注意, 我們一般以字爲單位訓練transformer模型, 也就是說我們不用分詞了, 首先我們要初始化字向量爲[ v o c a b s i z e , e m b e d d i n g d i m e n s i o n ] [vocab \ size, \ embedding \ dimension] [ v o c a b s i z e , e m b e d d i n g d i m e n s i o n ] , v o c a b s i z e vocab \ size v o c a b s i z e 爲總共的字庫數量, e m b e d d i n g d i m e n s i o n embedding \ dimension e m b e d d i n g d i m e n s i o n 爲字向量的維度, 也是每個字的數學表達.
在這裏論文中使用了s i n e sine s i n e 和c o s i n e cosine c o s i n e 函數的線性變換來提供給模型位置信息:
P E ( p o s , 2 i ) = s i n ( p o s / 1000 0 2 i / d model ) P E ( p o s , 2 i + 1 ) = c o s ( p o s / 1000 0 2 i / d model ) (eq.1) PE_{(pos,2i)} = sin(pos / 10000^{2i/d_{\text{model}}}) \quad PE_{(pos,2i+1)} = cos(pos / 10000^{2i/d_{\text{model}}})\tag{eq.1} P E ( p o s , 2 i ) = s i n ( p o s / 1 0 0 0 0 2 i / d model ) P E ( p o s , 2 i + 1 ) = c o s ( p o s / 1 0 0 0 0 2 i / d model ) ( e q . 1 )
上式中p o s pos p o s 指的是句中字的位置, 取值範圍是[ 0 , m a x s e q u e n c e l e n g t h ) [0, \ max \ sequence \ length) [ 0 , m a x s e q u e n c e l e n g t h ) , i i i 指的是詞向量的維度, 取值範圍是[ 0 , e m b e d d i n g d i m e n s i o n ) [0, \ embedding \ dimension) [ 0 , e m b e d d i n g d i m e n s i o n ) , 上面有s i n sin s i n 和c o s cos c o s 一組公式, 也就是對應着e m b e d d i n g d i m e n s i o n embedding \ dimension e m b e d d i n g d i m e n s i o n 維度的一組奇數和偶數的序號的維度, 例如0 , 1 0, 1 0 , 1 一組, 2 , 3 2, 3 2 , 3 一組, 分別用上面的s i n sin s i n 和c o s cos c o s 函數做處理, 從而產生不同的週期性變化, 而位置嵌入在e m b e d d i n g d i m e n s i o n embedding \ dimension e m b e d d i n g d i m e n s i o n 維度上隨着維度序號增大, 週期變化會越來越慢, 而產生一種包含位置信息的紋理, 就像論文原文中第六頁講的, 位置嵌入函數的週期從2 π 2 \pi 2 π 到10000 ∗ 2 π 10000 * 2 \pi 1 0 0 0 0 ∗ 2 π 變化, 而每一個位置在e m b e d d i n g d i m e n s i o n embedding \ dimension e m b e d d i n g d i m e n s i o n 維度上都會得到不同週期的s i n sin s i n 和c o s cos c o s 函數的取值組合, 從而產生獨一的紋理位置信息, 模型從而學到位置之間的依賴關係和自然語言的時序特性.
下面畫一下位置嵌入, 可見縱向觀察, 隨着e m b e d d i n g d i m e n s i o n embedding \ dimension e m b e d d i n g d i m e n s i o n 增大, 位置嵌入函數呈現不同的週期變化.
對於同一個位置的字,也就是seq_len相同,在不同的hidden dimension上的明暗變化是不同的。在同一個hidden dimension維度上,沿着seq_len的維度是呈週期變化的。這樣通過sin和cos函數就把位置信息進行了編碼。
注意力矩陣是一個seq_len * seq_len的矩陣,下圖是注意力矩陣可視化後的效果:
上圖中, 我們用位置編碼矩陣乘以(矩陣乘)他本身的轉置, 也就是P E : [ s e q _ l e n , e m b e d d i n g _ d i m ] PE: \ [seq\_len, \ embedding\_dim ] P E : [ s e q _ l e n , e m b e d d i n g _ d i m ] , 我們求P E P E T PEPE^T P E P E T , 得出的維度是[ s e q _ l e n , s e q _ l e n ] [seq\_len, \ seq\_len ] [ s e q _ l e n , s e q _ l e n ] . 我們看到上圖中, 矩陣的對角線隆起, 也就是值比較大, 是因爲一個矩陣乘以他本身的轉置之後, 形成的矩陣的對角線正是這個矩陣的每一行( r o w ) (row) ( r o w ) 點乘這一行本身, 所以是值最大的區域(紅色部分). 對於位置編碼來說, 也就是當前位置與當前位置本身相關程度最高. 再往對角線兩邊看, 發現以對角線(紅色山峯)區域爲中心, 兩邊屬於緩慢下降趨勢, 這就說明了隨着離當前位置越遠, 其位置編碼的相關程度就越低. 由此可見, 位置編碼建立在時間維度的關聯關係.
後邊有人指出,transformer只進行了位置上的編碼,但是不能體現方向上的信息,導致transformer結構直接用於NER任務時,效果不佳,在MSRA數據集上只有86%的f1值,經過改進可以達到92.7%的f1值,比使用char-bigram-bilstm-crf的效果(92%)好一些。Adapted Transformer Encoder for Named Entity Recognition,論文鏈接:https://arxiv.org/abs/1911.04474
2. s e l f a t t e n t i o n m e c h a n i s m self \ attention \ mechanism s e l f a t t e n t i o n m e c h a n i s m , 自注意力機制
Attention mask:在softmax之前,需要根據seq_len來進行mask,防止padding位置上也有信息。
注意, 在上面s e l f a t t e n t i o n self \ attention s e l f a t t e n t i o n 的計算過程中, 我們通常使用m i n i b a t c h mini \ batch m i n i b a t c h 來計算, 也就是一次計算多句話, 也就是X X X 的維度是[ b a t c h s i z e , s e q u e n c e l e n g t h ] [batch \ size, \ sequence \ length] [ b a t c h s i z e , s e q u e n c e l e n g t h ] , s e q u e n c e l e n g t h sequence \ length s e q u e n c e l e n g t h 是句長, 而一個m i n i b a t c h mini \ batch m i n i b a t c h 是由多個不等長的句子組成的, 我們就需要按照這個m i n i b a t c h mini \ batch m i n i b a t c h 中最大的句長對剩餘的句子進行補齊長度, 我們一般用0 0 0 來進行填充, 這個過程叫做p a d d i n g padding p a d d i n g .
但這時在進行s o f t m a x softmax s o f t m a x 的時候就會產生問題, 回顧s o f t m a x softmax s o f t m a x 函數σ ( z ) i = e z i ∑ j = 1 K e z j \sigma (\mathbf {z} )_{i}={\frac {e^{z_{i}}}{\sum _{j=1}^{K}e^{z_{j}}}} σ ( z ) i = ∑ j = 1 K e z j e z i , e 0 e^0 e 0 是1, 是有值的, 這樣的話s o f t m a x softmax s o f t m a x 中被p a d d i n g padding p a d d i n g 的部分就參與了運算, 就等於是讓無效的部分參與了運算, 會產生很大隱患, 這時就需要做一個m a s k mask m a s k 讓這些無效區域不參與運算, 我們一般給無效區域加一個很大的負數的偏置, 也就是:
z i l l e g a l = z i l l e g a l + b i a s i l l e g a l z_{illegal} = z_{illegal} + bias_{illegal} z i l l e g a l = z i l l e g a l + b i a s i l l e g a l
b i a s i l l e g a l → − ∞ bias_{illegal} \to -\infty b i a s i l l e g a l → − ∞
e z i l l e g a l → 0 e^{z_{illegal}} \to 0 e z i l l e g a l → 0
經過上式的m a s k i n g masking m a s k i n g 我們使無效區域經過s o f t m a x softmax s o f t m a x 計算之後還幾乎爲0 0 0 , 這樣就避免了無效區域參與計算.
3. 殘差連接和L a y e r N o r m a l i z a t i o n Layer \ Normalization L a y e r N o r m a l i z a t i o n
1). 殘差連接 :
我們在上一步得到了經過注意力矩陣加權之後的V V V , 也就是A t t e n t i o n ( Q , K , V ) Attention(Q, \ K, \ V) A t t e n t i o n ( Q , K , V ) , 我們對它進行一下轉置, 使其和X e m b e d d i n g X_{embedding} X e m b e d d i n g 的維度一致, 也就是[ b a t c h s i z e , s e q u e n c e l e n g t h , e m b e d d i n g d i m e n s i o n ] [batch \ size, \ sequence \ length, \ embedding \ dimension] [ b a t c h s i z e , s e q u e n c e l e n g t h , e m b e d d i n g d i m e n s i o n ] , 然後把他們加起來做殘差連接, 直接進行元素相加, 因爲他們的維度一致:
X e m b e d d i n g + A t t e n t i o n ( Q , K , V ) X_{embedding} + Attention(Q, \ K, \ V) X e m b e d d i n g + A t t e n t i o n ( Q , K , V )
在之後的運算裏, 每經過一個模塊的運算, 都要把運算之前的值和運算之後的值相加, 從而得到殘差連接, 訓練的時候可以使梯度直接走捷徑反傳到最初始層:
X + S u b L a y e r ( X ) (eq. 5) X + SubLayer(X) \tag{eq. 5} X + S u b L a y e r ( X ) ( e q . 5 )
2). L a y e r N o r m LayerNorm L a y e r N o r m :
L a y e r N o r m a l i z a t i o n Layer Normalization L a y e r N o r m a l i z a t i o n 的作用是把神經網絡中隱藏層歸一爲標準正態分佈, 也就是i . i . d i.i.d i . i . d 獨立同分布, 以起到加快訓練速度, 加速收斂的作用:
μ i = 1 m ∑ i = 1 m x i j \mu_{i}=\frac{1}{m} \sum^{m}_{i=1}x_{ij} μ i = m 1 i = 1 ∑ m x i j
上式中以矩陣的行( r o w ) (row) ( r o w ) 爲單位求均值;
σ j 2 = 1 m ∑ i = 1 m ( x i j − μ j ) 2 \sigma^{2}_{j}=\frac{1}{m} \sum^{m}_{i=1}
(x_{ij}-\mu_{j})^{2} σ j 2 = m 1 i = 1 ∑ m ( x i j − μ j ) 2
上式中以矩陣的行( r o w ) (row) ( r o w ) 爲單位求方差;
L a y e r N o r m ( x ) = α ⊙ x i j − μ i σ i 2 + ϵ + β (eq.6) LayerNorm(x)=\alpha \odot \frac{x_{ij}-\mu_{i}}
{\sqrt{\sigma^{2}_{i}+\epsilon}} + \beta \tag{eq.6} L a y e r N o r m ( x ) = α ⊙ σ i 2 + ϵ x i j − μ i + β ( e q . 6 )
然後用每一行 的每一個元素 減去這行的均值 , 再除以這行的標準差 , 從而得到歸一化後的數值, ϵ \epsilon ϵ 是爲了防止除0 0 0 ;
之後引入兩個可訓練參數α , β \alpha, \ \beta α , β 來彌補歸一化的過程中損失掉的信息, 注意⊙ \odot ⊙ 表示元素相乘而不是點積, 我們一般初始化α \alpha α 爲全1 1 1 , 而β \beta β 爲全0 0 0 .
4. Feed Forward
這一部分比較簡單,把上一步中的輸出,經過了一個放縮,先把維度擴大到之前的3倍,再縮小到之前的hidden_size,再經過激活函數。得到一個[seq_len, hidden_size]大小的矩陣,再經過殘差連接和Layer Normalizaion。
5. Transformer整體架構
經過上面4個步驟, 我們已經基本瞭解到來t r a n s f o r m e r transformer t r a n s f o r m e r 編碼器的主要構成部分, 我們下面用公式把一個t r a n s f o r m e r b l o c k transformer \ block t r a n s f o r m e r b l o c k 的計算過程整理一下:
1). 字向量與位置編碼:
X = E m b e d d i n g L o o k u p ( X ) + P o s i t i o n a l E n c o d i n g (eq.2) X = EmbeddingLookup(X) + PositionalEncoding \tag{eq.2} X = E m b e d d i n g L o o k u p ( X ) + P o s i t i o n a l E n c o d i n g ( e q . 2 )
X ∈ R b a t c h s i z e ∗ s e q . l e n . ∗ e m b e d . d i m . X \in \mathbb{R}^{batch \ size \ * \ seq. \ len. \ * \ embed. \ dim.} X ∈ R b a t c h s i z e ∗ s e q . l e n . ∗ e m b e d . d i m .
2). 自注意力機制:
Q = L i n e a r ( X ) = X W Q Q = Linear(X) = XW_{Q} Q = L i n e a r ( X ) = X W Q
K = L i n e a r ( X ) = X W K (eq.3) K = Linear(X) = XW_{K} \tag{eq.3} K = L i n e a r ( X ) = X W K ( e q . 3 )
V = L i n e a r ( X ) = X W V V = Linear(X) = XW_{V} V = L i n e a r ( X ) = X W V
X a t t e n t i o n = S e l f A t t e n t i o n ( Q , K , V ) (eq.4) X_{attention} = SelfAttention(Q, \ K, \ V) \tag{eq.4} X a t t e n t i o n = S e l f A t t e n t i o n ( Q , K , V ) ( e q . 4 )
3). 殘差連接與L a y e r N o r m a l i z a t i o n Layer \ Normalization L a y e r N o r m a l i z a t i o n
X a t t e n t i o n = X + X a t t e n t i o n (eq. 5) X_{attention} = X + X_{attention} \tag{eq. 5} X a t t e n t i o n = X + X a t t e n t i o n ( e q . 5 )
X a t t e n t i o n = L a y e r N o r m ( X a t t e n t i o n ) (eq. 6) X_{attention} = LayerNorm(X_{attention}) \tag{eq. 6} X a t t e n t i o n = L a y e r N o r m ( X a t t e n t i o n ) ( e q . 6 )
4). 下面進行t r a n s f o r m e r b l o c k transformer \ block t r a n s f o r m e r b l o c k 結構圖中的第4部分 , 也就是F e e d F o r w a r d FeedForward F e e d F o r w a r d , 其實就是兩層線性映射並用激活函數激活, 比如說R e L U ReLU R e L U :
X h i d d e n = A c t i v a t e ( L i n e a r ( L i n e a r ( X a t t e n t i o n ) ) ) (eq. 7) X_{hidden} = Activate(Linear(Linear(X_{attention}))) \tag{eq. 7} X h i d d e n = A c t i v a t e ( L i n e a r ( L i n e a r ( X a t t e n t i o n ) ) ) ( e q . 7 )
5). 重複3).:
X h i d d e n = X a t t e n t i o n + X h i d d e n X_{hidden} = X_{attention} + X_{hidden} X h i d d e n = X a t t e n t i o n + X h i d d e n
X h i d d e n = L a y e r N o r m ( X h i d d e n ) X_{hidden} = LayerNorm(X_{hidden}) X h i d d e n = L a y e r N o r m ( X h i d d e n )
X h i d d e n ∈ R b a t c h s i z e ∗ s e q . l e n . ∗ e m b e d . d i m . X_{hidden} \in \mathbb{R}^{batch \ size \ * \ seq. \ len. \ * \ embed. \ dim.} X h i d d e n ∈ R b a t c h s i z e ∗ s e q . l e n . ∗ e m b e d . d i m .
通過sin和cos函數對不同維度上的信息的週期是不同的,把位置信息與word embedding信息相加,再求了一個attention matrix,維度是[seq_len, seq_len]的,每一行是歸一化的,是當前字與整個句子每個字的相似度的概率分佈。因爲用了點積,本質上是自己與自己作點積得到的概率分佈。再對embedding的信息作加權,得到殘差。
multi-head是爲了提取不同的語義信息。
一個transformer層用了兩次殘差連接和兩次Layer Normalization。
transformer的本質是multi-head的self-attention。
參考:
https://github.com/aespresso/a_journey_into_math_of_ml