从CNN视角看在自然语言处理上的应用
作者丨卞書青
學校丨中國人民大學在讀碩士
研究方向丨信息抽取、深度學習
本文經授權轉載自知乎專欄「RUC智能情報站」。
1. 前言
卷積神經網絡(Convolutional Neural Network)最早是應用在計算機視覺當中,而如今 CNN 也早已應用于自然語言處理(Natural Language Processing)的各種任務。
本文主要以 CMU CS 11-747 (Neural Networks for NLP)?[1] 課程中 Convolutional Networks for Text 這一章節的內容作為主線進行講解。本文主要包括了對如下幾塊內容的講解,第一部分是對于常見的語言模型在進行文本表示時遇到的問題以及引入卷積神經網絡的意義,第二部分是對于卷積神經網絡模塊的介紹,第三部分主要是介紹一些卷積神經網絡應用于自然語言處理中的論文,第四部分主要是對這一篇綜述進行總結。
2. 引例
我們首先來看這么一個問題,假設我們需要對句子做情感上的分類。
傳統的詞袋模型或者連續詞袋模型都可以通過構建一個全連接的神經網絡對句子進行情感標簽的分類。但是這樣存在一個問題,我們通過激活函數可以讓某些結點激活(例如一個句子里“not”,”hate”這樣的較強的特征詞),但在這樣網絡構建里,句子中詞語的順序被忽略,也許同樣兩個句子都出現了 not 和 hate,但是一個句子(I do not hate this movie)表示的是 good 的情感,另一個句子(I hate this movie and will not choose it)表示的是 bad 的情感。
其實很重要的一點是在剛才上述模型中我們無法捕獲像 not hate 這樣由連續兩個詞所構成的關鍵特征的詞的含義。
在語言模型里 n-gram 模型是可以用來解決,想法其實就是將連續的兩個詞作為一個整體納入到模型中,這樣確實能夠解決我們剛才提出的問題。加入 bi-gram,tri-gram 可以讓我們捕捉到例如“don’t love”,“not the best”。
但是問題又來了,如果我們使用多元模型,實際訓練時的參數是一個非常大的問題,因為假設你有 20000 個詞,加入 bi-gram 實際上你就要有 400000000 個詞,這樣參數訓練顯然是爆炸的。另外一點,相似的詞語在這樣的模型中不能共享例如參數權重等,這樣就會導致相似詞無法獲得交互信息。
3. 卷積神經網絡結構的認識
利用卷積神經網絡實際上是可以解決上述的兩個問題。在講卷積神經網絡前,我們先來看兩個簡單的例子。
假設我去識別出左邊這個方框里的貓,實際上在一張圖片中貓所處的位置并不重要,它在左邊,在右邊,還是在底部,其實對于貓來說,它的特征是不變的。我需要在這一部分位置學習的特征也能用在另一部分位置上,所以對于這個圖像上的所有位置,我們都能使用同樣的學習特征。
而在右邊的例子中,假設一句話中是談論貓咪的,貓咪這個詞的意義是否會隨它在第一句話還是第二句話而發生改變呢,大部分情況是不變的,所以我們當我們使用一個文本網絡時,網絡能夠學習到什么是貓咪并且可以重復使用,而不是每一次見到它就要重新學習。
接下來我們先來介紹卷積神經網絡中各個重要的環節。
3.1?卷積
所以這里我們首先去理解卷積神經網絡中卷積的運算。這里我們以圖像作為輸入。比較容易理解卷積的方法是把卷積想象成作用于矩陣的一個滑動窗口函數。如下面這張圖的表示。
滑動窗口又稱作卷積核、濾波器或是特征檢測器。圖中使用 3x3 的卷積核,將卷積核與矩陣對應的部分逐元素相乘,然后求和。對于卷積的運算可以看下面這幅圖的解釋。
在不改變卷積核權重的情況下,就像拿著一只刷子一樣對整個圖水平垂直滑動進行卷積運算,這樣輸出就是經過卷積運算后的輸出層。這里有一個對卷積操作的動畫演示 [2],可以加深對其的理解。
3.2 什么是卷積神經網絡
卷積神經網絡其實就是多層卷積運算,然后對每層的卷積輸出用非線性激活函數做轉換(后面會講到)。卷積過程中每塊局部的輸入區域與輸出的一個神經元相連接。對每一層應用不同的卷積核,每一種卷積核其實可以理解為對圖片的一種特征進行提取,然后將多種特征進行匯總。
以下面這幅圖為例,原始的 input 為一幅圖片,第一層卷積過后輸出層變為 6@28*28,所以這里的卷積核實際上用了 6 個,6 個卷積核代表了對這一張原始圖片的六種不同角度的特征提取(例如提取圖片左上方的邊緣線條,右下方的邊緣線條等等)。
feature map 實際上的含義就是特征通道(或者理解為一個圖片的不同特征),也可以說就是輸出層的深度,這里就是 6,然后后面每一次做卷積操作是都是要對所有的特征通道進行卷積操作以便提取出更高級的特征。這里也涉及到池化層,在下一小節進行講解。在訓練階段,卷積神經網絡會基于你想完成的任務自動學習卷積核的權重值。
例如,在上面這幅圖中,第一層 CNN 模型也許學會從原始像素點中檢測到一些邊緣線條,然后根據邊緣線條在第二層檢測出一些簡單的形狀(例如橫線條,左彎曲線條,豎線條等),然后基于這些形狀檢測出更高級的特征,比如一個A字母的上半部分等。最后一層則是利用這些組合的高級特征進行分類。?
卷積神經網絡中的卷積計算實際上體現了:位置不變性和組合性。位置不變性是因為卷積核是在全圖范圍內平移,所以并不用關心貓究竟在圖片的什么位置。組合性是指每個卷積核對一小塊局部區域的低級特征組合形成更高級的特征表示。當然這兩點對于句子的建模也是很多的幫助,我們會在后面的例子中提到。?
3.3 卷積是如何應用到自然語言處理中?
在圖像中卷積核通常是對圖像的一小塊區域進行計算,而在文本中,一句話所構成的詞向量作為輸入。每一行代表一個詞的詞向量,所以在處理文本時,卷積核通常覆蓋上下幾行的詞,所以此時卷積核的寬度與輸入的寬度相同,通過這樣的方式,我們就能夠捕捉到多個連續詞之間的特征,并且能夠在同一類特征計算時中共享權重。下面這張圖很好地詮釋了剛才的講解。
3.4 池化層?
卷積神經網絡的一個重要概念就是池化層,一般是在卷積層之后。池化層對輸入做降采樣。池化的過程實際上是對卷積層分區域求最大值或者對每個卷積層求最大值。例如,下圖就是 2x2 窗口的最大值池化(在自然語言處理中,我們通常對整個輸出做池化,每個卷積層只有一個輸出值)。
為什么要進行池化操作?
池化首先是可以輸出一個固定大小的矩陣,這對于自然語言處理當中輸入句子的長度不一有非常大的作用。例如,如果你用了 200 個卷積核,并對每個輸出使用最大池化,那么無論卷積核的尺寸是多大,也無論輸入數據的維度或者單詞個數如何變化,你都將得到一個 200 維的輸出。這讓你可以應對不同長度的句子和不同大小的卷積核,但總是得到一個相同維度的輸出結果,用作最后的分類。
另外池化層在降低數據維度的同時還能夠保留顯著的特征。每一種卷積核都是用來檢測一種特定的特征。在以句子分類中,每一種卷積核可以用來檢測某一種含義的詞組,如果這種類型的含義的詞語出現了,該卷積核的輸出值就會非常大,通過池化過程就能夠盡可能地將該信息保留下來。
關于池化層幾種池化方式會在下面的內容里講解。
3.5 激活函數?
有關激活函數很多細節的講述在最后的總結會提到。
4. 卷積神經網絡結構在自然語言處理的應用
首先我們來介紹第一篇論文?Natural Language Processing (almost) from Scratch,該論文主要是針對原來那種 man-made 的輸入特征和人工特征,利用神經網絡的方法自動抽取出文本句子更高級的特征用來處理自然語言處理里的各項任務。
例如本文中輸入是一個句子序列,輸出是對句子中各個詞的詞性的預測。該文提出了兩種方法,一種是滑動窗口的方法(window approach),另一種就是將整個句子作為輸入(sentence approach)的方法,兩種方法就分別對應著局部和全局的特征。模型結構如下圖所示:
window approach
sentence approach
window approach 是根據某一個單詞以及其附近固定長度范圍內的單詞對應的詞向量來為單詞預測標簽。需要注意的是,當處理到一個句子的開始或者結尾的單詞的時候,其前后窗口或許不包含單詞,這時候我們需要填充技術,為前面或者后面填充象征開始或者結束的符號。?
實際上基于窗口的方法已經可以解決很多常見的任務,但是如果一個單詞如果非常依賴上下文的單詞,且當時這個單詞并不在窗口中,這時就需要 sentence approach,這里所使用的卷積操作與卷積神經網絡中的卷積操作基本相同。這里需要對句子中的每一個單詞進行一次卷積操作,這里池化過程選擇最大池化,這里認為句子中大部分的詞語對該單詞的意義不會有影響。?
剛才這篇論文實際上是在池化層中直接選擇了最大池化,接下來的這篇論文?A Convolutional Neural Network for Modelling Sentences?對句子級別特征的池化過程進行了改進并且提出了 DCNN 動態卷積網絡(Dynamic Convolutional Neural Network),在介紹該論文前首先先來介紹一下常見的幾種池化方式。
Max-pooling 最為常見,最大池化是取整個區域的最大值作為特征,在自然語言處理中常用于分類問題,希望觀察到的特征是強特征,以便可以區分出是哪一個類別。Average-pooling 通常是用于主題模型,常常是一個句子不止一個主題標簽,如果是使用 Max-pooling 的話信息過少,所以使用 Average 的話可以廣泛反映這個區域的特征。
最后兩個 K-max pooling 是選取一個區域的前 k 個大的特征。Dynamic pooling 是根據網絡結構動態調整取特征的個數。最后兩個的組合選取,就是該篇論文的亮點。?
該論文的亮點首先對句子語義建模,在底層通過組合鄰近的詞語信息,逐步向上傳遞,上層則又組合新的語義信息,從而使得句子中相離較遠的詞語也有交互行為(或者某種語義聯系)。從直觀上來看,這個模型能夠通過詞語的組合,再通過池化層提取出句子中重要的語義信息。
另一個亮點就是在池化過程中,該模型采用動態 k-Max 池化,這里池化的結果不是返回一個最大值,而是返回k組最大值,這些最大值是原輸入的一個子序列。池化中的參數k可以是一個動態函數,具體的值依賴于輸入或者網絡的其他參數。該模型的網絡結構如下圖所示:
這里重點介 紹k-max 池化和動態 k-max 池化。K-max 的好處在于,既提取除了句子中不止一個重要信息,同時保留了它們的順序。同時,這里取 k 的個數是動態變化的,具體的動態函數如下。
這里需要注意的是 s 代表的是句子長度, L 代表總的卷積層的個數, l 代表的是當前是在幾個卷積層,所以可以看出這里的 k 是隨著句子的長度和網絡深度而改變,我們的直觀的感受也能看出初始的句子層提取較多的特征,而到后面提取的特征將會逐漸變少,同時由于 k_top 代表最頂層的卷積層需要提取的個數。?
這里的網絡結構大多與通常的卷積網絡層,但需要注意的是這里有一個 Folding 層(折疊操作層)。這里考慮相鄰的兩行之間的某種聯系,將兩行的詞向量相加。?
該模型亮點很多,總結如下,首先它保留了句子中詞序和詞語之間的相對位置,同時考慮了句子中相隔較遠的詞語之間的語義信息,通過動態 k-max pooling 較好地保留句子中多個重要信息且根據句子長度動態變化特征抽取的個數。?
剛才這篇論文是對池化過程進行改進,接下來的兩篇論文是對卷積層進行了改進。第三篇論文是?Neural Machine Translation in Linear Time,該論文提出了擴張卷積神經網絡(Dilated Convolution)應用于機器翻譯領域。Dilated convolution 實際上要解決的問題是池化層的池化會損失很多信息(無論該信息是有用還是無用)。
Dilated convolution 的主要貢獻就是,如何在去掉池化操作的同時,而不降低網絡的感受野。下圖理解起來更加容易,卷積的輸入像素的間距由 1-2-4-8,雖然沒有池化層,但是隨著層數越深覆蓋的原始輸入信息依舊在增加。也就是我們通常卷積核與輸入的一個區域的維度大小保持一致,但是去掉池化層后,我們隨著深度增加,卷積核的所能覆蓋的輸入區域擴展一倍。
在該模型中,句子建模時輸入是以句子的字符級別開始的,之后隨著卷積核所能覆蓋的范圍擴展,不斷地去交互信息,同時還能夠保證原始的輸入信息不被丟失。
之前的論文中主要是對卷積層和池化層從本身結構上進行改造,下面的這篇論文主要考慮到了本身句子已有依存句法樹信息,將其融入到句子的建模中來。
論文?Dependency-based Convolutional Neural Networks for Sentence Embedding?便是提出這一想法,模型的想法是,不僅僅是利用句子中相鄰的詞信息作為特征信息,一個依存句法樹的實際上將句子的語義信息關系真正地提取出來,由于整個卷積的過程,句子的語序關系仍然會丟失,通過將依存句法樹中父子節點的語序信息和兄弟語序信息一起作為輸入,可以更加有效地抽取句子的特征。
最后要介紹的一篇論文是有關于句子匹配(Sentence Matching)的問題,基礎問題仍然是句子建模。首先,文中提出了一種基于 CNN 的句子建模網絡,卷積的作用是從句子中提取出局部的語義組合信息,而多個 Feature Map 則是從多種角度進行提取,也就是保證提取的語義組合的多樣性。分別單獨地對兩個句子進行建模(使用上文中的句子模型),從而得到兩個相同且固定長度的向量,然后,將這兩個向量作為一個多層感知機(MLP)的輸入,最后計算匹配的分數。
這個模型比較簡單,但是有一個較大的缺點,兩個句子在建模過程中是完全獨立的,沒有任何交互行為,一直到最后生成抽象的向量表示后才有交互行為,這樣做使得句子在抽象建模的過程中會喪失很多語義細節,因此,推出了第二種模型結構。
這種結構提前了兩個句子間的交互行為,第一層中,首先取一個固定的卷積窗口 K1 ,然后遍歷 Sx 和 Sy 中所有組合的二維矩陣進行卷積,每一個二維矩陣輸出一個值,構成 Layer-2,然后進行 2×2 的 Max-pooling,后續的卷積層均是傳統的二維卷積操作。
5. 總結/Q&A
本篇綜述中具體介紹了卷積神經網絡的結構以及應用于自然語言處理中的場景,最后再做一個簡單的歸納總結。
還有一些有關卷積神經網絡細節上的問題與答案,與大家分享。?
Q: 卷積層和池化層有什么區別??
A: 首先可以從結構上可以看出,卷積之后輸出層的維度減小,深度變深。但池化層深度不變。同時池化可以把很多數據用最大值或者平均值代替。目的是降低數據量。降低訓練的參數。對于輸入層,當其中像素在鄰域發生微小位移時,池化層的輸出是不變的,從而能提升魯棒性。而卷積則是把數據通過一個卷積核變化成特征,便于后面的分離。?
Q: 采用寬卷積的好處有什么??
A:?通過將輸入邊角的值納入到滑窗中心進行計算,以便損失更少的信息。?
Q: 卷積輸出的深度與哪個部件的個數相同??
A:?輸出深度(通道)與卷積核(過濾器)的個數相等。?
Q:?激活函數通常放在卷積神經網絡的那個操作之后??
A:?通常放在卷積層之后。?
Q:?為什么激活函數通常都是采用非線性的函數??
A:?如果網絡中都采用線性函數的組合,那么線性的組合還是線性,那么使用多次線性組合就等同于使用了一次線性函數。因此采用非線性函數可以來逼近任意函數。?
Q:?非線性激活函數中 sigmod 函數存在哪些不足??
A:?Sigmod 函數存在飽和狀態,尤其是值過大時,當進入飽和狀態時,進行梯度下降計算時,很容易出現梯度消失的情況,求導的精確值不能保證。?
Q:?ReLU 和 SoftPlus 激活函數有哪些優勢??
A:?與 sigmod 相比,不存在指數計算,求導計算量變小,同時緩解了過擬合的情況,一部分輸出為 0,減少了參數的相互依存。
6. 參考資料
[1]?CMU CS 11-747 (Neural Networks for NLP)?
http://phontron.com/class/nn4nlp2017/schedule.html#
[2] 卷積操作動畫演示
http://cs231n.github.io/convolutional-networks/
[3]?寬/窄卷積動畫演示
http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html
[4]?Udacity Deep Learning 課程
https://cn.udacity.com/course/deep-learning--ud730
[5]?深度學習入門教程/代碼
https://github.com/CreatCodeBuild/TensorFlow-and-DeepLearning-Tutorial
7. 參考文獻
??Neural Machine Translation in Linear Time閱讀筆記
https://zhuanlan.zhihu.com/p/23795111
??卷積神經網絡(CNN)在句子建模上的應用
http://www.jeyzhang.com/cnn-apply-on-modelling-sentence.html
??卷積神經網絡在自然語言處理的應用
http://www.csdn.net/article/2015-11-11/2826192
關于PaperWeekly
PaperWeekly 是一個推薦、解讀、討論、報道人工智能前沿論文成果的學術平臺。如果你研究或從事 AI 領域,歡迎在公眾號后臺點擊「交流群」,小助手將把你帶入 PaperWeekly 的交流群里。
▽ 點擊 |?閱讀原文?| 訪問作者知乎專欄
總結
以上是生活随笔為你收集整理的从CNN视角看在自然语言处理上的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 论文共读 | “阳奉阴违”的半监督学习算
- 下一篇: 报名 | “阳奉阴违”的半监督学习算法