基於CNN的自然語言處理TensorFlow實現(上)

基於CNN的自然語言處理TensorFlow實現(上)

來自專欄「自然語言處理」的不歸路1 人贊了文章

引言

提到卷積神經網路,我們通常會想到計算機視覺。從 Facebook 的照片自動標註到無人駕駛汽車,CNN 在圖像分類上取得了重大突破並且成為當今大多數計算機視覺系統的核心。

最近人們逐漸開始使用 CNN 解決自然語言處理中的問題。在這篇文章中,我們首先將對 CNN 及其在 NLP 中的應用進行概述。由於應用於計算機視覺上的 CNN 更容易從直觀上來理解,因此,我們將以此為出發點進行探討,逐漸向 NLP 方向靠攏。

Kim Yoon 曾在一篇論文中提出一種模型,即 Convolutional Neural Networks for Sentence Classification 。該模型在一系列文本分類任務(如情感分析)中具有良好的分類性能,並為新的文本分類架構提供了一個標準基線。第二篇文章中,我們將實現一個與該模型相類似的基於 CNN 的模型。

由於我們水平有限,本文僅是希望與各位同行互相交流學習之用,難免存在錯誤以及不足,若您有任何意見和建議歡迎及時反饋!!如果想更好更深入地了解卷積的原理,可以參考神經網路-卷積神經網路(Python3)。

1. 什麼是卷積?

我們認為理解卷積最簡單的方式是把它看作一個應用於矩陣的滑動窗口函數。我們可以用一個動圖來更好地理解這句話,如圖1:

圖1

假設左邊的矩陣表示一個黑白圖像。每個小方格對應一個像素,黑色為0,白色為1(如果是灰度圖像,則小方格內的值通常在 0 到 255 之間)。滑動窗口一般稱為內核、濾波器或特徵檢測器。這裡我們使用的是 3×3 的濾波器,將其每個元素的值與原始矩陣中每個元素的值相乘,再將所得結果相加。為了獲得完整的卷積,我們通過在矩陣上滑動濾波器以使每個元素都能執行此操作。

下面我們用一個比較直觀的例子來向你展示上述操作的用處所在。

計算每個像素點與其相鄰像素點的值的平均數使圖像模糊

彩色圖片

濾波器

提取某個像素點與其相鄰像素點之間的差異來檢測邊緣

灰度圖像

濾波器

2. 什麼是卷積神經網路?

現在我們已經理解了什麼是卷積,那麼什麼是卷積神經網路(onvolutional neural networks,CNN)呢?CNN 基本上就是幾層卷積層的堆疊,以及應用於卷積結果值的非線性激活函數如 ReLu 或 Tanh 。在傳統的前饋神經網路中我們將每個輸入神經元與後一層的每個輸出神經元相連接。這也稱之為全連接層或仿射層。而在 CNN 中我們不採用這種連接方式,取而代之的是在輸入上進行卷積來計算輸出。這樣做就導致了我們的連接方式是局部連接的,即與輸出中的每個神經元相連的是輸入中的一個區域。CNN 的每一層應用不同的濾波器,通常會有成百上千個如上圖所示的濾波器,並且最終會將它們的結果進行結合。與此同時,還有稱之為池化層(或降採樣層)的結構,我們稍後將深入探討。在訓練階段,CNN 會根據你要執行的任務自動學習其濾波器的值。例如,在圖像分類中,CNN可以學習從第一層的原始像素中檢測邊緣,然後使用邊緣對第二層中的簡單形狀進行檢測,然後使用這些形狀來檢測更高級別的特徵,例如位於較高層的面部輪廓。而最後一層是利用這些特徵進行分類的分類器。

這種計算方式有兩種顯著特性:位置不變性和組合性。假設你要分辨出圖象中是否有一隻猴子。由於你要在整個圖像上滑動濾波器,所以你並會關心猴子在圖像中的位置。事實上,池化也可以為你提供平移、旋轉、縮放的不變性,但池化的作用不僅只在於此。第二個關鍵特性是(局部)組合性。每個濾波器將較低級特徵的局部塊組合成更高級的表示。這也就是為什麼 CNN 在機器視覺領域如此強大的原因。直觀來說,你可以用像素構建邊緣、用邊緣構建形狀、用形狀構建更複雜的對象。

3. 如何將其應用於NLP?

不同於圖像的像素,大多數 NLP 任務的輸入是表示為矩陣的句子或文檔。矩陣的每一行對應一個標記,通常是一個單詞,但也可以是一個字元。也就是說,每一行都是表示一個單詞的向量。通常,這些向量是詞嵌入(低維表示),如 word2vec 或 GloVe。但其也可以是一個對應於辭彙表中索引的 one-hot 向量。對於一個具有 10 個單詞的句子,採用 100 維嵌入,則會得到一個 10×100 的矩陣作為輸入。我們把這作為我們的「圖像」。

在視覺處理上,我們的濾波器划過圖像的局部塊,但在 NLP 中,我們通常使用濾波器滑過矩陣的一整行(一個單詞)。因此,我們的濾波器的「寬度」通常與輸入矩陣的寬度相同。高度或者說區域大小可能會有所不同,但通常每次將窗口滑過 2-5 個單詞。綜上所述,基於卷積神經網路的 NLP 應該是如下圖這樣子的。

上圖所示的是用於句子分類的卷積神經網路架構。這裡我們有三種濾波器的尺寸:2、3和 4,每種尺寸各有兩個濾波器。每個濾波器對句子矩陣執行卷積並生成(可變長度的)特徵映射。然後在每個映射上執行 1-max 池化,即記錄每個特徵映射中的最大值。因此我們就從 6 個映射中生成了 6 個只包含一個元素的特徵向量。然後將這 6 個只包含一個元素的特徵向量串聯起來,形成倒數第二層的特徵向量。最後的 softmax 層接收這個特徵向量作為輸入,並用其對句子進行分類。這裡我們假設進行二分類,因此上圖描述了兩種可能的輸出狀態。

對於圖像來說,我們對其局部不變性和局部組合性有著直觀的感受,然而對於 NLP 卻並非如此。因為你可能非常在意一個單詞在句子中出現的位置。在圖像處理中,彼此靠近的像素在含以上可能是相關的,然而 NLP 中的單詞卻並不總是具有這樣的特性。在許多語言中,有些短語可能被幾個其他單詞來分割開。並且單詞的組合方式也是很模糊的,很明顯,單詞以某種方式組合,例如形容詞用來修飾名詞,然而我們很難賦予更高級的表示以合適的含義。也很難解釋其機理究竟是怎樣的。這一切並不像計算機視覺的例子那麼明顯。

考慮到上述這些情況,似乎 CNN 並不適合 NLP 任務。循環神經網路會更加直觀。循環神經網路更類似於我們處理語言的方式(或者至少是我們所認為的我們處理語言的方式):即從做到右順序閱讀。幸運的是,這並不意味著 CNN 沒有任何作用。相反,結果表明,CNN 在 NLP 問題上的應用效果非常好。儘管詞袋模型明顯是一種在錯誤的假設下做出的過度簡化,但多年來它依然一直是標準的方法,並且具有良好的成效。

CNN 最重要的一點就是速度快。非常之快。卷積是計算機圖形學的核心部分,並且我們可以在 GPU 的硬體級上來執行卷積。即使與 n-gram 相比,CNN 在表示方面也是十分高效的。在辭彙量巨大的情況下,對任何超過 3-gram 的計算很快就會帶來高昂的計算代價。即使谷歌也無法進行超過 5-gram 的計算。卷積濾波器不需要表示整個辭彙表,而只是自動地學習合適的表示。尺寸大於 5 的濾波器是完全可行的,我們更傾向於認為,第一層中的許多學習到的濾波器所捕捉到的特徵與 n-gram 非常相似(但不限於此),但是以更緊湊的方式來表示這些特徵。

4. CNN 的超參數

在解釋 CNN 如何應用於 NLP 任務之前,讓我們先看一下構建 CNN 時需要做出的一些選擇。希望這將有助於我們更好地理解該領域的文獻。

窄卷積以及寬卷積

當我們探討上面的卷積的時候,我們忽略了如何應用濾波器的一些細節。在矩陣的中心位置上應用一個 3×3 的濾波器沒有任何問題,但是在邊緣上呢?對於矩陣的第一個元素,它的上面和左邊沒有任何與之相鄰的元素,那麼該如何將濾波器應用到這個元素上?這時我們可以使用零填充,即我們認為所有矩陣之外的元素都是零。通過這種方式,我們可以將濾波器應用到輸入矩陣中的每個元素,並且可以獲得更大或同等尺寸的輸出。添加零填充也稱為寬卷積,不使用零填充稱為窄卷積。如下圖所示是一個一維的例子:

其中,左圖為窄卷積,由圖為寬卷積。

當濾波器的尺寸相對於輸入的尺寸較大時,可以看到寬卷積是多麼有用,甚至是必須的。上圖中,窄卷積產生一個尺寸為(7-5)+1=3 的輸出。而寬卷積產生一個尺寸為(7+2×4-5)+1=11的輸出。將其推廣,可知輸出的尺寸的公式為: n_{out}=(n_{in}+2	imes n_{padding}-n_{filter})+1

步長

卷積的另一個超參數是步長,它定義了你想在每一步中移動你的濾波器的程度。在上面的所有例子中,步長都是 1,並且濾波器的連續應用是重疊的。較大的步長會導致濾波器應用的次數較少,輸出尺寸也更小。下圖顯示了應用於一維輸入的尺寸分別為 1 和 2 的步長。

在文獻中,我們通常看到的步長是 1,但是較大的步長可以讓你構建一個類似於遞歸神經網路的模型,即看起來像一棵樹。

池化層

卷積神經網路的一個關鍵特性就是池化層,通常應用於卷積層之後。池化層對輸入進行降採樣。實現池化的最常見的操作是對每個濾波器的結果應用一個取最大值操作。你不需要在整個矩陣上進行池化,而只需要在一個窗口內進行池化。例如,下圖顯示了一個 2×2 的最大池化(在 NLP 中我們通常在整個輸出上進行池化,每個濾波器只產生一個數值)。

為什麼要進行池化?有以下幾個原因:首先池化的一個特性是它能夠產生一個固定尺寸的輸出矩陣,這通常是進行分類所必須的。例如,如果你有 1000 個濾波器,並對每個濾波器應用最大池化,那麼無論你的濾波器尺寸是多少以及輸入的尺寸是多少,你都會得到一個 1000 維的輸出。這就允許我們使用任意尺寸的句子以及任意尺寸的濾波器,而得到相同維度的輸出來作為最終分類器的輸入。

池化在減少輸出維度的同時,(我們希望)保留了最重要的信息。你可以將每個濾波器視為對某個特定特徵的檢測,例如檢測句子中是否包含「not amazing」之類的否定語句。如果這個短語出現在句子中的某個位置,那麼濾波器應用到該區域的結果將產生較大的值,但在其他區域產生較小的值。通過執行最大池化操作,你可以保留關於句子中是否出現這個特徵的信息,但是你將丟失它出現的確切位置的信息。但是這些關於局部性的信息真的有用嗎?答案是肯定的,它有點類似於 n-gram 模型。你在丟失關於局部性的全局信息的同時,保留了濾波器捕捉到的局部信息,比如「not amazing」,「amazing not」的巨大差異。

在圖像識別中,池化還具有平移(移動)和旋轉不變性。當你在一個區域上使用池化時,即使你將圖像平移/旋轉幾個像素,輸出也不會有太大變化,因為無論如何,最大池化操作選擇出來的最大值都是同一個值。

通道

我們需要理解的最後一個概念是通道。通道是輸入數據的不同「視圖」。例如,在圖像識別中,通常有 RGB (紅、黃、藍)通道。你可以跨通道應用卷積,你可以對它們應用不同的權重,也可以應用相同的權重。在 NLP 中,你可以想像有不同的通道:你可以有一個用於不同詞嵌入的單獨通道(例如 word2vec 和 GloVe ),也可以有一個通道用於以不同語言表示的同一個句子,或者以不同方式表述的短語。

5. 將卷積神經網路應用於 NLP

現在讓我們來看看 CNN 在自然語言處理中的一些應用。

最適合 CNN 的首先是分類任務,如情感分析、垃圾郵件檢測或主題分類。由於卷積和池化操作會丟失關於單詞局部順序的信息,因此,像在 PoS 標記或實體抽取中那樣的序列標記很難適用於純 CNN 架構(儘管向輸入中添加位置特徵也不是不可能)。

文章 [1] 在各種分類數據集上對 CNN 架構進行評估,其中主要包括情感分析和主題分類任務。CNN 架構在數據集上的表現十分優異,甚至在某些數據集上達到了全新的水準。不可思議的是,這篇文章所使用的網路十分簡單,這也正是 CNN 架構如此強大的原因。首先輸入層是由串連的 word2vec 詞嵌入組成的句子。然後是一個帶有多個濾波器的卷積層,再接著是最大池化層,最後是一個 softmax 分類器。這篇文章還對兩種不同的信道進行了靜態和動態詞嵌入的實驗,其中一個信道在訓練過程中進行了調整,另一個則沒有。在文章 [2] 中提出過類似的、但有些複雜的體系結構。文章[6] 為這個網路架構添加了一個額外的層來執行「語義聚類」。

文章 [5] 從零開始訓練CNN,不需要像 word2vec 或 GloVe 這樣的預先訓練過的單詞向量。它直接將卷積應用於一個 one-hot 向量。此外,作者還提出了一種空間高效的類似於詞袋模型的輸入數據表示法,從而減少了網路需要學習的參數的數量。在文章 [5] 中,作者額外用一個無監督的「區域嵌入」擴展了模型,這個「區域嵌入」是用 CNN 預測文本區域的上下文而學習到的。這些文章中的方法似乎適用於長篇文本(如電影評論),但它們在短文本(如tweet)上的表現尚不清楚。對短文本使用預先訓練過的詞嵌入和對長文使用詞嵌入,直覺上來說,後者能產生更大的收益。

構建一個 CNN 架構意味著我們需要設定許多超參數,其中有些是我們上面提到的:輸入表示(word2vec,GloVe,one-hot)、卷積濾波器的數量和尺寸、池化策略(最大池化、平均池化)以及激活函數(ReLu、tanh)。文章 [7] 對 CNN 架構中不同超參數的影響進行了實證評價。研究了它們在多次運行下對性能和方差的影響。如果你想要自己實現一個用於文本分類的 CNN,那麼使用文章 [7] 是一個明智的選擇。一個顯著的結論是,最大池化總是優於平均池化,一個理想的濾波器尺寸很重要,但也要結合具體任務來考慮。與此同時,在 NLP 任務中,關於正則化的考慮並沒什麼不同。這項研究需要注意的一點是,所有的數據集在文檔長度上都非常相似,因此相同的指導原則可能並不適用於差別很大的數據。

文章 [8] 探索了基於 CNN 的關係提取和關係分類任務。除了單詞向量之外,作者還將單詞對相關實體的相對位置作為卷積層的輸入。該模型假定實體的位置是給定的,並且每個樣本輸入包含一個關係。文章 [9] 和 [10]也對類似的模型進行了研究。

文章 [11] 和 [12] 展示了另一個比較有趣的 CNN 應用於 NLP 的例子,它來自微軟研究院。這兩篇文章描述了如何學習語義上有意義的可以用於信息檢索的句子表示。文章中給出的例子包括根據用戶當前閱讀的內容向用戶推薦有趣的文檔。句子表示是基於搜索引擎日誌數據進行訓練的。

大多數 CNN 架構以這種或那種方式學習單詞和句子的嵌入(低維表示)作為其訓練過程的一部分。然而並非所有文章都關注這一方面。文章 [13] 提出了一種 CNN 架構來預測 Facebook 帖子的主題標籤,同時為單詞和句子生成有意義的嵌入。然後,這些學習嵌入成功地應用於另一項任務,即向用戶推薦可能的有趣的文檔,並根據點擊流數據進行訓練。

6. 字元級的 CNN

到目前為止,所有的模型都是基於單詞的。但也有研究將 CNN 直接應用於字元。文章 [14] 就學習了字元級的嵌入,將其與預先訓練的詞嵌入結合起來,並使用 CNN 作為詞性標註的一部分。文章 [15] 和 [16] 探索了如何使用 CNN 直接從字元中進行學習,而不需要任何預先訓練過的嵌入。值得注意的是,作者使用了一個相對較深的網路,總共有9層,並將其應用於情感分析和文本分類任務。結果表明,直接對字元級輸入進行學習在大型數據集(數以百萬計的例子)上非常有效,但較簡單的模型在較小的數據集(成千上萬的例子)上則表現得較差。文章 [17] 探索了字元級卷積在語言建模中的應用,即使用字元級 CNN 的輸出作為 LSTM 在每個時間步上的輸入。類似的模型可以適用於各種語言。以上所有論文都是在最近 1-2 年內發表的。顯然已經有許多 CNN 應用於 NLP 的出色的研究成果,而且新的研究成果和更先進的系統正如雨後春筍般出現。

接下來,我們將利用 TensorFlow 實現一個具體的基於 CNN 的 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.

推薦閱讀:

為何讀不懂你的那個TA
NNLM最新論文調研-1-《Character-Aware Neural Language Models》
04 GloVe詞向量使用介紹及思考
《Assertion-based QA with Question-Aware Open Information Extraction》閱讀筆記
gensim計算文檔相似度

TAG:神經網路 | 深度學習DeepLearning | 自然語言處理 |