利用CNN來做NLP(textcnn)

講到nlp,我們常用的都是lstm/gru。
舉個例子,因爲我們總會說,因爲句子經過embdding後,句子爲一個三維張量,假設爲:(None,20,300)。其中20爲timestep,也就是一個句子的單詞個數,300爲embdding維度。爲了更深的理解句子,剖析句子語意,我們假設接上一層lstm(num_units=128,return_sequence=True),那麼輸出的張量就爲(None,20,128)。你會發現句子的embedding維度變了,我們可以說經過lstm後,我們用一種更高級的方式表示出了單詞的維度,不再是300,而是128了。也就是句子變了。我們往往會接上兩層這樣的lstm,之後再接一些池化層、全連接層等等,一個基本的nlp分類網絡就形成了~

那麼如果我告訴你CNN同樣可以改變句子的維度,就像lstm那樣變成一個新的句子,且新句子更容易被網絡理解,而且提供了n-gram的信息。是不是很神奇?

等一下。n-gram?他不是tfidf那邊的東西嗎?(如果不明白n-gram,請先自行百度)我們爲了結合單詞間的關係,我們把連續的2個詞,3個詞…稱爲一個term。在神經網絡也可以完成這樣的轉換?是的,這就是textcnn。

OK。textcnn我不想講太多,我建議直接看下面這篇博文,我自己寫也寫不了這麼多,這麼好。但是看完後,我會加一些自己的東西。

鏈接:[NLP] TextCNN模型原理和實現

看完之後我想你一定有一些體會,但是肯定還會有一些疑問。我想你的疑問不外乎這些:
1.我想知道textcnn每一步之後的輸出張量的形狀,這樣我方便知道每一層發生了什麼,顯然上面的鏈接沒有給你很直觀的體驗。
2.我想知道爲什麼用Maxpooling不用平均池化?
3.我想知道爲什麼要用池化。。。
4。卷積和池化和我以前在cv裏看到的不一樣。。看不懂。。

1,4我將用一段代碼來解釋。2,3在後面我將將一些自己的理解。
下面是一個簡短的textecnn的代碼:

    xconv1 = Convolution1D(filters=50,
                        kernel_size=1,
                        padding='same',
                        activation='relu')(x)
    
    xconv2 = Convolution1D(filters=50,
                        kernel_size=2,
                        padding='same',
                        activation='relu')(x)

到這裏我們停一下,我們設x形狀:(None,20,300)
請你回答我的xonv1,xonv2的形狀?我如果padding='valid’呢?形狀變不變?
首先第一個問題啊,2個輸出都是(None,20,50)。首先解釋一下:
Convolution1D,確實有兩個方向可以做卷積,比如嘛,對於conv1,這裏不是(20,300)的矩陣嗎,我顯然做一維卷積,我的單個卷積核可以是(20,1)或者(300,1),一個實現的是詞方向的卷積,一個實現的是embedding方向的卷積。但是明顯,,,我們是要詞方向的啊。所以卷積核形狀一定是(300,1)。這樣的話,每一個卷積核都會產生一個20維向量,50個自然是(20,50)了~
補充:對於conv2,卷積核形狀:(300,2)
第二個問題,我其實是爲例迎合這個圖:
在這裏插入圖片描述
這個圖經過卷積後,每一個卷積核生成的向量怎麼長度不一?如果你pad的話,肯定是一樣的,你不pad,也就是padding=‘valid’。那麼不填充自然就維度不一了。

接下來爲了不亂,我們只對conv1池化:

xconv1 = GlobalMaxPooling1D()(xconv1)

已知池化前形狀:(None,20,50)輸出形狀是啥?
直接說了哦,是(None,1,50)
也就是(None,50).。
爲什麼不是(None,20)?
我只說一句話你就懂了。
GlobalMaxPooling1D是對整個feature_map上取最大值。(定義使然)feature_map不就是20維的向量嗎,我們再找最大值,20–》1,不自然而然的變成了(None,1,50)了嗎。
應該明白了吧。

對於問題3。我簡單說一下:因爲20,也就是time_step,是你pad sentence後補齊、截取得到的,取平均的話裏面可能有很多補的0.因爲這個和我們textcnn關係不大,我簡單說一下,如不懂請留言。

問題4:
https://www.cnblogs.com/ymjyqsx/p/6485924.html

最後附上膨脹卷積的處理方式,它考慮了跳過一些單位之間詞的關係。

    xconv3 = Convolution1D(filters=50,
                        kernel_size=4,dilation_rate=2,
                        padding='same',
                        activation='relu')(x)

關於空洞卷積/膨脹卷積:
https://www.zhihu.com/question/54149221

最後論文鏈接:
https://arxiv.org/pdf/1408.5882.pdf

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章