??首先需要明確的是,Transformer是一個翻譯模型凛剥。與之前主流的翻譯模型相比,transformer的依然是一個encoder-decoder結(jié)構(gòu),改變的主要是encoder和decoder內(nèi)部的組成客们,改變結(jié)構(gòu)帶來的優(yōu)勢是使得模型可以并行化訓(xùn)練。Transformer的結(jié)構(gòu)如下:
transformer結(jié)構(gòu).png
圖中左邊就是encoder部分材诽,右邊就是decoder部分底挫。
下面來具體看下兩個部分的組成。首先看encoder部分脸侥,如下圖:
transformer中encoder的主要組成.png
encoder主要結(jié)構(gòu)組成包括一個self-attention模塊和一個FFN模塊建邓。之所以是self-attention,是因為輸入的Q睁枕、K官边、V都是輸入句子對應(yīng)的embedding矩陣。此外還加上了resnet中的殘差結(jié)構(gòu)外遇,減少了梯度消失的風(fēng)險注簿,使得模型更好訓(xùn)練。
再來看看decoder部分跳仿,如下圖:
transformer中decoder的主要組成.png
decoder主要結(jié)構(gòu)組成包括一個self-attention模塊诡渴,一個encoder-decoder-attention模塊和一個FFN模塊。其中self-attention模塊和FFN模塊和encoder部分中的相同菲语,而encoder-decoder-attention模塊在結(jié)構(gòu)上也和self-attention模塊一樣妄辩,不同點在于encoder-decoder-attention模塊中的K和V是encoder部分的輸出,Q是自身self-attention模塊的輸出山上。
前文已經(jīng)提到眼耀,transformer的主要改進(jìn)在于可以并行化訓(xùn)練 。之前主流的翻譯模型中encoder和decoder組成都是RNN佩憾,但是RNN是不能并行化訓(xùn)練的畔塔,只有前一時刻訓(xùn)練結(jié)束才能進(jìn)行當(dāng)前時刻的訓(xùn)練(就像GBDT一樣,每棵樹的訓(xùn)練是依賴前一棵樹的)鸯屿。但是transformer中attention結(jié)構(gòu)不一樣澈吨,它是將每個時刻的輸入信息之間的距離視為1,任意兩個時刻的輸入信息是可以直接交互運算的寄摆。attention中信息之間的交互計算是通過矩陣運算實現(xiàn)的谅辣,而矩陣運算是可以很好的進(jìn)行并行計算的。RNN和attention中信息的處理如下圖:
RNN中t時刻信息與t-2時刻信息的交互必須要先經(jīng)過t-1時刻婶恼,但是attention中t時刻和t-2時刻之間可以直接交互桑阶。沒有了時序上的限制柏副,attention結(jié)構(gòu)就可以進(jìn)行并行化計算了。同時attention結(jié)構(gòu)另外一個優(yōu)勢在于長期依賴問題得到緩解蚣录,比如RNN中t+2時刻信息與t-2時刻的信息依賴關(guān)系之間相差4步割择,但是attention中兩者可以直接計算,因此可以認(rèn)為兩者相距為1萎河。不過盡管attention中長期依賴問題得到緩解荔泳,但是也帶來另外一個問題,就是對位置信息的忽略虐杯。時序數(shù)據(jù)中數(shù)據(jù)的先后關(guān)系是很重要的玛歌,比如一句話中兩個單詞的顛倒可能就會導(dǎo)致完全不同的含義。Transformer的補(bǔ)救措施是給輸入信息加上了位置編碼擎椰,如下圖:
也就是對每個單詞對應(yīng)的embedding向量再加上位置編碼向量支子。位置編碼公式如下:其中,是信息在序列中的位置达舒,而是位置編碼的維度序號值朋,且。為什么要用這個函數(shù)呢巩搏?文中給的解釋是:
We chose this function because we hypothesized it would allow th emodel to easily learn to attend by relative positions, since for any fixed offset k, can be represented as a linear function of
這里我給下個人解釋昨登,位置編碼后會得到一個矩陣,行數(shù)就是序列的長度塔猾,列數(shù)就是embedding維度篙骡。每一列上的值都是從同一個頻率的正弦函數(shù)上取出的,每一行就是一個單詞的位置編碼向量丈甸,這個向量是由多個不同頻率的正弦函數(shù)組成糯俗。由于相同列都是從同一頻率的正弦函數(shù)上取的值,所以不同行向量之間可以線性表示睦擂。不過為什么滿足這樣特性的編碼函數(shù)就是好的函數(shù)我還是不太明白得湘,這里挖個坑,以后弄懂了再來寫顿仇。
在PyTorch實現(xiàn)代碼 中實現(xiàn)位置編碼時并不是直接實現(xiàn)上述公式淘正,而是做了點改變。改變在于將公式中 改為 臼闻。個人猜測這樣改變可能會節(jié)約時間吧鸿吆。
有一點需要注意:transformer中的并行化計算只在encoder中進(jìn)行,在decoder中是不可以并行化計算的述呐。(經(jīng)評論指正惩淳,在訓(xùn)練階段decoder中也是可以進(jìn)行并行化計算的,只是在預(yù)測階段不可以進(jìn)行并行化計算) decoder中attention結(jié)構(gòu)的K和V是不變的乓搬,但是output embedding是變化的思犁,依賴于上一時刻decoder的輸出代虾。
接下來再來講下transformer中的attention結(jié)構(gòu)。Transformer中最基本的attention結(jié)構(gòu)是Scaled Dot-Product Attention激蹲,結(jié)構(gòu)如下:
Scaled Dot-Product Attention結(jié)構(gòu).png
其中棉磨,Q和K的列數(shù)是一樣的,而K和V的行數(shù)是一樣的学辱。Attention函數(shù)可以理解為將一個query和一個(key, value)對映射成一個輸出乘瓤,query和key進(jìn)行矩陣相乘得到相應(yīng)的weight,然后再將weight和value進(jìn)行矩陣相乘得到最終的輸出项郊。Transformer中用的是Multi-Head Attention馅扣,其實也是Scaled Dot-Product Attention組成的斟赚,Multi-Head Attention結(jié)構(gòu)圖如下:
Multi-Head Attention結(jié)構(gòu).png
其實Multi-Head Attention就是由多組Scaled Dot-Product Attention組成着降,transformer中先將高維的Q、K拗军、V映射到多個低維空間中任洞,在每個低維空間中進(jìn)行attention操作得到一個低維的輸出,然后再將這些低維輸出拼接起來得到和原始維度一樣的輸出发侵。這樣做的好處在于不增加計算量的情況下使得attention的效果更好了交掏。下面是Multi-Head Attention的PyTorch實現(xiàn)代碼 :
Multi-Head Attention實現(xiàn)代碼.png
其中self.linears的作用就是將原始的Q、K刃鳄、V映射到不同的低維空間中盅弛。
最后編輯于 :2019.05.03 19:23:19
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者