1. 程式人生 > >第二講 cs224n系列之word2vec & 詞向量

第二講 cs224n系列之word2vec & 詞向量

本系列是一個基於深度學習的NLP教程,2016年之前叫做CS224d: Deep Learning for Natural Language Processing,之後改名為CS224n: Natural Language Processing with Deep Learning。新版主講人是泰斗Chris Manning和Richard Socher(這是舊版的講師),兩人分別負責不同的章節。博主在學習的同時,對重點內容做成系列教程,與大家分享!

系列目錄(系列更新中)

1.語言模型

神經概率語言模型(Neural Probabilistic Language Model)中詞的表示是向量形式、面向語義的。兩個語義相似的詞對應的向量也是相似的,具體反映在夾角或距離上。甚至一些語義相似的二元片語中的詞語對應的向量做線性減法之後得到的向量依然是相似的。詞的向量表示可以顯著提高傳統NLP任務的效能,例如《基於神經網路的高效能依存句法分析器》中介紹的詞、詞性、依存關係的向量化對正確率的提升等。

2.word2vec

word2vec是一個計算word vector的開源工具。當我們在說word2vec演算法或模型的時候,其實指的是其背後用於計算word vector的CBoW模型和Skip-gram模型。很多人以為word2vec指的是一個演算法或模型,這也是一種謬誤。

詞向量的早期編碼方式我們一般叫做1-of-N representation或者one hot representation. 比如我們有下面的5個片語成的詞彙表,詞”Queen”的序號為2, 那麼它的詞向量就是(0,1,0,0,0)(0,1,0,0,0)。同樣的道理,詞”Woman”的詞向量就是(0,0,0,1,0) (0,0,0,1,0). One hot representation用來表示詞向量非常簡單,但是卻有很多問題。最大的問題是我們的詞彙表一般都非常大,比如達到百萬級別,這樣每個詞都用百萬維的向量來表示簡直是記憶體的災難。這樣的向量其實除了一個位置是1,其餘的位置全部都是0,表達的效率不高.
Dristributed representation可以解決One hot representation的問題,它的思路是通過訓練,將每個詞都對映到一個較短的詞向量上來。所有的這些詞向量就構成了向量空間,進而可以用普通的統計學的方法來研究詞與詞之間的關係。當然在實際情況中,我們並不能對詞向量的每個維度做一個很好的解釋。具體詞向量的樣子在後面Skip-grams框架中有講解。

word2vec作為神經概率語言模型的輸入,其本身其實是神經概率模型的副產品,是為了通過神經網路學習某個語言模型而產生的中間結果。具體來說,“某個語言模型”指的是“CBOW”和“Skip-gram”。具體學習過程會用到兩個降低複雜度的近似方法——Hierarchical Softmax或Negative Sampling。兩個模型乘以兩種方法,一共有四種實現。

根據上面說的整理如下:

  • Skip-grams (SG):預測上下文
  • Continuous Bag of Words (CBOW):預測目標單詞

兩種稍微高效一些的訓練方法:

  • Hierarchical softmax
  • Negative sampling

下文介紹演算法中的 Skip-grams (SG),也就是說通過一個word預測context(上下文)

2.1CBOW與Skip-Gram模式關係

word2vec主要分為CBOW(Continuous Bag of Words)和Skip-Gram兩種模式。CBOW是從原始語句推測目標字詞;而Skip-Gram正好相反,是從目標字詞推測出原始語句。CBOW對小型資料庫比較合適,而Skip-Gram在大型語料中表現更好。
對同樣一個句子:Hangzhou is a nice city。我們要構造一個語境與目標詞彙的對映關係,其實就是input與label的關係。
這裡假設滑窗尺寸為1(滑窗尺寸……這個……不懂自己google吧-_-|||)
CBOW可以製造的對映關係為:[Hangzhou,a]—>is,[is,nice]—>a,[a,city]—>nice
Skip-Gram可以製造的對映關係為(is,Hangzhou),(is,a),(a,is), (a,nice),(nice,a),(nice,city)
這裡寫圖片描述

3 Skip-gram基本模型

原理圖:
這裡寫圖片描述
注意這裡雖然有四條線,但模型中只有一個條件分佈(因為這只是個詞袋模型而已,與位置無關)。學習就是要最大化這些概率。

3.1 相關公式

J(θ)=t=1Tmjmj0p(wt+j|wt;θ)
要最大化目標函式。對其取個負對數,得到損失函式——對數似然的相反數:
Negative log likelihood:
J(θ)=1Tt=1Tmjmj0log{p(wt+j|wt)}
這些術語都是一樣的:Loss function = cost function = objective function,不用擔心用錯了。對於softmax來講,常用的損失函式為交叉熵。
其中:
某個上下文條件概率p(wt+j|wt;θ)可由softmax得到:
圖片描述
這裡的o是outside(或者output)單詞索引(下標),c是中心詞的索引(下標),vcuc是中心詞c和outside(或者output)詞o對應的詞向量 (這裡的outside或者output其實就是上下文中的單詞)

點積也有點像衡量兩個向量相似度的方法,兩個向量越相似,其點積越大。
softmax之所叫softmax,是因為指數函式會導致較大的數變得更大,小數變得微不足道;這種選擇作用類似於max函式。

3.2 Skipgram框架結構

這裡寫圖片描述
從左到右是one-hot向量,乘以center word的W於是找到詞向量,乘以另一個context word的矩陣W’得到對每個詞語的“相似度”,對相似度取softmax得到概率,與答案對比計算損失。

這兩個矩陣都含有V個詞向量,也就是說同一個詞有兩個詞向量,哪個作為最終的、提供給其他應用使用的embeddings呢?有兩種策略,要麼加起來,要麼拼接起來。在CS224n的程式設計練習中,採取的是拼接起來的策略

最終我們就是要求兩個矩陣W和W’,一般是把這些引數寫進θ,有
圖片描述
由於上述兩個矩陣的原因,所以θθ的維度中有個2。

3.3 Skipgram框架相關細節

我們如何來表示這些單詞呢?首先,我們都知道神經網路只能接受數值輸入,我們不可能把一個單詞字串作為輸入,因此我們得想個辦法來表示這些單詞。最常用的辦法就是基於訓練文件來構建我們自己的詞彙表(vocabulary)再對單詞進行one-hot編碼。

假設從我們的訓練文件中抽取出10000個唯一不重複的單片語成詞彙表。我們對這10000個單詞進行one-hot編碼,得到的每個單詞都是一個10000維的向量,向量每個維度的值只有0或者1,假如單詞ants在詞彙表中的出現位置為第3個,那麼ants的向量就是一個第三維度取值為1,其他維都為0的10000維的向量(ants=[0, 0, 1, 0, …, 0])。

還是上面的例子,“The dog barked at the mailman”,那麼我們基於這個句子,可以構建一個大小為5的詞彙表(忽略大小寫和標點符號):(“the”, “dog”, “barked”, “at”, “mailman”),我們對這個詞彙表的單詞進行編號0-4。那麼”dog“就可以被表示為一個5維向量[0, 1, 0, 0, 0]。

模型的輸入如果為一個10000維的向量,那麼輸出也是一個10000維度(詞彙表的大小)的向量,它包含了10000個概率,每一個概率代表著當前詞是輸入樣本中output word的概率大小。

下圖是我們神經網路的結構:
這裡寫圖片描述

隱層沒有使用任何啟用函式,但是輸出層使用了sotfmax。

我們基於成對的單詞來對神經網路進行訓練,訓練樣本是 ( input word, output word ) 這樣的單詞對,input word和output word都是one-hot編碼的向量。最終模型的輸出是一個概率分佈。

隱層

說完單詞的編碼和訓練樣本的選取,我們來看下我們的隱層。如果我們現在想用300個特徵來表示一個單詞(即每個詞可以被表示為300維的向量)。那麼隱層的權重矩陣應該為10000行,300列(隱層有300個結點)。

Google在最新發布的基於Google news資料集訓練的模型中使用的就是300個特徵的詞向量。詞向量的維度是一個可以調節的超引數(在Python的gensim包中封裝的Word2Vec介面預設的詞向量大小為100, window_size為5)。

看下面的圖片,左右兩張圖分別從不同角度代表了輸入層-隱層的權重矩陣。左圖中每一列代表一個10000維的詞向量和隱層單個神經元連線的權重向量。從右邊的圖來看,每一行實際上代表了每個單詞的詞向量。

這裡寫圖片描述

所以我們最終的目標就是學習這個隱層的權重矩陣。

我們現在回來接著通過模型的定義來訓練我們的這個模型。

上面我們提到,input word和output word都會被我們進行one-hot編碼。仔細想一下,我們的輸入被one-hot編碼以後大多數維度上都是0(實際上僅有一個位置為1),所以這個向量相當稀疏,那麼會造成什麼結果呢。如果我們將一個1 x 10000的向量和10000 x 300的矩陣相乘,它會消耗相當大的計算資源,為了高效計算,它僅僅會選擇矩陣中對應的向量中維度值為1的索引行(這句話很繞),看圖就明白。

這裡寫圖片描述

我們來看一下上圖中的矩陣運算,左邊分別是1 x 5和5 x 3的矩陣,結果應該是1 x 3的矩陣,按照矩陣乘法的規則,結果的第一行第一列元素為0 x 17 + 0 x 23 + 0 x 4 + 1 x 10 + 0 x 11 = 10,同理可得其餘兩個元素為12,19。如果10000個維度的矩陣採用這樣的計算方式是十分低效的。

為了有效地進行計算,這種稀疏狀態下不會進行矩陣乘法計算,可以看到矩陣的計算的結果實際上是矩陣對應的向量中值為1的索引,上面的例子中,左邊向量中取值為1的對應維度為3(下標從0開始),那麼計算結果就是矩陣的第3行(下標從0開始)—— [10, 12, 19],這樣模型中的隱層權重矩陣便成了一個”查詢表“(lookup table),進行矩陣計算時,直接去查輸入向量中取值為1的維度下對應的那些權重值。隱層的輸出就是每個輸入單詞的“嵌入詞向量”。

輸出層

經過神經網路隱層的計算,ants這個詞會從一個1 x 10000的向量變成1 x 300的向量,再被輸入到輸出層。輸出層是一個softmax迴歸分類器,它的每個結點將會輸出一個0-1之間的值(概率),這些所有輸出層神經元結點的概率之和為1。

下面是一個例子,訓練樣本為 (input word: “ants”, output word: “car”) 的計算示意圖。
這裡寫圖片描述

3.4 相關推導

這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

上面藍色字型說還需要output求偏導,這個確實是,但是我感覺上面的對中心詞求的時候應該前面還需要求和的,以為公式裡還有一個,有待驗證!!!

這樣最後就剩下遞迴下降求了,小白自行百度!

4 訓練優化

瞭解了上面的原理,你可能會注意到,這個訓練過程的引數規模非常巨大。假設語料庫中有30000個不同的單詞,hidden layer取128,word2vec兩個權值矩陣維度都是[30000,128],在使用SGD對龐大的神經網路進行學習時,將是十分緩慢的。而且,你需要大量的訓練資料來調整許多權重,避免過度擬合。數以百萬計的重量數十億倍的訓練樣本意味著訓練這個模型將是一個野獸。
一般來說,有Hierarchical Softmax、Negative Sampling等方式來解決。這就是在開始的時候列出來的方法,現在知道為什麼了吧!
在下一篇文章中我將對skip-pram中的negative sampling進行詳細說明

參考文獻