一、背景
自從Attention機制在提出之后,加入Attention的Seq2Seq模型在各個任務上都有了提升,所以現在的seq2seq模型指的都是結合rnn和attention的模型。傳統的基於RNN的Seq2Seq模型難以處理長序列的句子,無法實現並行,並且面臨對齊的問題。
所以之后這類模型的發展大多數從三個方面入手:
-
input的方向性:單向 -> 雙向
-
深度:單層 -> 多層
-
類型:RNN -> LSTM GRU
但是依舊收到一些潛在問題的制約,神經網絡需要能夠將源語句的所有必要信息壓縮成固定長度的向量。這可能使得神經網絡難以應付長時間的句子,特別是那些比訓練語料庫中的句子更長的句子;每個時間步的輸出需要依賴於前面時間步的輸出,這使得模型沒有辦法並行,效率低;仍然面臨對齊問題。
再然后CNN由計算機視覺也被引入到deep NLP中,CNN不能直接用於處理變長的序列樣本但可以實現並行計算。完全基於CNN的Seq2Seq模型雖然可以並行實現,但非常占內存,很多的trick,大數據量上參數調整並不容易。
本篇文章創新點在於拋棄了之前傳統的encoder-decoder模型必須結合cnn或者rnn的固有模式,只用Attention。文章的主要目的在於減少計算量和提高並行效率的同時不損害最終的實驗結果。
二、整體框架
整體模型看上去看上去很復雜,其實這就是一個Seq2Seq模型,左邊一個encoder把輸入讀進去,右邊一個decoder得到輸出:
左邊的encoders和右邊的decoders都是由6層組成,內部左邊encoder的輸出是怎么和右邊decoder結合的呢?再畫張圖直觀的看就是這樣:
三、分別展開
從上面可知,Encoder的輸出,會和每一層的Decoder進行結合。我們取其中一層進行詳細的展示:
整體框架細節展示:
1)Encoder
Encoder有N=6層,每層包括兩個sub-layers:
第一個sub-layer是multi-head self-attention mechanism,用來計算輸入的self-attention
第二個sub-layer是簡單的全連接網絡。
在每個sub-layer我們都模擬了殘差網絡,每個sub-layer的輸出都是:
其中Sublayer(x) 表示Sub-layer對輸入 x 做的映射,為了確保連接,所有的sub-layers和embedding layer輸出的維數都相同。
2)Decoder
Decoder也是N=6層,每層包括3個sub-layers:
第一個是Masked multi-head self-attention,也是計算輸入的self-attention,但是因為是生成過程,因此在時刻 i 的時候,大於 i 的時刻都沒有結果,只有小於 i 的時刻有結果,因此需要做Mask
第二個sub-layer是全連接網絡,與Encoder相同
第三個sub-layer是對encoder的輸入進行attention計算。
同時Decoder中的self-attention層需要進行修改,因為只能獲取到當前時刻之前的輸入,因此只對時刻 t 之前的時刻輸入進行attention計算,這也稱為Mask操作。
圖示參考上述總體框架細節圖
3)The Final Linear and Softmax Layer
4) Position-wise Feed-forward Networks
在進行了Attention操作之后,encoder和decoder中的每一層都包含了一個全連接前向網絡,對每個position的向量分別進行相同的操作,包括兩個線性變換和一個ReLU激活輸出:
其中每一層的參數都不同
四、Attention Mechanism詳解
1)Attention定義
2)Self-Attention 具體計算步驟
以兩個單詞,Thinking, Machines 為例,通過詞嵌入變換X1,X2兩個向量,組成一個[2 x 4]的矩陣形式,如下:
如上圖所示,輸入是一個[2x4]的矩陣(單詞嵌入),權重矩陣是[4x3]的矩陣,分別與三個權重矩陣相乘,求得Q,K,V。
首先Q對K轉制做點乘,除以dk的平方根(這個主要防止QK相乘后非常大,因為兩個向量點乘是對應位相乘再相加,維度越大最終結果就可能越大,從而導致最后的梯度非常小,模型不能學習,所以除以維度dk,相當於平均了一下)。再做一個softmax得到合為1的比例,最后對V做點乘得到輸出Z。那么這個Z就是一個考慮過thinking周圍單詞(machine)的輸出。
注意看這個公式,QKT 其實就會組成一個word2word的attention map!(加了softmax之后就是一個合為1的權重了)。比如說你的輸入是一句話 "i have a dream" 總共4個單詞,這里就會形成一張4x4的注意力機制的圖:
這樣一來,單詞兩兩之間都有一個權重,注意encoder里面是叫self-attention,decoder里面是叫masked self-attention。
這里的masked就是要在做language modelling(或者像翻譯)的時候,不給模型看到后面單詞的信息。
mask就是沿着對角線把灰色的區域用0覆蓋掉,不給模型看到未來的信息。
詳細來說,i作為第一個單詞,只能有和i自己的attention。have作為第二個單詞,有和i, have 兩個attention。 a 作為第三個單詞,有和i,have,a 前面三個單詞的attention。到了最后一個單詞dream的時候,才有對整個句子4個單詞的attention。
做完softmax后就像這樣,橫軸合為1
3) Multi-Head Attention
Multi-Head Attention就是把Scaled Dot-Product Attention的過程做H次,然后把輸出Z合起來。論文中,它的結構圖如下:
還是以上面的形式來解釋:
重復記性8次相似的操作,得到8個Zi矩陣
為了使得輸出與輸入結構對標 乘以一個線性W0 得到最終的Z。
4) 動態演示
五、Position Embedding
因為模型不包括Recurrence/Convolution,因此是無法捕捉到序列順序信息的,例如將K、V按行進行打亂,那么Attention之后的結果是一樣的。但是序列信息非常重要,代表着全局的結構,因此必須將序列的分詞相對或者絕對position信息利用起來。
這里每個分詞的position embedding向量維度也是dmodel, 然后將原本的input embedding和position embedding加起來組成最終的embedding作為encoder/decoder的輸入。其中position embedding計算公式如下:
其中 pos 表示位置index, i 表示dimension index。通過看代碼得知,pos位置為偶數的采用sin函數,為奇數的采用cos函數。
Position Embedding本身是一個絕對位置的信息,但在語言中,相對位置也很重要,Google選擇前述的位置向量公式的一個重要原因是,由於我們有:
這表明位置p+k的向量可以表示成位置p的向量的線性變換,這提供了表達相對位置信息的可能性。
在其他NLP論文中,大家也都看過position embedding,通常是一個訓練的向量,但是position embedding只是extra features,有該信息會更好,但是沒有性能也不會產生極大下降,因為RNN、CNN本身就能夠捕捉到位置信息,但是在Transformer模型中,Position Embedding是位置信息的唯一來源,因此是該模型的核心成分,並非是輔助性質的特征。
來源:https://mp.weixin.qq.com/s/7RgCIFxPGnREiBk8PcxOBg
來源:https://jalammar.github.io/illustrated-transformer/
參考:https://mp.weixin.qq.com/s/s2mvrF2pWBQ1M3fmwpf0Cg