目錄網絡
寫這篇博客主要是爲了進一步瞭解如何將CNN看成Encoder結構來使用,同時這篇論文也是必看的論文之一。該論文證實了使用CNN做爲特徵抽取結構實現Seq2Seq,能夠達到與 RNN 相接近甚至更好的效果,而且CNN的高並行能力可以大大減小咱們的模型訓練時間(本文對原文中不清晰的部分作了梳理,建議與原文搭配服用)ide
原文連接:Convolutional Sequence to Sequence Learning函數
模型結構以下圖所示:
編碼
下面對模型的每一個部分進行分塊介紹:spa
卷積網絡和Transformer同樣,不是相似於RNN的時序模型,所以須要加入位置編碼來體現詞與詞之間的位置關係設計
GLU和GTU是在同一篇論文中提出的,其中,GLU也是CNN Seq2Seq的主要結構。能夠直接將其看成激活函數來看待,其將某以卷積核的輸出輸入到兩個結構相同的卷積網絡,令其中一個的輸出爲\(A\),另外一個爲\(B\)。
GLU與GRU的區別就在於A輸出的激活函數不一樣:
\[GLU:H_0=A \otimes \sigma (B)\]code
\[GTU:H_0=tanh(A) \otimes \sigma (B)\]orm
而CNN Seq2Seq就採用了GLU做爲模型的激活函數對象
原文連接:Language Modeling with Gated Convolutional Networksblog
編碼器與解碼器都是由多個卷積層構成的(原文中稱爲block,實際上就是layer),每一層包含一個1維卷積核以及一個門控線性單元(Gated linear units, GLU)。假設單詞數即輸入長度爲\(m\),kernel大小爲\(k\),pad爲\(p\),那麼計算輸出sequence長度的公式爲\((m+2p-k)/stride+1\),只要適當的設置卷積核的kernel大小、pad以及步長參數,便可使得輸出序列與輸入序列的維度保持一致。在文中,輸入爲25,kernel爲5,則輸出序列長度爲(25+2*2-5)/1+1=25。
另外,爲了充分讓輸出節點跟整個sequence單詞有聯繫,必須使用多個卷積層,這樣才能使得最後一個卷積核有足夠大得感覺野以感覺整個句子的特徵,同時也能捕捉局部句子的特徵。
來看一下整個編碼器的前向傳播方式:
這樣的卷積策略保證了每一層的輸入與輸出序列的一一對應,而且可以將其看做簡單的編碼器單元,多層堆疊以實現更深層次的編碼。
對於Attention的計算,關鍵就是找到 Query、Key 和 Value。下圖爲計算Attention且解碼的示意圖
Attention的計算過程以下:
Query由decoder的最後一個卷積層的輸出\(h_i^l\)以及上一時刻decoder最終的生成的目標\(g_i\)共同決定,\(W^l_d\)與\(b_d^l\)爲線性映射的參數。
\[d_i^l = W^l_dh^l_i+b_d^l+g_i\]
Key 則採用 Encoder 的輸出\(z_j^u\),典型的二維匹配模型,將 Query 與 Key 一一對齊,計算 dot attention分數:
\[a_{ij}^l = \frac{exp(d^l_i \cdot z^u_j)}{\sum_{t=1}^mexp(z_j^u+e_j)}\]
Value 的值則取編碼器的輸出\(z_j^u\)以及詞向量表徵\(e_j\)之和,目的是爲編碼器的輸出加上位置表徵信息。獲得對應的 Value 值 \(c_i^l\) 以後,直接與當前時刻的 Decoder 輸出 \(h_i^l\) 相加,再輸入分類器進行分類。
\[c_i^l = \sum_{j=1}^ma_{ij}^l(z_j^u + e_j)\]
模型還經過歸一化策略來保證經過每一層模型的方差變化不會太大,這裏先簡單的記錄一下,具體的操做細節須要回去仔細琢磨代碼。歸一化的主要策略以下:
初始化的目的與歸一化是一致的,即都是爲了保證前向與後項傳播的數據方差可以保持在一個較穩定的水準,模型初始化的策略以下:
最後的實驗部分就不記錄了,有興趣的同窗能夠去原文裏看看。
https://zhuanlan.zhihu.com/p/26918935
https://zhuanlan.zhihu.com/p/27464080
https://www.zhihu.com/question/59645329/answer/170014414