一,概述html
在天然語言生成的任務中,大部分是基於seq2seq模型實現的(除此以外,還有語言模型,GAN等也能作文本生成),例如生成式對話,機器翻譯,文本摘要等等,seq2seq模型是由encoder,decoder兩部分組成的,其標準結構以下:node
原則上encoder,decoder能夠由CNN,RNN,Transformer三種結構中的任意一種組合。但實際的應用過程當中,encoder,decnoder的結構選擇基本是同樣的(即encoder選擇CNN,decoder也選擇CNN,如facebook的conv2conv)。所以本文咱們也就介紹encoder,decoder是同種結構的三種模型,並對比其內部結構在編碼和解碼的不一樣之處。git
二,模型介紹github
1)基於RNN的seq2seq模型函數
在這裏的encoder和decoder都採用RNN系列模型,通常是GRU,LSTM等。通常有兩種用法:即單向encoder-單向decoder;雙向encoder-單向decoder(在這裏要保證encoder的hidden_size等於decoder的hidden_size,可是對於雙向encoder時,由於通常採用拼接來融合雙向信息,所以此時encoder的hidden_size通常爲decoder的hidden_size的一半)。post
基於RNN的encoder端和用RNN作分類問題基本一致,但在decoder端須要融入encoder端的信息,所以是有一些不同的,以GRU爲例(LSTM同理):編碼
encoder端:url
$r_t = \sigma(W_r [h_{t-1}, x_t])$spa
$z_t = \sigma(W_z [h_{t-1}, x_t])$翻譯
$\hat{h_t} = tanh(W_{\hat{h}} [r_t * h_{t-1}, x_t])$
$h_t = (1 - z_t) * h_{t-1} + z_t * \hat{h_t}$
decoder端:須要融入attention後的encoder的編碼向量$c_t$
$r_t = \sigma(W_r [h_{t-1}, x_t, c_t])$
$z_t = \sigma(W_z [h_{t-1}, x_t, c_t])$
$\hat{h_t} = tanh(W_{\hat{h}} [r_t * h_{t-1}, x_t, c_t])$
$h_t = (1 - z_t) * h_{t-1} + z_t * \hat{h_t}$
注:在decoder中的矩陣$W_r, W_z, W_{\hat{h}}$和encoder中的維度是不一樣的,由於後面的$ [h_{t-1}, x_t, c_t]$是拼接操做,這裏面的$ h_{t-1}, x_t, c_t$都對應一個映射矩陣,只是爲了方便操做,將他們對應的矩陣也拼接在一塊兒計算了。
2)基於conv的seq2seq模型
基於卷積的seq2seq模型好像使用範圍沒有那麼廣,目前我見到的只有在機器翻譯和語法糾錯中有用到(固然確定不排除在其餘任務中有使用),可是基於卷積的seq2seq是引入了很多有意思的知識,首先引入了stacking conv來捕捉長距離的信息。主要圍繞facebook的Convolutional Sequence to Sequence Learning 來說解。
1)不採用池化,只採用卷積操做,而且經過padding使得每一層卷積後的序列長度不變(這種操做能夠確保在多層conv中序列長度保持一致)。
2)對於輸入$x$,其維度爲$n*d$,在這裏假設kernel size的大小爲$k$,則給定一個卷積的參數矩陣$W$,其維度爲$2d*kd$(本質就是一個kernel size爲k的一維卷積對序列作卷積操做,而且filter size爲2d,這樣使得卷積後的token的向量的維度爲2d),使得轉換後的$h$(x的隱層表示)的維度爲$n*2d$。
3)引入GLU門機制激活函數,其表達式以下:
以上面獲得的$h$爲例,其前半段$h*d$置爲A,其後半段$h*d$置爲B,對B用sigmoid函數激活後相似於門機制,而後對$A$和$\sigma(B)$作元素對應相乘,這樣也保證了每一層卷積後的輸出維度和輸入維度一致(這就是爲何第2步要使得卷積後的token的向量維度爲$2d$,這種門機制在不少地方均可以使用,用來取代激活函數,既能夠作非線性轉換,又能夠過濾重要的信息)。
4)採用了multi-step attention來鏈接encoder和decoder,即對decoder的每一層都單獨計算attention(至於爲何要這樣作,我猜多是由於卷積是提取局部信息的,而每一層提取的局部信息都不同,由於每一層對encoder的結果的關注位置也是不同的,所以每一層對encoder的attention也應該是不同的)。
3)基於transformer的seq2seq模型
基於transformer的seq2seq模型來源於attention is all you need,具體的介紹能夠見詳解Transformer模型(Atention is all you need)。
三,三種模型的對比
從encoder,decoder,attention三個部位來對比
encoder端:
1)RNN
RNN的encoder端和常見的用於分類的RNN模型沒有什麼區別,輸入$x$,獲得最後一層的隱層狀態,用於以後計算attention。
2)conv
在這裏採用stacking conv來對輸入$x$編碼,做者認爲這種stacking conv是能夠捕獲到長距離的信息的,假設卷積的kernel size爲3,第一層卷積能覆蓋的最大長度爲3(對原始序列),第二層卷積能覆蓋的最大長度爲$3^2$(對原始序列),依次類推,所以隨着卷積層的增加,在原始序列上能覆蓋的最大長度呈指數增加。一樣去最後一層的隱層狀態,用於以後計算attention。同時在每一層之間都引入了殘差鏈接和batch normalization。
3)transformer
transformer的encoder和以前介紹的用transformer作分類基本一致(文本分類實戰(八)—— Transformer模型)。整個結構由self-attention和feed forward層組合而成的,一樣將最後一層的隱層狀態用於以後計算attention。
attention端:
1)RNN
RNN的attention都是基於decoder中的目標詞和encoder的序列中的每個詞計算點積(或者其餘的計算方式,如MLP,conv等均可以),而後softmax獲得一個機率分佈,也就是attention的權值。而後對encoder的序列中的每一個詞對應的向量作加權和獲得最終的attention的結果。具體的以下圖:
2)conv
卷積中的attention的計算和RNN中的基本一致,可是最後在作加權和的時候引入了最初encoder中embedding的詞向量,其表達式以下:
上面式子中$\alpha_{ij}^l$是表示$l$解碼層對應的attention權重,$z_j^u$表示的是encoder最後的隱層結果,$e_j$表示的是encoder最初的embedding層的詞向量,$j$表示encoder中第$j$個詞。
3)transformer
transformer的attention計算有點不太同樣,在這裏仍然使用了在作self-attention計算中的multi-attention和scaled-attention。所以這裏雖然目標詞是來源於decoder,可是整個計算過程和transformer中的self-attention是一致的。
decoder端:
1)RNN
RNN在解碼時通常都是用單層,由於從左到右的這種單層模式也符合解碼的模式,dencoder的層數也通常和encoder保持一致。RNN的解碼如上面的GRU示例同樣,只是在計算的過程當中引入了encoder的結果,其餘的和encoder沒什麼太大的差別。
2)conv
conv在解碼時主要是在序列的補全時和encoder不同,爲了保持卷積後序列的長度不變,encoder時會在序列的兩端添加長度爲$(kernel size - 1) / 2$的pad。而在decoder時會在序列的左端添加長度爲$(kernel size - 1)$的pad(在這裏kernel size通常取奇數,便於添加pad)。另外不一樣於RNN的是(RNN是將attention引入到了RNN結構中),conv在解碼時的卷積操做只是提取序列的特徵,而後通過GLU操做到和encoder的隱層相同的向量維度以後再計算attention,最後將attention的結果和GLU的結果和卷積前的結果相加做爲下一層的輸入。另外在解碼的每一層都引入了殘差鏈接和batch normalization。
3)transformer
transformer的decoder層其實和encoder層差很少,主要不一樣在加入了encoder的attention的結果,但這裏和RNN,conv又優勢不同,這裏是先對decoder中的序列作self-attention提取特徵,而後再作對encoder的attention,而後進入到feed forward層,所以在這裏的操做是串行的。一樣再transformer中由於層數比較多,也引入了殘差鏈接和Layer normalization(在天然語言處理中不少layer normalization的用的比batch normalization,除非是卷積,否則通常不用batch normalization)。
除了上面的不一樣點以外,通常來講transformer和conv的層數都比較深,所以也就須要殘差鏈接和normalization來避免模型過擬合。此外在transformer和conv中都會引入位置向量來引入序列的位置信息,可是在RNN中,由於RNN的本質是從前日後又依賴關係的,所以位置信息在這種傳遞過程當中已經存在了。
上述模型具體的代碼見 https://github.com/jiangxinyang227/NLP-Project/tree/master/dialogue_generator
參考文獻:
Convolutional Sequence to Sequence Learning
NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE
Attention Is All You Need
A Multilayer Convolutional Encoder-Decoder Neural Network for Grammatical Error Correction