CNN在中文文本分類的應用

深度學習近一段時間以來在圖像處理和NLP任務上都取得了不俗的成績。一般,圖像處理的任務是藉助CNN來完成的,其特有的卷積、池化結構可以提取圖像中各類不一樣程度的紋理、結構,並最終結合全鏈接網絡實現信息的彙總和輸出。RNN因爲其記憶功能爲處理NLP中的上下文提供了途徑。html

在短文本分析任務中,因爲句子句長長度有限、結構緊湊、可以獨立表達意思,使得CNN在處理這一類問題上成爲可能。論文Convolutional Neural Networks for Sentence Classification(論文做者Yoon Kim)即在這一類問題上作了嘗試。首先來看看論文中介紹的模型結構及原理:
python

CNN模型結構以下:


一共包括4部分:

一、  輸入層:

如圖所示,輸入層是句子中的詞語對應的wordvector依次(從上到下)排列的矩陣,假設句子有 n 個詞,vector的維數爲  k  ,那麼這個矩陣就是  n × k 的(在CNN中能夠看做一副高度爲n、寬度爲k的圖像)。git

這個矩陣的類型能夠是靜態的(static),也能夠是動態的(non static)。靜態就是word vector是固定不變的,而動態則是在模型訓練過程當中,word vector也當作是可優化的參數,一般把反向偏差傳播致使word vector中值發生變化的這一過程稱爲Fine tune。(這裏若是word vector若是是隨機初始化的,不只訓練獲得了CNN分類模型,還獲得了word2vec這個副產品了,若是已經有訓練的word vector,那麼實際上是一個遷移學習的過程)github

對於未登陸詞的vector,能夠用0或者隨機小的正數來填充。windows

二、  第一層卷積層:

輸入層經過卷積操做獲得若干個Feature Map,卷積窗口的大小爲 h ×k ,其中 h  表示縱向詞語的個數,而  k  表示word vector的維數。經過這樣一個大型的卷積窗口,將獲得若干個列數爲1的Feature Map。(熟悉NLP中N-GRAM模型的讀者應該懂得這個意思)。網絡

三、  池化層:

接下來的池化層,文中用了一種稱爲Max-over-timePooling的方法。這種方法就是簡單地從以前一維的Feature Map中提出最大的值,文中解釋最大值表明着最重要的信號。能夠看出,這種Pooling方式能夠解決可變長度的句子輸入問題(由於無論Feature Map中有多少個值,只須要提取其中的最大值)。最終池化層的輸出爲各個Feature Map的最大值們,即一個一維的向量。app

四、  全鏈接+softmax層:

池化層的一維向量的輸出經過全鏈接的方式,鏈接一個Softmax層,Softmax層可根據任務的須要設置(一般反映着最終類別上的機率分佈)。機器學習

訓練方案:

在倒數第二層的全鏈接部分上使用Dropout技術,Dropout是指在模型訓練時隨機讓網絡某些隱含層節點的權重不工做,不工做的那些節點能夠暫時認爲不是網絡結構的一部分,可是它的權重得保留下來(只是暫時不更新而已),由於下次樣本輸入時它可能又得工做了,它是防止模型過擬合的一種經常使用的trikc。同時對全鏈接層上的權值參數給予L2正則化的限制。這樣作的好處是防止隱藏層單元自適應(或者對稱),從而減輕過擬合的程度。學習

在樣本處理上使用minibatch方式來下降一次模型擬合計算量,使用shuffle_batch的方式來下降各批次輸入樣本之間的相關性(在機器學習中,若是訓練數據之間相關性很大,可能會讓結果不好、泛化能力得不到訓練、這時一般須要將訓練數據打散,稱之爲shuffle_batch)。優化

論文做者也公佈了本身的實現程序(下載戳這裏),同時有一位同行對上述論文給出瞭解讀並基於上述程序作了對比實驗(論文解讀戳這裏)。本人上面的分析也是基於原始論文和解讀,算是錦上添花吧。

實驗流程及結果:

參考上述論文和源程序,本人對其在中文短文本分類問題上進行了實驗。

實驗要求:

       Python環境

       安裝結巴分析的python版本

       安裝numpy、pandas等一系列科學計算相關庫,windows下藉助Anaconda進行安裝比較方便

       安裝theano,這個參考各類安裝、使用教程吧。

語料庫:使用的是搜狗語料庫,搜索SogouC.reduced可找到下載鏈接。

文本預處理:

       使用jieba分詞後將一些實詞漢詞提取出來,同時,因爲CNN輸入窗口的大小是必定的,對於長度小於N的句子,使用Pad with zeroes的方式,對於長度大於N的句子,將其切分爲若干段長度小於等於N的句子。使用軍事和教育兩個題材的預料進行處理後,樣本總數量大體在2W的樣子。

訓練調參:

       模型結構與trikc均與原文一直,在處理word vector size時,採用原始論文采用的300時,效果不是太理想,將該參數調低,採用szie=50、size=100,最終效果還算能夠。同時,feature_map的數量要比word vector size值大一些,以儘量提取更爲豐富的句子信息。

       下面是訓練過程當中的一些結果:


word vector size=50& feature_maps size = 100

來看看訓練獲得的wordvector在語義空間的映射效果若是,以該詞對應的向量空間的餘弦積的形式衡量詞之間的類似性:


左:word vector size=50 & feature_maps size= 100 右:word vector size=100& feature_maps size = 100

軍事題材類的詞,語義表達的效果較好,而醫療衛生相關的則效果通常。若是原始預料集更大,可能效果還會進一步提高的。同時,也能夠考慮使用word2vec模型訓練獲得word vector,在使用上述模型訓練CNN分類模型,同時更新word vector。

本文同時在知加發表,歡迎圍觀。

最後,進過本人使用的實驗代碼可從github下載(Theano),對做者的原始代碼作了比較詳盡的註釋,同時增長漢語的分詞預處理模塊和後面的word vector展示模塊

我的採用Tensorflow實現的版本:github (Tensorflow版本),歡迎一塊兒交流學習~~~

相關文章
相關標籤/搜索