文本分類(下)-卷積神經網絡(CNN)在文本分類上的應用

1 簡介

原先寫過兩篇文章,分別介紹了傳統機器學習方法在文本分類上的應用以及CNN原理,而後本篇文章結合兩篇論文展開,主要講述下CNN在文本分類上的應用。前面兩部份內容主要是來自兩位博主的文章(文章中已經給出原文連接),是對兩篇論文的解讀以及總結,基本上闡釋了CNN文本分類模型;後半部分講一個實例和項目實戰html

2 論文1《Convolutional Neural Networks for Sentence Classification

模型結構

在短文本分析任務中,因爲句子句長長度有限、結構緊湊、可以獨立表達意思,使得CNN在處理這一類問題上成爲可能,主要思想是將ngram模型與卷積操做結合起來git

2.1 輸入層

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

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

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

2.2 第一層卷積層:

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

2.3 池化層:

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

2.4 全鏈接+softmax層:

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

2.5 訓練方案

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

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

項目代碼:CNN_sentence 以上部份內容來自:https://www.cnblogs.com/cl1024cl/p/6205012.html

3 論文2《A Sensitivity Analysis of (and Practitioners' Guide to) Convolutional Neural Networks for Sentence Classification

這篇論文主要工做是對「Convolutional Naural Networks for Sentence Classification」這篇論文的模型進行了各類各樣的對比試驗,並給出了調參的建議,進而獲得了一些關於超參數的設置經驗。

3.1 調參實驗結論:

  • 因爲模型訓練過程當中的隨機性因素,如隨機初始化的權重參數,mini-batch,隨機梯度降低優化算法等,形成模型在數據集上的結果有必定的浮動,如準確率(accuracy)能達到1.5%的浮動,而AUC則有3.4%的浮動;
  • 詞向量是使用word2vec仍是GloVe,對實驗結果有必定的影響,具體哪一個更好依賴於任務自己;
  • Filter的大小對模型性能有較大的影響,而且Filter的參數應該是能夠更新的;
  • Feature Map的數量也有必定影響,可是須要兼顧模型的訓練效率;
  • 1-max pooling的方式已經足夠好了,相比於其餘的pooling方式而言;
  • 正則化的做用微乎其微。

3.2 建議:

  • 使用non-static版本的word2vec或者GloVe要比單純的one-hot representation取得的效果好得多;
  • 爲了找到最優的過濾器(Filter)大小,可使用線性搜索的方法。一般過濾器的大小範圍在1-10之間,固然對- 於長句,使用更大的過濾器也是有必要的;
  • Feature Map的數量在100-600之間;
  • 能夠儘可能多嘗試激活函數,實驗發現ReLU和tanh兩種激活函數表現較佳;
  • 使用簡單的1-max pooling就已經足夠了,能夠不必設置太複雜的pooling方式;
  • 當發現增長Feature Map的數量使得模型的性能降低時,能夠考慮增大正則的力度,如調高dropout的機率;
  • 爲了檢驗模型的性能水平,屢次反覆的交叉驗證是必要的,這能夠確保模型的高性能並非偶然。

4 一個CNN作文本分類的簡單例子

I like this movie very much!
咱們以上圖爲例,圖上用紅色標籤標註了5部分,結合這5個標籤,具體解釋下整個過程的操做,來看看CNN如何解決文本分類問題的。

4.1 #sentence

上圖句子爲「[I like this movie very much!」 ,一共有兩個單詞加上一個感嘆號,關於這個標點符號,不一樣學者有不一樣的操做,好比去除標點符號。在這裏咱們先不去除,那麼整個句子有7個詞,詞向量維度爲5,那麼整個句子矩陣大小爲7x5

4.2 #filters

filters的區域大小可使不一樣的,在這裏取(2,3,4)3種大小,每種大小的filter有兩個不一樣的值的filter,因此一共是有6個filter。

4.3 #featuremaps

咱們在句子矩陣和過濾器矩陣填入一些值,那麼咱們能夠更好理解卷積計算過程,這和CNN原理那篇文章同樣,

好比咱們取大小爲2的filter,最開始與句子矩陣的前兩行作乘積相加,獲得 0.6 x 0.2 + 0.5 x 0.1 + … + 0.1 x 0.1 = 0.51,而後將filter向下移動1個位置獲得0.53.最終生成的feature map大小爲(7-2+1x1)=6。 爲了得到feature map,咱們添加一個bias項和一個激活函數,好比Relu

4.4 #1max

由於不一樣大小的filter獲取到的feature map大小也不同,爲了解決這個問題,而後添加一層max-pooling,選取一個最大值,相同大小的組合在一塊兒 ###4.5 #concat1max 通過max-pooling操做以後,咱們將固定長度的向量給sofamax,來預測文本的類別。

5 文本分類實戰

下面是利用Keras實現的CNN文本分類部分代碼:

# 建立tensor
print("正在建立模型...")
inputs=Input(shape=(sequence_length,),dtype='int32')
embedding=Embedding(input_dim=vocabulary_size,output_dim=embedding_dim,input_length=sequence_length)(inputs)
reshape=Reshape((sequence_length,embedding_dim,1))(embedding)

# cnn
conv_0=Conv2D(num_filters,kernel_size=(filter_sizes[0],embedding_dim),padding='valid',kernel_initializer='normal',activation='relu')(reshape)
conv_1=Conv2D(num_filters,kernel_size=(filter_sizes[1],embedding_dim),padding='valid',kernel_initializer='normal',activation='relu')(reshape)
conv_2=Conv2D(num_filters,kernel_size=(filter_sizes[2],embedding_dim),padding='valid',kernel_initializer='normal',activation='relu')(reshape)

maxpool_0=MaxPool2D(pool_size=(sequence_length-filter_sizes[0]+1,1),strides=(1,1),padding='valid')(conv_0)
maxpool_1=MaxPool2D(pool_size=(sequence_length-filter_sizes[1]+1,1),strides=(1,1),padding='valid')(conv_1)
maxpool_2=MaxPool2D(pool_size=(sequence_length-filter_sizes[2]+1,1),strides=(1,1),padding='valid')(conv_2)


concatenated_tensor = Concatenate(axis=1)([maxpool_0, maxpool_1, maxpool_2])
flatten = Flatten()(concatenated_tensor)
dropout = Dropout(drop)(flatten)
output = Dense(units=2, activation='softmax')(dropout)
model=Model(inputs=inputs,outputs=output)
複製代碼

運行結果

英文:

準訓練結果:驗證集76%左右

中文:

準訓練結果:驗證集91%左右 項目地址:https://github.com/yanqiangmiffy/Text-Classification-Application

6 相關資料

相關文章
相關標籤/搜索