一文詳解 Word2vec 之 Skip-Gram 模型(實現篇)
雷鋒網按:這是一個關於 Skip-Gram 模型的系列教程,共分為結構、訓練和實現三個部分,本文為最後一部分:實現篇。原文作者天雨粟,原載於作者知乎專欄,雷鋒網已獲授權。
前言上一篇的專欄介紹了Word2Vec中的Skip-Gram模型,如果看過的小夥伴可以直接開始動手用TensorFlow實現自己的Word2Vec模型,本篇文章將利用TensorFlow來完成Skip-Gram模型。還不是很了解Skip-Gram思想的小夥伴可以先看一下上一篇的專欄內容。
本篇實戰代碼的目的主要是加深對Skip-Gram模型中一些思想和trick的理解。由於受限於語料規模、語料質量、演算法細節以及訓練成本的原因,訓練出的結果顯然是無法跟gensim封裝的Word2Vec相比的,本代碼適合新手去理解與練習Skip-Gram模型的思想。
工具介紹● 語言:Python 3
● 包:TensorFlow(1.0版本)及其它數據處理包(見代碼中)
● 編輯器:jupyter notebook
● 線上GPU:floyd (https://www.floydhub.com/)
● 數據集:經過預處理後的維基百科文章(英文)
正文部分文章主要包括以下四個部分進行代碼構造:
- 數據預處理
- 訓練樣本構建
- 模型構建
- 模型驗證
1 數據預處理
關於導入包和載入數據在這裡就不寫了,比較簡單,請參考git上的代碼。
數據預處理部分主要包括:
替換文本中特殊符號並去除低頻詞
對文本分詞
構建語料
單詞映射表
首先我們定義一個函數來完成前兩步,即對文本的清洗和分詞操作。
上面的函數實現了替換標點及刪除低頻詞操作,返回分詞後的文本。
下面讓我們來看看經過清洗後的數據:
有了分詞後的文本,就可以構建我們的映射表,代碼就不再贅述,大家應該都比較熟悉。
我們還可以看一下文本和詞典的規模大小:
整個文本中單詞大約為1660萬的規模,詞典大小為6萬左右,這個規模對於訓練好的詞向量其實是不夠的,但可以訓練出一個稍微還可以的模型。
2 訓練樣本構建我們知道skip-gram中,訓練樣本的形式是(input word, output word),其中output word是input word的上下文。為了減少模型噪音並加速訓練速度,我們在構造batch之前要對樣本進行採樣,剔除停用詞等噪音因素。
採樣
在建模過程中,訓練文本中會出現很多「the」、「a」之類的常用詞(也叫停用詞),這些詞對於我們的訓練會帶來很多噪音。在上一篇Word2Vec中提過對樣本進行抽樣,剔除高頻的停用詞來減少模型的噪音,並加速訓練。
我們採用以下公式來計算每個單詞被刪除的概率大小:
其中 f(wi) 代表單詞 wi 的出現頻次。t為一個閾值,一般介於1e-3到1e-5之間。
上面的代碼計算了樣本中每個單詞被刪除的概率,並基於概率進行了採樣,現在我們手裡就拿到了採樣過的單詞列表。
構造batch
我們先來分析一下skip-gram的樣本格式。skip-gram不同於CBOW,CBOW是基於上下文預測當前input word。而skip-gram則是基於一個input word來預測上下文,因此一個input word會對應多個上下文。我們來舉個栗子「The quick brown fox jumps over lazy dog」,如果我們固定skip_window=2的話,那麼fox的上下文就是[quick, brown, jumps, over],如果我們的batch_size=1的話,那麼實際上一個batch中有四個訓練樣本。
上面的分析轉換為代碼就是兩個步驟,第一個是找到每個input word的上下文,第二個就是基於上下文構建batch。
首先是找到input word的上下文單詞列表:
我們定義了一個get_targets函數,接收一個單詞索引號,基於這個索引號去查找單詞表中對應的上下文(默認window_size=5)。請注意這裡有一個小trick,我在實際選擇input word上下文時,使用的窗口大小是一個介於[1, window_size]區間的隨機數。這裡的目的是讓模型更多地去關注離input word更近詞。
我們有了上面的函數後,就能夠輕鬆地通過input word找到它的上下文單詞。有了這些單詞我們就可以構建我們的batch來進行訓練:
注意上面的代碼對batch的處理。我們知道對於每個input word來說,有多個output word(上下文)。例如我們的輸入是「fox」,上下文是[quick, brown, jumps, over],那麼fox這一個batch中就有四個訓練樣本[fox, quick], [fox, brown], [fox, jumps], [fox, over]。
3 模型構建數據預處理結束後,就需要來構建我們的模型。在模型中為了加速訓練並提高詞向量的質量,我們採用負採樣方式進行權重更新。
輸入層到嵌入層
輸入層到隱層的權重矩陣作為嵌入層要給定其維度,一般embeding_size設置為50-300之間。
嵌入層的 lookup 通過 TensorFlow 中的 embedding_lookup 實現,詳見:
http://t.cn/RofvbgF
嵌入層到輸出層
在skip-gram中,每個input word的多個上下文單詞實際上是共享一個權重矩陣,我們將每個(input word, output word)訓練樣本來作為我們的輸入。為了加速訓練並且提高詞向量的質量,我們採用negative sampling的方法來進行權重更新。
TensorFlow中的sampled_softmax_loss,由於進行了negative sampling,所以實際上我們會低估模型的訓練loss。詳見:http://t.cn/RofvS4t
請注意代碼中的softmax_w的維度是vocab_size x embedding_size,這是因為TensorFlow中的sampled_softmax_loss中參數weights的size是[num_classes, dim]。
4 模型驗證
在上面的步驟中,我們已經將模型的框架搭建出來,下面就讓我們來訓練訓練一下模型。為了能夠更加直觀地觀察訓練每個階段的情況。我們來挑選幾個詞,看看在訓練過程中它們的相似詞是怎麼變化的。
訓練模型:
在這裡注意一下,盡量不要經常去讓代碼列印驗證集相似的詞,因為這裡會多了一步計算步驟,就是計算相似度,會非常消耗計算資源,計算過程也很慢。所以代碼中我設置1000輪列印一次結果。
從最後的訓練結果來看,模型還是學到了一些常見詞的語義,比如one等計數詞以及gold之類的金屬詞,animals中的相似詞也相對準確。
為了能夠更全面地觀察我們訓練結果,我們採用sklearn中的TSNE來對高維詞向量進行可視化。詳見:http://t.cn/Rofvr7D
上面的圖中通過TSNE將高維的詞向量按照距離遠近顯示在二維坐標系中,該圖已經在git庫中,想看原圖的小夥伴去git看~
我們來看一下細節:
上面是顯示了整張大圖的局部區域,可以看到效果還不錯。
關於提升效果的技巧:
增大訓練樣本,語料庫越大,模型學習的可學習的信息會越多。
增加window size,可以獲得更多的上下文信息。
增加embedding size可以減少信息的維度損失,但也不宜過大,我一般常用的規模為50-300。
附錄:
git代碼中還提供了中文的詞向量計算代碼。同時提供了中文的一個訓練語料,語料是我從某招聘網站上爬取的招聘數據,做了分詞和去除停用詞的操作(可從git獲取),但語料規模太小,訓練效果並不好。
上面是我用模型訓練的中文數據,可以看到有一部分語義被挖掘出來,比如word和excel、office很接近,ppt和project、文字處理等,以及邏輯思維與語言表達等,但整體上效果還是很差。一方面是由於語料的規模太小(只有70兆的語料),另一方面是模型也沒有去調參。如果有興趣的同學可以自己試下會不會有更好的效果。
完整代碼請見:
http://t.cn/RofPq2p
雷鋒網相關閱讀:
不是你無法入門自然語言處理(NLP),而是你沒找到正確的打開方式
25 行 Python 代碼實現人臉檢測——OpenCV 技術教程
※吳恩達正式宣布創業,離職百度92天後成立Deeplearning.ai
※聲控技術競賽的戰鬥已然打響,聊天機器人如何將我們從屏幕上解放出來?
※極智嘉(Geek+)CEO鄭勇:智能物流和倉儲改變商業未來 | CCF-GAIR 2017
TAG:雷鋒網 |
※Classical CNN models:LeNet-5 模型結構詳解
※ProgrammerGuide8.7節Simulink模型可調參數
※LEGO 推出《The Hulkbuster: Ultron Edition》模型
※近賞 Ron English「Cheezy & Super Starfish」Grin 模型
※潮聞快食|G-SHOCK 攜手《Transformers》推出別注模型,nanamica x Dr. Martens即將上架。
※OpenStack-Neutron的資源模型
※Arvizio發布MR Studio 4.0,支持HoloLens、Magic Leap與點雲、攝影測量模型進行交互
※Tensorflow_08A_Keras 助攻下的 Sequential 模型
※Apache Storm流計算模型 及WordCount源碼實踐
※吳恩達《序列模型》精鍊筆記(2)-NLP和Word Embeddings
※從 Encoder到Decoder 實現 Seq2Seq 模型
※一致性模型之Sequential Consistency
※Facebook發布PyTorch 1.1,開源AI模型優化簡化工具BoTorch & Ax
※拍賓利R-type Continental模型
※Kaggle Carvana 圖像分割比賽冠軍模型 TernausNet 解讀
※Masterpiece Motion發布,加速簡化3D模型動畫Rigging
※Oracle開源GraphPipe:幾行代碼讓你在TensorFlow部署PyTorch模型
※LEGO 發布 James Bond? Aston Martin DB5 跑車積木模型
※Dahood 與 Kasing Lung 推出別注「DaZimomo」玩具模型
※坦克世界1.0版本Prototipo Standard B最終版模型圖賞