一、CNN文本分類簡介
文本分類是NLP領(lǐng)域的一個(gè)重要子任務(wù),文本分類的目標(biāo)是自動的將文本打上已經(jīng)定義好的標(biāo)簽,常見的文本分類任務(wù)有:
- 用戶評論的情感識別
- 垃圾郵件過濾
- 用戶查詢意圖識別
- 新聞分類
由此看出文本分類的用途十分之廣,包括知識圖譜領(lǐng)域的關(guān)系抽取任務(wù)也是使用文本分類實(shí)現(xiàn)的。
有很多經(jīng)典的統(tǒng)計(jì)學(xué)習(xí)方法可以用來做文本分類,比如SVM,LR,MaxEnt等等。這些方法的一般流程是標(biāo)注數(shù)據(jù)、特征工程、模型訓(xùn)練、模型預(yù)測。有過相關(guān)經(jīng)驗(yàn)的同學(xué)應(yīng)該知道,這里最耗費(fèi)時(shí)間的過程應(yīng)該就是特征工程。這里特征通常有詞法特征、語法特征等等,下面找了一篇關(guān)于特征設(shè)計(jì)的論文供大家參考:http://www.aclweb.org/anthology/S10-1057

?
這是篇關(guān)系抽取的論文,但其中特征的設(shè)計(jì)可以供我們參考 。這個(gè)表中的特征有詞性識別(pos)、依存分析(dependency)、N-gram等,除此之外還使用很多外部知識庫,比如wordNet/FrameNet/TextRunner等等,要想訓(xùn)練一個(gè)比較好的文本分類器,需要設(shè)計(jì)大量的特征,有的任務(wù)特征會達(dá)到千萬級別。特征設(shè)計(jì)這里主要有兩個(gè)缺點(diǎn):
- 需要一些背景知識設(shè)計(jì)各種精巧的特征
- 需要借助其他NLP工具。NLP工具本身會有一些誤差,這樣就將誤差傳播到后續(xù)的任務(wù)中
這里就不得不提深度學(xué)習(xí)的強(qiáng)大,比如CNN可以自動的提取一些文本的特征而不需要再人工設(shè)計(jì)大量的特征,而且在準(zhǔn)確率上甚至比人工設(shè)計(jì)特征的方法還要高。也難怪目前NLP領(lǐng)域都開始上深度學(xué)習(xí)了。
二、CNN模型
2.1 CNN模型簡介
卷積神經(jīng)網(wǎng)絡(luò)(CNN)跟全連接神經(jīng)網(wǎng)絡(luò)一樣,CNN的每一層也是由神經(jīng)元組成的,全連接神經(jīng)網(wǎng)絡(luò)中,每相鄰的兩層之間的節(jié)點(diǎn)都有邊相連,而CNN相鄰層之間只有部分節(jié)點(diǎn)相連,并且在CNN的輸入層、卷積層、池化層中,每層的維度包括輸入都是三維的。
CNN通常由輸入層、卷積層、池化層、全連接層、softmax層組成,下面簡單介紹下這幾層,以方便大家理解CNN是如何工作的。
2.1.1 卷積層
卷積層是卷及神經(jīng)網(wǎng)絡(luò)中最重要的部分,這個(gè)部分通常被稱作過濾器(filter)或內(nèi)核(kernel),在這里我們稱之為過濾器。下圖是一個(gè)過濾器工作的示意圖:


?


?
輸入經(jīng)過一個(gè)filter處理后得到的粉紅色區(qū)域叫做Feature Map,在示意圖中filter的尺寸是[圖片上傳失敗...(image-e4bdc7-1557814223444)]
,在實(shí)際應(yīng)用中這個(gè)尺寸也是根據(jù)需求人工設(shè)定的,一般設(shè)定為[圖片上傳失敗...(image-bbecc1-1557814223444)]
等等。因?yàn)檫^濾器處理矩陣的深度與當(dāng)前層神經(jīng)網(wǎng)絡(luò)矩陣的深度時(shí)一致的,所以在這里我們只設(shè)定過濾器的長和寬就可以了,另外我們還需要指定過濾器的深度。過濾器的作用在圖像領(lǐng)域比較好理解,就是提取圖像局部的特征。
2.2.2 池化層
在卷積層之后往往會加入一層池化層,池化層可以有效縮小矩陣的尺寸,從而減少最后全連接層的參數(shù),利用池化層既可以加速計(jì)算也可以減小過擬合。下圖是池化層工作的示意圖,使用一個(gè)尺寸為[圖片上傳失敗...(image-aae9b9-1557814223444)]
的filter進(jìn)行max pooling。






?
**2.2.3 經(jīng)典卷積模型LeNet-5 **
卷積神經(jīng)網(wǎng)絡(luò)的特有結(jié)構(gòu)為卷積層和池化層,通過這種網(wǎng)絡(luò)結(jié)構(gòu)組合而得的神經(jīng)網(wǎng)絡(luò)有無限多種,下面我們介紹一個(gè)經(jīng)典的卷積模型LeNet-5 ,這個(gè)模型是在論文Gradient-based learning applied to document recognition中提出的,它是第一應(yīng)用于數(shù)字識別的卷積神經(jīng)網(wǎng)絡(luò),在MNIST數(shù)據(jù)集上LeNet-5模型上可以得到99.2%的準(zhǔn)確率,它一共有7層結(jié)構(gòu):

?
從左到右分別是:卷積、池化、卷積、池化、全連接、全連接、全連接。
2.2 CNN文本分類
上面章節(jié)簡單對CNN進(jìn)行了介紹,那回到我們的正題,繼續(xù)說CNN和文本分類,我們以一篇經(jīng)典的論文方法介紹下CNN是如何用于文本分類的(論文地址:https://arxiv.org/pdf/1408.5882.pdf)。

?
這篇論文提出的模型架構(gòu)圖如上,整體模型主要分為三個(gè)部分:輸入層、卷積+池化層、全連接+softmax層??梢钥闯?,這個(gè)模型跟我們前面介紹LeNet-5模型相比結(jié)構(gòu)簡單了許多,這也是由文本輸入特殊性造成的。
2.2.1 輸入層
輸入層會將一段文本轉(zhuǎn)換成卷積層所需要的輸入格式,一般會得到一個(gè)三維的輸入[圖片上傳失敗...(image-a61c54-1557814223444)]
。
其中[圖片上傳失敗...(image-82634d-1557814223444)]
代表一段文本單詞數(shù)量。因?yàn)槲谋镜膯卧~數(shù)量是變長的,在這里我們需要對輸入文本做預(yù)處理,將其加工成定長。常用的方法有取數(shù)據(jù)中最長文本長度、統(tǒng)計(jì)文本長度分布取一個(gè)能覆蓋大部分文本的長度。這里推薦第二種方法。
[圖片上傳失敗...(image-6fd036-1557814223444)]
代表embedding的維度。每個(gè)單詞的embedding可以使用word2vec或者GloVe訓(xùn)練好的詞向量,比如這個(gè)網(wǎng)站上有使用GloVe模型訓(xùn)練好的詞向量,地址:https://nlp.stanford.edu/data/,其中詞向量維度有50,100,200,300維。當(dāng)然也可以使用完全隨機(jī)的詞向量。不過一般實(shí)驗(yàn)證明,使用pre-trained詞向量對于一般的NLP任務(wù)都有提升。
[圖片上傳失敗...(image-1ef4bb-1557814223444)]
對于一個(gè)圖像來說通常是3,代表RGB圖片,對于文本來說,通常這個(gè)值為1。不過這篇文章中提出了一種multi-channel方法,將這個(gè)設(shè)置為2,其實(shí)就是將兩種文本的不同來源的embedding拼到了一起,下面介紹下論文中提到不同embedding的方法
<caption>不同類型輸入</caption>
|
|
|
| CNN-rand | 所有的word vector都是隨機(jī)初始化的,同時(shí)當(dāng)做訓(xùn)練過程中優(yōu)化的參數(shù) |
| CNN-static | 所有的word vector直接使用無監(jiān)督學(xué)習(xí)即Google的Word2Vector工具(COW模型)得到的結(jié)果,并且是固定不變的 |
| CNN-non-static | 所有的word vector直接使用無監(jiān)督學(xué)習(xí)即Google的Word2Vector工具(COW模型)得到的結(jié)果,但是會在訓(xùn)練過程中被Fine tuned |
| CNN-multichannel | CNN-static和CNN-non-static的混合版本,即兩種類型的輸入 |
2.2.2 卷積+池化層
經(jīng)過輸入層后,我們得到了表示文本的三維輸入,它的形狀為[圖片上傳失敗...(image-46335-1557814223443)]
,接下來我們對輸入進(jìn)行卷積操作。卷積filter的尺寸為[圖片上傳失敗...(image-e716d2-1557814223443)]
,其中[圖片上傳失敗...(image-3e45c7-1557814223443)]
代表filter長度,也就是每次處理文本中單詞的數(shù)量;[圖片上傳失敗...(image-8243a1-1557814223443)]
代表embedding的維度;[圖片上傳失敗...(image-3be78c-1557814223443)]
代表filter的深度,我們可以使用不同的[圖片上傳失敗...(image-255b48-1557814223443)]
分別進(jìn)行卷積來提取更多的特征。可以看出每次卷積的時(shí)候都是整行整行的進(jìn)行。當(dāng)[圖片上傳失敗...(image-6b5203-1557814223443)]
可以理解為unigram特征,[圖片上傳失敗...(image-785ccc-1557814223443)]
的時(shí)候就是bigram特征。在卷積層我們分別采取[圖片上傳失敗...(image-b419e5-1557814223443)]
進(jìn)行卷積就得到了三個(gè)feature map,每個(gè)feature map的長度跟原文本的長度相關(guān),寬度為[圖片上傳失敗...(image-b56d23-1557814223443)]
,經(jīng)過卷積層后我們就提取到了原文本的n-gram相關(guān)特征。
在池化層采用了max-pooling的方法,池化層的filter的[圖片上傳失敗...(image-ef9c30-1557814223443)]
,其中[圖片上傳失敗...(image-837cf6-1557814223443)]
代表對文本卷積后feature map的長度。經(jīng)過池化后feature map的維度會降為1,因此pooling結(jié)束后,得到向量的維度就是[圖片上傳失敗...(image-7311e4-1557814223443)]
,這樣就得到整個(gè)文本的特征表示。
這個(gè)模型只使用了一層卷積+一層池化,跟LeNet-5模型相比,還是太過于簡單了,但是從paper中的實(shí)驗(yàn)來看,這個(gè)模型性能已經(jīng)很好了,那么問題來了
- CNN用于文本可以采用多層卷積+池化的結(jié)構(gòu)嗎?
- CNN提取的特征究竟代表什么意義?
- max-pooling的方法過于簡單粗暴,有沒有什么別的方法?
2.2.3 全連接+softmax層
經(jīng)過卷積池化后我們得到了表示文本的特征向量,然后再經(jīng)過一個(gè)全連接+softmax層就得到了代表屬于不同類別的概率向量,也就完成了分類的工作。
三、實(shí)驗(yàn)結(jié)果
貼一個(gè)原文的實(shí)驗(yàn)結(jié)果:

?
- pre-trained詞向量能明顯提升分類效果,可以看出CNN-static是明顯好于CNN-rand的結(jié)果
- CNN-multichannel在小數(shù)據(jù)集上好于CNN-singlechannel。作者初始是希望multichannle避免過擬合,是詞向量盡量不要偏離原始預(yù)訓(xùn)練好的詞向量同時(shí)也使詞向量適應(yīng)于具體的任務(wù)
- CNN-non-static比大部分CNN-static好,說明適當(dāng)fine-tune是有用的,使詞向量適當(dāng)適應(yīng)具體任務(wù),如下表所示,對于'bad'這個(gè)詞,static channel將'good'作為鄰居詞,這對情感分析類的任務(wù)是不太準(zhǔn)確的。而Non-static channel經(jīng)過fine tune就得到‘terrible’的鄰居詞,這跟情感分析任務(wù)是對應(yīng)的。

?
下面給出一些調(diào)參技巧,出自https://blog.csdn.net/memray/article/details/51454208
下面總結(jié)一下Ye Zhang等人基于Kim Y的模型做了大量的調(diào)參實(shí)驗(yàn)之后的結(jié)論:
- 由于模型訓(xùn)練過程中的隨機(jī)性因素,如隨機(jī)初始化的權(quán)重參數(shù),mini-batch,隨機(jī)梯度下降優(yōu)化算法等,造成模型在數(shù)據(jù)集上的結(jié)果有一定的浮動,如準(zhǔn)確率(accuracy)能達(dá)到1.5%的浮動,而AUC則有3.4%的浮動;
- 詞向量是使用word2vec還是GloVe,對實(shí)驗(yàn)結(jié)果有一定的影響,具體哪個(gè)更好依賴于任務(wù)本身;
- Filter的大小對模型性能有較大的影響,并且Filter的參數(shù)應(yīng)該是可以更新的;
- Feature Map的數(shù)量也有一定影響,但是需要兼顧模型的訓(xùn)練效率;
- 1-max pooling的方式已經(jīng)足夠好了,相比于其他的pooling方式而言;
- 正則化的作用微乎其微。
Ye Zhang等人給予模型調(diào)參者的建議如下:
- 使用
non-static版本的word2vec或者GloVe要比單純的one-hot取得的效果好得多; - 為了找到最優(yōu)的過濾器(Filter)大小,可以使用線性搜索的方法。通常過濾器的大小范圍在
1-10之間,當(dāng)然對于長句,使用更大的過濾器也是有必要的; -
Feature Map的數(shù)量在100-600之間; - 可以盡量多嘗試激活函數(shù),實(shí)驗(yàn)發(fā)現(xiàn)
ReLU和tanh兩種激活函數(shù)表現(xiàn)較佳; - 使用簡單的
1-max pooling就已經(jīng)足夠了,可以沒必要設(shè)置太復(fù)雜的pooling方式; - 當(dāng)發(fā)現(xiàn)增加
Feature Map的數(shù)量使得模型的性能下降時(shí),可以考慮增大正則的力度,如調(diào)高dropout的概率; - 為了檢驗(yàn)?zāi)P偷男阅芩剑啻畏磸?fù)的交叉驗(yàn)證是必要的,這可以確保模型的高性能并不是偶然。
四、代碼實(shí)現(xiàn)
CNN文本分類的tensorflow實(shí)現(xiàn)
執(zhí)行訓(xùn)練
使用隨機(jī)初始化的詞向量進(jìn)行訓(xùn)練
python train.py --input_layer_type 'CNN-rand'

使用與訓(xùn)練好的GloVe 詞向量訓(xùn)練,在訓(xùn)練過程中詞向量不可訓(xùn)練,是固定的
python train.py --input_layer_type 'CNN-static'

使用與訓(xùn)練好的GloVe 詞向量訓(xùn)練,在訓(xùn)練中微調(diào)詞向量
python train.py --input_layer_type 'CNN-non-static'

使用兩個(gè)詞向量組成雙通道作為輸入,一個(gè)固定,另一個(gè)可以微調(diào)
python train.py --input_layer_type 'CNN-multichannel'

Preference
http://www.jeyzhang.com/cnn-apply-on-modelling-sentence.html