當咱們聽到卷積神經網絡(Convolutional Neural Network, CNNs)時,每每會聯想到計算機視覺。CNNs在圖像分類領域作出了巨大貢獻,也是當今絕大多數計算機視覺系統的核心技術,從Facebook的圖像自動標籤到自動駕駛汽車都在使用。php
最近咱們開始在天然語言處理(Natural Language Processing)領域應用CNNs,並取得了一些引人注目的成果。我將在本文中概括什麼是CNNs,怎樣將它們應用於NLP。CNNs背後的直覺知識在計算機視覺的用例裏更容易被理解,所以我就先從那裏開始,而後慢慢過渡到天然語言處理。css
對我來講,最容易的理解方式就是把卷積想象成做用於矩陣的一個滑動窗口函數。這麼說有些拗口,可是用動畫顯示就很直觀了。html
3x3的濾波器作卷積運算。圖片來源: http://deeplearning.stanford.edu/wiki/index.php/Feature_extraction_using_convolutiongit
把左側的矩陣想象成一幅黑白圖像。每個元素對應一個像素點,0表示黑點,1表示白點(灰度圖的像素值通常是0~255)。移動窗口又稱做核、濾波器或是特徵檢測器。這裏咱們使用3x3的濾波器,將濾波器與矩陣對應的部分逐元素相乘,而後求和。咱們平移窗口,使其掃過矩陣的全部像素,對整幅圖像作卷積運算。github
你也許有些疑惑,剛纔的操做究竟會有什麼效果呢。咱們就來看幾個直觀的例子。web
用鄰近點像素值的均值替換其原值,實現圖像模糊的效果:算法
用鄰近點像素值與自身的差值替換其原值,實現邊緣檢測的效果:微信
(爲了直觀地來理解,想一想圖像中平滑的那些部分,那些像素點與周圍像素的顏色幾乎一致:求和的結果趨近於0,至關於黑色。若是有一條明顯的邊緣線,好比黑白分界線,那麼像素值的差值將會很大,至關於白色)網絡
GIMP手冊裏還有一些其它的例子。想要深刻了解卷積運算的原理,我推薦閱讀Chris Olah寫的專題博客。框架
如今你明白了什麼是卷積運算了吧。那CNNs又是什麼呢?CNNs本質上就是多層卷積運算,外加對每層的輸出用非線性激活函數作轉換,好比用ReLU和tanh。在傳統的前饋神經網絡中,咱們把每一個輸入神經元與下一層的輸出神經元相鏈接。這種方式也被稱做是全鏈接層,或者仿射層。在CNNs中咱們不這樣作,而是用輸入層的卷積結果來計算輸出。這至關因而局部鏈接,每塊局部的輸入區域與輸出的一個神經元相鏈接。對每一層應用不一樣的濾波器,每每是如上圖所示成百上千個,而後彙總它們的結果。這裏也涉及到池化層(降採樣),我會在後文作解釋。在訓練階段,CNN基於你想完成的任務自動學習濾波器的權重值。舉個例子,在圖像分類問題中,第一層CNN模型或許能學會從原始像素點檢測到一些邊緣線條,而後根據邊緣線條在第二層檢測出一些簡單的形狀,而後基於這些形狀檢測出更高級的特徵,好比臉部輪廓等。最後一層是利用這些高級特徵的一個分類器。
這種計算方式有兩點值得咱們注意:位置不變性和組合性。好比說你想對圖片中是否包含大象作分類。由於濾波器是在全圖範圍內平移,因此並不用關心大象究竟在圖片的什麼位置。事實上,池化也有助於平移、旋轉和縮放的不變性,它對克服縮放因素的效果尤爲好。第二個關鍵因素是(局部)組合性。每一個濾波器對一小塊局部區域的低級特徵組合造成更高級的特徵表示。這也是CNNs對計算機視覺做用巨大的緣由。咱們能夠很直觀地理解,線條由像素點構成,基本形狀又由線條構成,更復雜的物體又源自基本的形狀。
NLP任務的輸入再也不是像素點了,大多數狀況下是以矩陣表示的句子或者文檔。矩陣的每一行對應於一個分詞元素,通常是一個單詞,也能夠是一個字符。也就是說每一行是表示一個單詞的向量。一般,這些向量都是word embeddings(一種底維度表示)的形式,如word2vec和GloVe,可是也能夠用one-hot向量的形式,也即根據詞在詞表中的索引。如果用100維的詞向量表示一句10個單詞的句子,咱們將獲得一個10x100維的矩陣做爲輸入。這個矩陣至關因而一幅「圖像」。
在計算機視覺的例子裏,咱們的濾波器每次只對圖像的一小塊區域運算,但在處理天然語言時濾波器一般覆蓋上下幾行(幾個詞)。所以,濾波器的寬度也就和輸入矩陣的寬度相等了。儘管高度,或者區域大小能夠隨意調整,但通常滑動窗口的覆蓋範圍是2~5行。綜上所述,處理天然語言的卷積神經網絡結構是這樣的(花幾分鐘時間理解這張圖片,以及維度是如何變化的。你能夠先暫時忽略池化操做,咱們在稍後會解釋它):
用於句子分類器的卷積神經網絡(CNN)結構示意圖。這裏咱們對濾波器設置了三種尺寸:二、3和4行,每種尺寸各有兩種濾波器。每一個濾波器對句子矩陣作卷積運算,獲得(不一樣程度的)特徵字典。而後對每一個特徵字典作最大值池化,也就是隻記錄每一個特徵字典的最大值。這樣,就由六個字典生成了一串單變量特徵向量(univariate feature vector),而後這六個特徵拼接造成一個特徵向量,傳給網絡的倒數第二層。最後的softmax層以這個特徵向量做爲輸入,用其來對句子作分類;咱們假設這裏是二分類問題,所以獲得兩個可能的輸出狀態。來源:Zhang, Y., & Wallace, B. (2015). A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification.
計算機視覺完美的直觀感覺這裏還存在嗎?位置不變性和局部組合性對圖像來講很直觀,但對NLP卻並不是如此。你也許會很在乎一個詞在句子中出現的位置。相鄰的像素點頗有多是相關聯的(都是物體的同一部分),但單詞並不老是如此。在不少種語言裏,短語之間會被許多其它詞所隔離。一樣,組合性也不見得明顯。單詞顯然是以某些方式組合的,好比形容詞修飾名詞,但如果想理解更高級特徵真正要表達的含義是什麼,並不像計算機視覺那麼明顯了。
由此看來,卷積神經網絡彷佛並不適合用來處理NLP任務。遞歸神經網絡(Recurrent Neural Network)更直觀一些。它們模仿咱們人類處理語言的方式(至少是咱們本身所認爲的方式):從左到右的順序閱讀。慶幸的是,這並不意味着CNNs沒有效果。全部的模型都是錯的,只是一些能被利用。實際上CNNs對NLP問題的效果很是理想。正如詞袋模型(Bag of Words model),它明顯是基於錯誤假設的過於簡化模型,但這不影響它多年來一直被做爲NLP的標準方法,而且取得了不錯的效果。
CNNs的主要特色在於速度快。很是的快。卷積運算是計算機圖像的核心部分,在GPU級別的硬件層實現。相比於n-grams,CNNs表徵方式的效率也更勝一籌。因爲詞典龐大,任何超過3-grams的計算開銷就會很是的大。即便Google也最多不超過5-grams。卷積濾波器能自動學習好的表示方式,不須要用整個詞表來表徵。那麼用尺寸大於5行的濾波器徹底合情合理了。我我的認爲許多在第一層學到的濾波器撲捉到的特徵與n-grams很是類似(但不侷限),可是以更緊湊的方式表徵。
在解釋如何將CNNs用於NLP任務以前,先來看一下構建CNN網絡時須要面臨的幾個選擇。但願這能幫助你更好地理解相關文獻。
在上文中解釋卷積運算的時候,我忽略瞭如何使用濾波器的一個小細節。在矩陣的中部使用3x3的濾波器沒有問題,在矩陣的邊緣該怎麼辦呢?左上角的元素沒有頂部和左側相鄰的元素,該如何濾波呢?解決的辦法是採用補零法(zero-padding)。全部落在矩陣範圍以外的元素值都默認爲0。這樣就能夠對輸入矩陣的每個元素作濾波了,輸出一個一樣大小或是更大的矩陣。補零法又被稱爲是寬卷積,不使用補零的方法則被稱爲窄卷積。1D的例子如圖所示:
窄卷積 vs 寬卷積。濾波器長度爲5,輸入長度爲7。來源:A Convolutional Neural Network for Modelling Sentences (2014)
當濾波器長度相對輸入向量的長度較大時,你會發現寬卷積頗有用,或者說頗有必要。在上圖中,窄卷積輸出的長度是 (7-5)+1=3,寬卷積輸出的長度是(7+2*4-5)+1=11。通常形式爲
卷積運算的另外一個超參數是步長,即每一次濾波器平移的距離。上面全部例子中的步長都是1,相鄰兩個濾波器有重疊。步長越大,則用到的濾波器越少,輸出的值也越少。下圖來自斯坦福的cs231課程網頁,分別是步長爲1和2的狀況:
卷積步長。左側:步長爲1,右側:步長爲2。來源: http://cs231n.github.io/convolutional-networks/
在文獻中咱們經常見到的步長是1,但選擇更大的步長會讓模型更接近於遞歸神經網絡,其結構就像是一棵樹。
卷積神經網絡的一個重要概念就是池化層,通常是在卷積層以後。池化層對輸入作降採樣。經常使用的池化作法是對每一個濾波器的輸出求最大值。咱們並不須要對整個矩陣都作池化,能夠只對某個窗口區間作池化。例如,下圖所示的是2x2窗口的最大值池化(在NLP裏,咱們一般對整個輸出作池化,每一個濾波器只有一個輸出值):
CNN的最大池化。來源: http://cs231n.github.io/convolutional-networks/#pool
池化的特色之一就是它輸出一個固定大小的矩陣,這對分類問題頗有必要。例如,若是你用了1000個濾波器,並對每一個輸出使用最大池化,那麼不管濾波器的尺寸是多大,也不管輸入數據的維度如何變化,你都將獲得一個1000維的輸出。這讓你能夠應用不一樣長度的句子和不一樣大小的濾波器,但老是獲得一個相同維度的輸出結果,傳入下一層的分類器。
池化還能下降輸出結果的維度,(理想狀況下)卻能保留顯著的特徵。你能夠認爲每一個濾波器都是檢測一種特定的特徵,例如,檢測句子是否包含諸如「not amazing」等否認意思。若是這個短語在句子中的某個位置出現,那麼對應位置的濾波器的輸出值將會很是大,而在其它位置的輸出值很是小。經過採用取最大值的方式,能將某個特徵是否出如今句子中的信息保留下來,可是沒法肯定它究竟在句子的哪一個位置出現。這個信息出現的位置真的很重要嗎?確實是的,它有點相似於一組n-grams模型的行爲。儘管丟失了關於位置的全局信息(在句子中的大體位置),可是濾波器捕捉到的局部信息卻被保留下來了,好比「not amazing」和「amazing not」的意思就截然不同。
在圖像識別領域,池化還能提供平移和旋轉不變性。若對某個區域作了池化,即便圖像平移/旋轉幾個像素,獲得的輸出值也基本同樣,由於每次最大值運算獲得的結果老是同樣的。
咱們須要瞭解的最後一個概念是通道。通道便是輸入數據的不一樣「視角」。好比說,作圖像識別時通常會用到RGB通道(紅綠藍)。你能夠對每一個通道作卷積運算,賦予相同或不一樣的權值。你也一樣能夠把NLP想象成有許多個通道:把不一樣類的詞向量表徵(例如word2vec和GloVe)看作是獨立的通道,或是把不一樣語言版本的同一句話看做是一個通道。
咱們接下來看看卷積神經網絡模型在天然語言處理領域的實際應用。我試圖去歸納一些研究成果。但願至少可以涵蓋大部分主流的成果,不免也會遺漏其它一些有意思的應用(請在評論區提醒我)。
最適合CNNs的莫過於分類任務,如語義分析、垃圾郵件檢測和話題分類。卷積運算和池化會丟失局部區域某些單詞的順序信息,所以純CNN的結構框架不太適用於PoS Tagging和Entity Extraction等順序標籤任務(也不是不可能,你能夠嘗試輸入位置相關的特徵)。
文獻[1>在不一樣的分類數據集上評估CNN模型,主要是基於語義分析和話題分類任務。CNN模型在各個數據集上的表現很是出色,甚至有個別刷新了目前最好的結果。使人驚訝的是,這篇文章採用的網絡結構很是簡單,但效果至關棒。輸入層是一個表示句子的矩陣,每一行是word2vec詞向量。接着是由若干個濾波器組成的卷積層,而後是最大池化層,最後是softmax分類器。該論文也嘗試了兩種不一樣形式的通道,分別是靜態和動態詞向量,其中一個通道在訓練時動態調整而另外一個不變。文獻[2]中提到了一個相似的結構,但更復雜一些。文獻[6]在網絡中又額外添加了一個層,用於語義聚類。
Kim, Y. (2014). 卷積神經網絡用來語句分類
文獻[4]從原始數據訓練CNN模型,不須要預訓練獲得word2vec或GloVe等詞向量表徵。它直接對one-hot向量進行卷積運算。做者對輸入數據採用了節省空間的相似詞袋錶徵方式,以減小網絡須要學習的參數個數。在文獻[5]中做者用了CNN學習獲得的非監督式「region embedding」來擴展模型,預測文字區域的上下文內容。這些論文中提到的方法對處理長文本(好比影評)很是有效,但對短文本(好比推特)的效果還不清楚。憑個人直覺,對短文本使用預訓練的詞向量應該能比長文本取得更好的效果。
搭建一個CNN模型結構須要選擇許多個超參數,我在上文中已經提到了一些:輸入表徵(word2vec, GloVe, one-hot),卷積濾波器的數量和尺寸,池化策略(最大值、平均值),以及激活函數(ReLU, tanh)。文獻[7]經過屢次重複實驗,比較了不一樣超參數對CNN模型結構在性能和穩定性方面的影響。若是你想本身實現一個CNN用於文本分類,能夠借鑑該論文的結果。其主要的結論有最大池化效果老是好於平均池化;選擇理想的濾波器尺寸很重要,但也根據任務而定需;正則化在NLP任務中的做用並不明顯。須要注意的一點是該研究所用文本集裏的文本長度都相近,所以如果要處理不一樣長度的文本,上述結論可能不具備指導意義。
文獻[8]探索了CNNs在關係挖掘和關係分類任務中的應用。除了詞向量表徵以外,做者還把詞與詞的相對位置做爲卷積層的輸入值。這個模型假設了全部文本元素的位置已知,每一個輸入樣本只包含一種關係。文獻[9]和文獻[10]使用的模型相似。
來自微軟研究院的文獻[11]和 [12]介紹了CNNs在NLP的另外一種有趣的應用方式。這兩篇論文介紹瞭如何學習將句子表示成包含語義的結構,它能被用來作信息檢索。論文中給出的例子是基於用戶當前的閱讀內容,爲其推薦其它感興趣的文檔。句子的表徵是基於搜索引擎的日誌數據訓練獲得的。
大多數CNN模型以這樣或是那樣的訓練方式來學習單詞和句子的詞向量表徵,它是訓練過程的一部分。並非全部論文都關注這一步訓練過程,也並不在意學到的表徵意義有多大。文獻[13]介紹了用CNN模型對Facebook的日誌打標籤。這些學到的詞向量隨後又被成功應用於另外一個任務 —— 基於點擊日誌給用戶推薦感興趣的文章。
至此,全部的模型表徵都是在單詞的層面上。另外有一些團隊則研究如何將CNNs模型直接用於字符。文獻[14]學到了字符層面的向量表徵,將它們與預訓練的詞向量結合,用來給語音打標籤。文獻[15]和[16]研究了直接用CNNs模型直接從字符學習,而沒必要預訓練詞向量了。值得注意的是,做者使用了一個相對較深的網絡結構,共有9層,用來完成語義分析和文本分類任務。結果顯示,用字符級輸入直接在大規模數據集(百萬級)上學習的效果很是好,但用簡單模型在小數據集(十萬級)上的學習效果通常。文獻[17]是關於字符級卷積運算在語言建模方面的應用,將字符級CNN模型的輸出做爲LSTM模型每一步的輸入。同一個模型用於不一樣的語言。
使人驚訝的是,上面全部論文幾乎都是發表於近兩年。顯然CNNs模型在NLP領域已經有了出色的表現,新成果和頂級系統還在層出不窮地出現。
如有疑問或是反饋,請在評論區留言。謝謝閱讀!
[1] Kim, Y. (2014). Convolutional Neural Networks for Sentence Classification. Proceedings
of the 2014 Conference on Empirical Methods in Natural Language Processing (EMNLP 2014), 1746–1751.
[2] Kalchbrenner, N., Grefenstette, E., & Blunsom, P. (2014). A Convolutional Neural
Network for Modelling Sentences. Acl, 655–665.
[3] Santos, C. N. dos, & Gatti, M. (2014). Deep Convolutional Neural Networks
for Sentiment Analysis of Short Texts. In COLING-2014 (pp. 69–78).
[4] Johnson, R., & Zhang, T. (2015). Effective Use of Word Order for Text
Categorization with Convolutional Neural Networks. To Appear: NAACL-2015, (2011).
[5] Johnson, R., & Zhang, T. (2015). Semi-supervised Convolutional Neural Networks for Text Categorization via Region Embedding.
[6] Wang, P., Xu, J., Xu, B., Liu, C., Zhang, H., Wang, F., & Hao, H. (2015). Semantic
Clustering and Convolutional Neural Network for Short Text Categorization. Proceedings ACL 2015, 352–357.
[7] Zhang, Y., & Wallace, B. (2015). A Sensitivity Analysis of (and Practitioners’ Guide to)
Convolutional Neural Networks for Sentence Classification,
[8]Nguyen, T. H., & Grishman, R. (2015). Relation Extraction: Perspective from Convolutional
Neural Networks. Workshop on Vector Modeling for NLP, 39–48.
[9] Sun, Y., Lin, L., Tang, D., Yang, N., Ji, Z., & Wang, X. (2015). Modeling Mention , Context
and Entity with Neural Networks for Entity Disambiguation, (Ijcai), 1333–1339.
[10] Zeng, D., Liu, K., Lai, S., Zhou, G., & Zhao, J. (2014). Relation Classification via
Convolutional Deep Neural Network. Coling, (2011), 2335–2344.
[11] Gao, J., Pantel, P., Gamon, M., He, X., & Deng, L. (2014). Modeling Interestingness with Deep Neural Networks.
[12]Shen, Y., He, X., Gao, J., Deng, L., & Mesnil, G. (2014). A Latent Semantic Model with Convolutional-Pooling Structure for Information Retrieval. Proceedings of the 23rd ACM International Conference on
Conference on Information and Knowledge Management – CIKM ’14, 101–110.
[13]Weston, J., & Adams, K. (2014). # T AG S PACE : Semantic Embeddings from Hashtags, 1822–1827.
[14] Santos, C., & Zadrozny, B. (2014). Learning Character-level Representations for Part-of-Speech Tagging. Proceedings of the 31st International Conference on Machine Learning, ICML-14(2011), 1818–1826.
[15] Zhang, X.Zhao, J., & LeCun, Y. (2015). Character-level Convolutional Networks for Text Classification, 1–9.
[16] Zhang, X., & LeCun, Y. (2015). Text Understanding from Scratch. arXiv E-Prints, 3, 011102.
[17] Kim, Y., Jernite, Y., Sontag, D., & Rush, A. M. (2015). Character-Aware Neural Language Models.
原文連接:Understanding Convolutional Neural Networks for NLP(譯者/趙屹華 審覈/劉翔宇、朱正貴 責編/周建丁 原創/翻譯投稿請聯繫:zhoujd@csdn.net,微信號:jianding_zhou)
譯者簡介:趙屹華,計算廣告工程師@搜狗,前生物醫學工程師,關注推薦算法、機器學習領域。