本系列是一個基於深度學習的NLP教程,2016年以前叫作CS224d: Deep Learning for Natural Language Processing,以後更名爲CS224n: Natural Language Processing with Deep Learning。新版主講人是泰斗Chris Manning和Richard Socher(這是舊版的講師),兩人分別負責不一樣的章節。博主在學習的同時,對重點內容作成系列教程,與你們分享!html
神經機率語言模型(Neural Probabilistic Language Model)中詞的表示是向量形式、面向語義的。兩個語義類似的詞對應的向量也是類似的,具體反映在夾角或距離上。甚至一些語義類似的二元詞組中的詞語對應的向量作線性減法以後獲得的向量依然是類似的。詞的向量表示能夠顯著提升傳統NLP任務的性能,例如《基於神經網絡的高性能依存句法分析器》中介紹的詞、詞性、依存關係的向量化對正確率的提高等。算法
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。兩個模型乘以兩種方法,一共有四種實現。markdown
根據上面說的整理以下:網絡
兩種稍微高效一些的訓練方法:框架
下文介紹算法中的 Skip-grams (SG),也就是說經過一個word預測context(上下文)iphone
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)
ide
原理圖:
注意這裏雖然有四條線,但模型中只有一個條件分佈(由於這只是個詞袋模型而已,與位置無關)。學習就是要最大化這些機率。函數
點積也有點像衡量兩個向量類似度的方法,兩個向量越類似,其點積越大。
softmax之所叫softmax,是由於指數函數會致使較大的數變得更大,小數變得微不足道;這種選擇做用相似於max函數。
從左到右是one-hot向量,乘以center word的W因而找到詞向量,乘以另外一個context word的矩陣W’獲得對每一個詞語的「類似度」,對類似度取softmax獲得機率,與答案對比計算損失。
這兩個矩陣都含有V個詞向量,也就是說同一個詞有兩個詞向量,哪一個做爲最終的、提供給其餘應用使用的embeddings呢?有兩種策略,要麼加起來,要麼拼接起來。在CS224n的編程練習中,採起的是拼接起來的策略
最終咱們就是要求兩個矩陣W和W’,通常是把這些參數寫進
,有
因爲上述兩個矩陣的緣由,因此θθ的維度中有個2。
咱們如何來表示這些單詞呢?首先,咱們都知道神經網絡只能接受數值輸入,咱們不可能把一個單詞字符串做爲輸入,所以咱們得想個辦法來表示這些單詞。最經常使用的辦法就是基於訓練文檔來構建咱們本身的詞彙表(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」) 的計算示意圖。
上面藍色字體說還須要output求偏導,這個確實是,可是我感受上面的對中心詞求的時候應該前面還須要求和的,覺得公式裏還有一個 ,有待驗證!!!
這樣最後就剩下遞歸降低求了,小白自行百度!
瞭解了上面的原理,你可能會注意到,這個訓練過程的參數規模很是巨大。假設語料庫中有30000個不一樣的單詞,hidden layer取128,word2vec兩個權值矩陣維度都是[30000,128],在使用SGD對龐大的神經網絡進行學習時,將是十分緩慢的。並且,你須要大量的訓練數據來調整許多權重,避免過分擬合。數以百萬計的重量數十億倍的訓練樣本意味着訓練這個模型將是一個野獸。
通常來講,有Hierarchical Softmax、Negative Sampling等方式來解決。這就是在開始的時候列出來的方法,如今知道爲何了吧!
在下一篇文章中我將對skip-pram中的negative sampling進行詳細說明