機器學習必須熟悉的演算法之word2vector(二)
查看更多的專業文章、課程信息、產品信息,請移步至:
「人工智慧LeadAI」公眾號;官網:www.leadai.org.
正文共2766個字,5張圖,預計閱讀時間7分鐘。
在上一篇文章中,我們簡述了skip gram版word2vector的基本原理,留下一個問題待解決,那就是網路非常大,這將導致如下幾個困難:1、在上面訓練梯度下降會比較慢;2、需要數量巨大的數據來喂到網路中;3、非常容易過擬合。這一節就是專門介紹實際訓練中的技巧的。原文在這裡:http://mccormickml.com/2017/01/11/word2vec-tutorial-part-2-negative-sampling/
當然,我不會生硬地翻譯這篇文章,而是按照自己的理解,儘可能用自己的邏輯將它寫出來,期望能夠比原文更加清晰一些。
總得來講,共有三個技巧,我們一個個看。
一、將片語和短語看做獨立的單詞
這個技巧的原理非常簡單。比如文本中有「中華人民共和國」,此時,按照機械的劃分,中華、人民、共和國應該是三個詞,但是顯然,中華人民共和國作為一個單獨的詞會更加合理一些。
如何從文本中發現片語和短語是一個專門的演算法,這裡略過了,因為超出了我們今天的主題。
二、對高頻詞進行
讓我們回顧一下上一節構造訓練數據單詞對的方法。
在上面的構建單詞對的過程中,對那些常見的詞,如「the」存在兩個問題:
1、類似(fox,the)這樣的單詞對並沒有什麼用,因為此處的th並沒有對理解fox產生什麼貢獻,它太普遍了,以至於在大多數單詞的周圍都可以發現它。此時,我們只能說the在fox 的周圍,卻不構成fox 的context。
2、上面的辦法會產生太多(the,...)樣式的單詞對,這對於學習單詞the的vector來說,實在是太多了。
解決這兩個問題的辦法就是subsampling,具體意思是:
當我們掃描文本中的詞時,會根據一定的概率刪除這個詞,也就是相當於文本中此處沒有了這個詞。這個概率大小取決於該詞在整個語料庫中的出現頻率。出現頻率越高,那麼我們刪除該詞的概率就越大。
這個很容易理解,以上面的the為例,由於它在整個語料庫中出現的頻率很高,我們就會刪除相當一部分的the,以便減少訓練量。
再具體一點,假設我們刪除了jump over the
lazy dog 中的the,我們的窗口大小是2,那麼,the與其前後各兩個片語成的詞對就不會稱為訓練數據,因為the已經被刪除了,其次,以the前後各兩個詞作為輸入的詞對中,都會減少一個(*,the)的詞對。
那麼,接下來一個問題就是如何確定刪除一個詞的概率?直接上公式:
P(wi)是保留單詞wi的概率,z(wi)是該詞在整個語料庫出現的比例。
我們可以將上面的公式畫成圖來看看:
Note:要得到這個圖,只需在google中輸入
Graph for (sqrt(x/0.001)+1)*0.001/x即可。
至於這個公式怎麼來的,說實話,我也不清楚,鑒於它不是本文的重點,我也沒有深究,如果有清楚的夥伴,歡迎留言補充。
三、負抽樣
這個辦法才是本文的重頭戲,其中的思想對人很有啟發性。剛剛聽完螞蟻金服張家興老師分享的螞蟻金服人工智慧實踐,裡面提到了問題匹配模型訓練中的一個技巧,其思想與負抽樣很相似。可見技術是具體的,但技術背後反映出的解決問題的思想卻是共通的。
負抽樣技術主要解決的問題就是模型難以訓練。所以,我們先來看看模型為什麼難以訓練。
使用SGD訓練神經網路的過程就是取出一條樣本數據,然後據此去調整神經網路的所有權重,以便網路能夠對這條數據的預測更加準確一些。這裡的重點是所有權重!
調整所有的權重是多大的工作量呢?在上篇文章中,我們已經有過解釋,請參考上篇文章。總之,所有權重是一個巨大數量的係數。對每一條樣本,每訓練一次,這麼多的係數都要進行輕微的調整。顯然,超多的訓練數據,巨多的權重係數,將使得神經網路的訓練非常緩慢和困難。
負抽樣解決這一問題的辦法就是使得對每一條樣本的每一次訓練,只更新很小一部分的權重,而不是全都更新。下面我們深入細節來看一下。
假設我們的訓練數據是(fox,quick)單詞對,回憶一下,此條訓練數據的標籤就是quick,用one-hot編碼後,就是一個8維向量,quick所對應的維度為1,其他維度為0。
也就是說,我們希望神經網路輸出的8維向量中,對應quick的維度是1,其他維度是0。在輸出層,每一個輸出維度實際上對應著一個神經元。
在我們的例子中,我們看到其他應當為0的維度有7個,在實際工作中,這個維度的數量是非常大的,因為我們的詞表一般會很大。
所謂負抽樣,即是從這些應當為0的維度中隨機抽取幾個,只更新這幾個維度對應的神經元的權重,這既是負抽樣的確切含義。當然,同時還要加上輸出應當為1的維度所對應的神經元。
具體負抽樣時抽幾個維度的神經元,取決於具體的問題,google的論文中建議是5到20個。
讓我們用一個例子來具體感受一下。假設我們負抽樣的維度數為5,我們的詞表中有10000個單詞,詞向量的維度為300,也即是隱藏層有300個神經元。
那麼,在輸出層,權重矩陣的大小將是300*10000。現在我們抽取了5個負的維度(輸出應當為0的維度),加上輸出為1的維度,只更新這6個維度所對應的神經元。那麼需要更新的權重係數是300*6=1800個。這隻占輸出層中所有權重係數的0.06%!!
另外,在隱藏層,我們還要更新輸入的單詞所對應的300個權重。這是無論用不用負抽樣,都要更新的權重。
如果不好理解,我們就具體一點,隱藏層可以看作一個10000*300的矩陣,其中每一行都代表一個單詞的300維詞向量,我們更新的就是輸入單詞所對應的那一行的300個權重係數。
四、負抽樣應當抽誰的樣?
上一節中,我們說了負抽樣,一般抽5到20 個維度。問題來了,假設是抽5個維度,那麼,應當抽哪5個維度呢?負的維度實在太多,如果詞表為10000,那麼負的維度就有9999個。從這裡面抽5個,難道是隨機抽嗎?
答案是否定的。在抽取這5個維度時,是按照單詞在語料庫中出現的次數多少來的, 出現次數越多,那麼越可能被抽中。具體是按照如下公式來決定的:
P(w_i)就是w_i這個單詞被負抽樣抽中的概率。
f(w_i)即是w_i在語料庫中出現的次數。
至於為什麼要取一次3/4次方,據說是基於經驗,這樣效果會更好。
五、無總結,不進步
通過這兩篇文章,我簡要地敘述了skip-gram版的word2vector的原理和部分實現細節。
我覺得最重要的在於體會作者設計這樣的神經網路,用n-gram來構造訓練數據背後所隱含的思想。這些思想才是我們在實際工作中最緊缺的。
這裡留一個問題供大家思考,在負抽樣時,為什麼要按照單詞出現的頻率來抽樣,這樣有什麼好處?
推薦閱讀:
※過擬合與正則化
※神經網路的理解
※關鍵詞提取Part1(A Quick Review)
※機器學習基石筆記15-16:小結和雜談
TAG:機器學習 |