NN4NLP課程筆記(一)

最近開始學習卡耐基梅隆大學的NLP課程——CMU CS 11-747,感覺這門課相對初學者來說是比較友好的,它結合了很多實際的NLP的任務來教授很多NLP的基礎知識,前提是要閱讀過它指定的教材。之前我已經學習過著名的斯坦福大學的cs224n的NLP課程,那門課程也是不錯的,不過已經有大牛整理了該課程的筆記,有興趣的同學可以參考CS224n-碼農場。

備註:我這個筆記並沒有嚴格按照其課程講解順序,只是將我認為比較重要的知識點總結出來,順序可能也會有不一樣。做這個筆記的原因一個是方便自己的知識回顧,還有一個就是希望能幫助那些英語不好的同學從整體了解該課程的知識體系。如有不足的地方,請指正。

Lecture1

關於CMU的這門課程有一點比較特別的是它使用的是dynet深度學習框架來完成所有的實例。這個框架與tensorflow這種靜態圖框架不同,是一種動態圖框架,和pytorch是一個類型的。眾所周知,對於動態圖框架來說,最大的好處就是可以為每個訓練樣本動態定義一個計算圖,在訓練過程中可以修改計算圖,且允許單步調試,這是tensorflow,theano等靜態圖框架不能做到的,舉個例子來說就是在tensorflow中,定義了一個add(a,b)操作,想知道該計算得到的值,必須使用session.run()之後,才能獲取結果。但是dynet則直接就能讀取該計算操作的結果。(當然,tensorflow在引入了Fold特性後,也具備了動態計算圖的能力,有興趣的同學可以參考pytorch dynet - 搜索結果 - 知乎)。當然動態計算圖的缺點也很明顯,就是每個樣本都定義不同的動態計算圖,整個模型訓練的效率會很不好,因此dynet提供了automatic batching機制來提升訓練效率,即根據實際情況給一個計算圖喂一個minibatch的數據,或者給一個樣本喂一個樣本的數據。

備註:其實課程老師 Graham Neubig說的幾個使用dynet的優點,個人感覺可能沒有那麼明顯,對於NLP任務來說,使用tensorflow等靜態計算圖框架可能確實比較麻煩,但是為啥不用pytorch或者其他框架呢?可能是因為dynet由CMU參與開發並提出的吧。我之前只用過tensorflow做過文本分類任務,在開發調試上確實有點彆扭。準備通過這個課程學習pytorch(因為pytorch相對dynet來說比較成熟)。

NLP的難題

首先NLP是做什麼的?

簡單說就是設計演算法來處理一些自然語言數據任務。人類的自然語言二義性很嚴重,相近的表示很有可能其表達的含義會不同。同時人類的自然語言也在不停的更新,例如各種網路用語、俚語等的出現。然而相對的,卻很少有人能夠完全掌握整套語言系統規則,大家只是憑感覺去處理文本。因此湧現了很多不同的方向來研究人類語言,比如有監督的機器學習方法,通過輸入大量的已經標記過的樣本數據,來學習樣本中包含的一些語言特性和規則。比如文本分類,主題提取等。

文本處理有很多先天的難度:

  1. 離散型,因為文本多是由各種語言裡面的元字元組合成詞、句得到,每個字元就是一個離散的特徵,組成的詞也是離散型的,這個與其他機器學習任務是不同的。因此要建立字元與字元或者詞語詞之間的聯繫是很難的,反面例子就是關於顏色特徵,可以根據色調值和強度值來精確區分兩個不同的顏色。
  2. 理解語言,需要會的東西太多了:語法、詞語形態、語義、自然界的常識、修辭、敘述手法、多語言間的翻譯知識等。
  3. 數據的稀疏性。由1和2可知,對自然語言文本直接建立特徵矩陣,很容易就得到一個稀疏矩陣,無法遍歷所有可能的特徵的值。光是詞的組合就有接近無限種可能。更何況人類還在不斷造詞。

本課程主要是運用深度學習中的深度神經網路來解決一些NLP的問題,後面的課程可以不斷了解到Neural Network是如何幫助我們解決上面的問題。

First Example——Sentence Classification

課程首先舉了一個句子分類的例子。兩個句子的情感分類:

這個問題可以看成是一個多分類任務,一個樣本句子對應五個標籤有5個對應的概率 P_{y_i} ,在五個標籤中選擇一個作為 P_{y_i} 最大的那個作為其最終標籤。那麼如何對文本進行特徵矩陣化呢?

方法一:Bag of Words詞袋模型

相信搞NLP的同學對詞袋模型都比較熟悉,這是對自然文本進行特徵向量化的基本操作。最簡單的詞袋模型將所有語料中的詞進行one-hot編碼,表示了一個詞是否出現在所處理的文本中。它不考慮詞序以及其他任何特徵,只是一個詞查找的功能。在課程中提到的BOW詞袋模型,應該是更高級一點的,如圖:

首先,它已經建立了詞袋,然後每個詞也訓練得到了一些詞向量,詞向量每個維度的含義如圖所示。模型的主要原理為將一個句子的所有詞的「詞-分類score向量」(姑且這麼描述)相加,同時增加偏值bias,得到一個句子的分數。然後使用softmax函數,將分數轉換成概率。

這種方法簡單,也在一定程度上解決了問題,但是有一定缺陷,如句子中出現複雜的片語、或者語法關係、或者其他複雜語義,那麼簡單得將詞分數向量相加就會失去其本身的作用,舉例:

圖中用紅框標出來的就是較為複雜的語義,dont love中,dont在neutral或者bad類型分數高的,love在very good上分數高,最後相加,可能得到一個good或者neutral的結果,顯然是不對的,下面的句子中,含有兩個negative的詞,如果相加,可能會得到一個negative的結果,顯然也是不對的。

那麼解決方法是什麼呢?課程裡面提出了一個概念叫combination Feature,表示對不同詞的組合建立的複雜特徵關係。舉例:對諸如「dont」"love"兩個詞同時存在,則其對應的bad上的分數會高一點。其實說白了就是對特徵進行組合與關聯,建立複雜的特徵。這不就是神經網路擅長的事情嗎?神經網路的本質工作之一就是能夠找到數據中的一些複雜的組合特徵,這個工作由人工來做既費時,也需要一定的專家知識,但是語言學家畢竟少,至此我們又找到一個使用神經網路來解決NLP任務的理由了。

因此,課程中對上述BOW模型進行了改進,取名為Continuous Bag of Words(CBOW)。(注意一下這個東西目前跟word2vec的CBOW不是一回事。)模型如圖:

這個CBOW模型能夠學習到一些較為高級的特徵,如主題、情感等,但是它仍然只是簡單得將句子裡面詞的scores相加,簡單的線性模型仍然無法學到複雜的combination feature。因此可以在模型增加一個非線性變換,來達到學習組合特徵的目的,deep CBOW的基本原理就是這個,如圖所示:

Computation Graph

計算圖這個是屬於開發框架的內容,不管是動態圖框架還是靜態圖框架,他們有個共同的特點就是都需要設計神經網路的計算圖。

神經網路的計算圖是一個有向圖,本質上是按照神經網路訓練時的forward Propagation的步驟來定義圖的架構。其中,圖的節點有兩種,一種是沒有指針指向的,這種節點一般表示輸入數據X,還有一種節點通常由一個有向邊指向,表示一個函數操作,例如 f(u)=u^T ,而圖的有向邊表示它指向的節點的函數參數或者是一個數據依賴。

我們只需要定義好這個圖結構,那麼這些開發框架將會自動幫我們執行forward propagation(FP)以及backward propagation(BP)。FP的實現就按照我們定義的圖結構來依次計算,課程里給了個例子: y=x^TAx+bx+c ,其計算圖以及FP過程如圖:

那麼BP是如何實現的呢,一般深度學習開發框架中,已經為每個圖中的函數節點實現了求偏導的運算,如節點 f(x,A)=x^TAx ,其對x和A的偏導已經實現,為: frac{partial f(x,A)}{partial x}=(A^T+A)x ,以及 frac{partial f(x,A)}{partial A}=xx^T .那麼框架只需要從圖的終點從後往前依次計算對參數的偏導就可以了。

(具體的BP過程就不描述了,有興趣的同學可以去吳恩達的DeepLearning課程上去學習,個人覺得裡面的推導還是對初學者比較友好的。當然斯坦福的cs231課程也不錯。)


推薦閱讀:

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