1. 程式人生 > >word2vec並行實現小記

word2vec並行實現小記

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               


word2vec能將文字中出現的詞向量化,其原理建立在Mikolov的博士論文成果及其在谷歌的研究經驗的基礎上。與潛在語義分析(Latent Semantic Index, LSI)、潛在狄立克雷分配(Latent Dirichlet Allocation)的經典過程相比,word2vec利用了詞的上下文,語義資訊更加地豐富。word2vec並不是Mikolov某一天拍拍腦袋就給想出來的,也是站在牛人的肩膀上。大牛Bengio(NIPS 2001)藉著深度學習的東風提出了一種可並行的神經網路模型;Morin(2005)為了加快神經網路語言模型(Neural Network Language Model,NNLM)的概率輸出Softmax的計算,提出了Hierarchical Softmax;Mikolov同學慢慢地注意到神經網路在語言模型中的作用,早年的論文多在語音領域,其博士論文總結並優化了迴圈神經網路(Recurrent Neural Network),之後到了谷歌做研究,才總算提出了word2vec。這一段歷史可進一步檢視

licstar的部落格:詞向量與語言模型。本文的重點在於描述word2vec是如何並行的,或者說是哪個部分並行的。相關實現程式碼在gitHub/siegfang/word2vec

並行前的準備

並行訓練前需要遍歷一遍所有的訓練的語料,統計詞頻,並依據詞頻構建一顆哈夫曼樹(Huffman Tree)。一般來說,在海量語料的情況下,詞頻非常小的詞一般不予以考慮。這裡面大概有兩個原因:

  • 只出現一次或兩次的詞往往會非常之多,得到的詞彙表非常龐大,後續所需的記憶體空間(包括哈夫曼樹和詞向量)也將非常龐大,訓練時間也會相應地延長;
  • 詞頻極低的詞由於出現次數少,在神經網路訓練中往往得不到充分地訓練,其詞向量可能會與鄰近詞相近,這會降低訓練效果。

一個例子就是“奧巴馬與主席夫人彭麗...”中的“彭麗”。由於新聞抓取錯誤或人名缺失等問題,會產生很多莫名其妙的低頻詞。深度學習等一切機器學習都不是萬能的,去掉或替換這些噪聲,能使得訓練更好地進行。

並行ing

並行的關鍵在於如何分割好並行的任務和如何達成任務之間的良好通訊?具體到word2vec來說,需要做的是將訓練的語料分成若干份,依次交給並行的執行緒、程序或分散式機器等並行執行載體進行Skip-Gram或CBow-Gram模型訓練,在各個獨立的並行空間中,語料是不相同的,但訓練的神經網路、詞向量和哈夫曼是共享的,訓練中使用的學習率等引數需要更新,在結束訓練後需要計算。

Hierarchical Softmax

Hierarchical Softmax使用以詞作為葉子的二叉樹(這裡即為哈夫曼樹)來計算每個詞出現的概率。每個詞都可以由根結點經過某一路徑到達,設L(w)是這條路徑的長度,n(w,j)是這條路徑上的第j個結點。顯然n(w,1)即為根結點(root),n(w,L(w))是詞所在的葉子結點。除了葉子結點,對於整棵樹中包括根在內的其它結點,ch(n)表示結點n所分支的某一子結點。以輸入詞向量預測輸出向量的概率計算公式為:

其中[x]為指示函式,當x為真時,[x]的值為1,否則為-1;。拿Skip-Gram模型來說,就是要以一個詞的向量去預測其上下文的詞的向量,而CBow-Gram則是先將上下文的詞的向量和來預測中間詞的向量,如下圖所示:

gram

word2vec中通過最小化交叉熵來對哈夫曼樹節點向量和詞向量進行更新。從根結點到詞結點的路徑可以看作是不斷地從父結點選擇一個子結點的過程,要使得路徑正確就必須使得每次子結點的選擇正確,也就是選擇正確子結點的概率比錯誤的高。哈夫曼樹從根結點開始的邊要麼以0標記,要麼以1標記,這裡使用交叉熵來使得每次選擇都能儘可能地正確,正確選擇的概率p(c)及交叉熵H如下

其中c為正確選擇的標記。最小化交叉熵可以通過梯度下降法迭代實現,偏導如下式所示:

Mikolov在其實現中使用1-c,這其實是一樣的。之前我不是很明白為什麼這麼做?直到我用CBow-Gram做了一次主客觀分類和褒貶分類時,我發現使用1-c會比使用c,準確率、召回率都會高1%,算是個小經驗(trick)吧~

站在巨人的肩膀上

參考了其它語言和大牛的實現方法,包括:

為啥不實現Negative Sampling

Negative Sampling在Mikolov自個兒的C程式碼中是有實現的,但ansj和piskvorky就沒有,jdeng實現了但用巨集(define)置程式碼無法執行。我挨個遍歷了沒有實現的大牛,問是不是因為詞向量的質量在即使沒Negative Sampling的情況下也足夠好?

  • jdeng issue#2:Right. The performance improvement was not observed but I am not sure if my implementation is accurate.
  • piskvorky issue#156:See issue #130 : negative sampling is waiting for someone to implement it.
  • ansj issue#4:一直沒有回覆

記憶體

我使用ansj的序列實現對比我的並行實現,分別做了在77M網路小說資料和1G新聞資料的對比。記憶體變化圖如下:

77_seq

77M文字資料序列訓練堆記憶體變化圖

77_para

77M文字資料並行訓練堆記憶體變化圖

1G_seq

1G文字資料序列訓練堆記憶體變化圖

1G_para

1G文字資料並行訓練堆記憶體變化圖

參考文獻

  • Bengio Y, Ducharme R, Vincent P, et al. A Neural Probabilistic Language Model[J]. Journal of Machine Learning Research, 2003, 3: 1137-1155.
  • Morin F, Bengio Y. Hierarchical probabilistic neural network language model[C]//Proceedings of the international workshop on artificial intelligence and statistics. 2005: 246-252.
  • Mikolov T. Statistical Language Models Based on Neural Networks}[D]. Ph. D. thesis, Brno University of Technology, 2012.
  • Mikolov T, Sutskever I, Chen K, et al. Distributed representations of words and phrases and their compositionality[J]. arXiv preprint arXiv:1310.4546, 2013.
  • Mikolov T, Chen K, Corrado G, et al. Efficient Estimation of Word Representations in Vector Space[J]. arXiv preprint arXiv:1301.3781, 2013.
  • word2vec演示:http://thisplusthat.me/
           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述