Word2Vec 学习心得
本文沒什么干貨,主要是前后看了大概一個(gè)星期,反復(fù)去讀源碼和解讀文章,終于感覺這東西不那么云山霧罩了。同時(shí)也發(fā)現(xiàn)網(wǎng)上很多材料有點(diǎn)扯淡,99% 的博文不過是把別人的東西用自己的話說一下,人云亦云。好多人自己理解錯(cuò)了而不自知,實(shí)在是誤人誤己。
我也不敢說理解得有多深,下面的內(nèi)容甚至可能有自相矛盾的地方,所以閱讀本文時(shí)請一定擦亮眼睛,認(rèn)真思考。
源碼才是根本,作者那兩篇論文感覺參考價(jià)值也不高。說到底,Machine Learning/Deep Learning 的價(jià)值在于實(shí)踐,而實(shí)際開發(fā)的應(yīng)用中經(jīng)過大量的 tricks 之后,代碼跟論文推導(dǎo)、實(shí)驗(yàn)可能相去甚遠(yuǎn)。
Data Mining 是一門實(shí)驗(yàn)科學(xué),編程實(shí)現(xiàn)、實(shí)驗(yàn)所用的數(shù)據(jù)集都可能對假設(shè)和結(jié)論產(chǎn)生無法預(yù)知的影響,希望各位時(shí)刻牢記。
0 一段前言
個(gè)人覺得學(xué) Word2Vec 有幾種路徑。如果你代碼能力足夠,建議直接讀作者的原始論文和 Rong Xin 的解釋篇,然后找一些比較高質(zhì)量的源碼解析作為輔助,這樣效率比較高。如果不行,那就得多讀一些東西,比如來斯為的博文和博士論文、網(wǎng)上中文的英文的詳解博客,建立一組整體概念,然后對照源碼來看。
前者的典型見: http://www.cnblogs.com/neopenx/p/4571996.html
后者的典型是皮果提的“Word2Vec 數(shù)學(xué)原理”系列。正如前者所說,數(shù)學(xué)熟練如皮果提也在理解 Skip-Gram 時(shí)犯了先入為主的錯(cuò)誤;而強(qiáng)如 Physcal 也會(huì)一時(shí)疏忽把 Huffman 樹記成了滿二叉樹。
所以再三強(qiáng)調(diào),要批判地看本文和網(wǎng)上一切的解讀文章。感慨一下,我因?yàn)檫@個(gè)東西看了不下三十篇中文的英文的博文,皮果提的“數(shù)學(xué)原理”頗有夸大其詞之嫌,但已經(jīng)算是相當(dāng)有深度的,像其他一些所謂解讀不過是把論文的圖復(fù)制過來然后用自己的理解隨便說兩句,所以你能看到大量相關(guān)博文介紹 CBOW、Skip-Gram 倆模型但往往淺嘗輒止。
理解到 Physcal 博文即 http://www.cnblogs.com/neopenx/p/4571996.html 這篇程度的人恐怕不足千分之一,包括但不限于皮果提、網(wǎng)易的w2v筆記和國外一些看起來很好看的博文。大多數(shù)人只是簡單看了一下論文,好一點(diǎn)兒的如來斯為的博文和博士論文,也只是做了發(fā)展梳理和一些后續(xù)實(shí)驗(yàn),感覺并沒有結(jié)合代碼本身對論文的提法做一些重構(gòu)。
那篇“秒懂詞向量”的文章也不過是剛?cè)腴T的程度,感覺比我強(qiáng)不到哪兒去……
對了,蘇劍林的科學(xué)空間建議看一下,我覺得這位在 NLP 方面的理解也很厲害,可能跟數(shù)學(xué)出身有關(guān)吧。
本文將根據(jù)自己的理解,把 Word2Vec 這款開源工具做一點(diǎn)梳理,可能更適合厘清一些誤解而不適合新手入門。有需要可以參考上面的說明自己找資料學(xué)習(xí),文中不會(huì)過多解釋。
1 幾個(gè)概念
1.1 Word2Vec
Word2Vec 是 Google 開源的一款詞向量訓(xùn)練工具,特點(diǎn)是效率高,據(jù)稱可"單機(jī)在一天內(nèi)訓(xùn)練完一個(gè)包含 16 億單詞的訓(xùn)練集”。它是對以往的 NNLM 的改進(jìn),相關(guān)內(nèi)容可參考來斯為的博客和博士論文,介紹比較詳細(xì)。
但 Word2Vec 并不是最佳的詞向量訓(xùn)練工具,它流行的原因是 Google 光環(huán)加成和相對高效。更新的 FastText 速度更快,而且論文也有去了 FB 的 Mikolov 掛名。
實(shí)際上就“詞的分布式表示(DR)”問題有三類模型,據(jù)來斯為的博士論文,包括:
- 基于矩陣的DR,包括 tf-idf based LSA,GloVe 等
- 基于聚類的DR,如布朗聚類
- 基于NN的DR即 Word Vector,可以對上下文、上下文與目標(biāo)詞關(guān)系進(jìn)行建模
“分布表示(distributional representation)”意為“通過上下文表示語義”。根據(jù)實(shí)驗(yàn),三類模型之間不存在誰好誰壞,參數(shù)不同、語料不同時(shí)表現(xiàn)(“精確程度”的各類衡量指標(biāo)和訓(xùn)練速度)相差很大。而且三類模型之間存在一定的聯(lián)系,如來斯為證明了 Skip-gram + Negtive Sampling 與 Glove 的等價(jià)性。可以說不同的算法更多是對不同的指標(biāo)的權(quán)衡,應(yīng)當(dāng)根據(jù)實(shí)際情況選擇合適的方案。希望讀者不要忘記這一點(diǎn)。
1.2 CBOW & Skip-gram
完整的 NNLM 最早由 Bengio(2003) 提出,可以看作四層網(wǎng)絡(luò)。由于隱藏層有非線性、輸出層是 Softmax (輸出到詞表大小),計(jì)算量非常大。
Mikolov 提出的 CBOW 、 Skip-Gram 兩個(gè)模型,是對過去 NNLM 的大幅簡化,除輸出仍為 Softmax 外,只有一層線性連接。Hierarchical Softmax 和 Negative Sampling 則是進(jìn)一步加速訓(xùn)練的方法。總之 Mikolov 取勝的最主要因素就是訓(xùn)練速度,在給出過得去的準(zhǔn)確度的情況下使用很多激進(jìn)方法加速。這方面網(wǎng)上也有很多對比,不再贅述。
另外參見 Physcal 的文章,Skip-Gram 不是 CBOW 的對稱模型,而是一個(gè)精度更高的版本。“CBOW 是上下文預(yù)測當(dāng)前詞、Skip-Gram 是當(dāng)前詞預(yù)測上下文”的說法并不準(zhǔn)確,只是一種曖昧的形容而非實(shí)事。作為專業(yè)人士要盡量避免“用簡單形容來概括復(fù)雜操作/概念”的嘗試,用來向外行人解釋或者加強(qiáng)自己的記憶尚可,當(dāng)了真就不對。想知道真實(shí)情況,應(yīng)該去讀源碼。
來斯為的博士論文里提了一句大意是“實(shí)際上兩個(gè)模型都是根據(jù)上下文預(yù)測當(dāng)前詞”,只不過他的解釋是“兩種模型都要遍歷全文”,我也沒看懂到底哪個(gè)解釋更高明些……
word2vec.c 中,CBOW 是 422-482 行,SG 是 482-530 行。
可以看到,CBOW 是先在一個(gè)窗口內(nèi)把 C o n t e x t ( w ) Context(w) Context(w) 算完(求和-平均)做 FF 、BP,更新窗口詞的參數(shù),而 Skip-Gram 在窗口內(nèi)則是逐個(gè)更新【目標(biāo)詞和窗口中某個(gè)詞】組成的詞對,每個(gè)詞對更新一次參數(shù)。兩段代碼對比著看會(huì)更明顯。
也就是說, CBOW 的 FF 和 BP 都是一把梭,窗口里的詞算完 FF 再算 BP;而 Skip-Gram 更小心,一個(gè)【詞對】算一次 FF 和 BP。這就是 SG 比 CBOW 要慢得多得多的原因。效果如何呢?網(wǎng)上一般的黑盒經(jīng)驗(yàn)就是所謂大語料用 CBOW,小語料用 SG 或者 CBOW 對高頻詞友好、 SG 對低頻詞友好了。說白了還是數(shù)據(jù)說話,試了才知道。
我覺得更合適的類比是,和兩個(gè)模型代表兩種訓(xùn)練方法:CBOW 像 mini-batch,SG 像 online。這樣精度更高的含義好像就不難理解了吧?
Negative Sampling、Hierarchical Softmax 兩種模式的計(jì)算量看起來差不多,但由于 HS 采用了 Huffman 編碼,高頻詞路徑更短,所以對一般語料(大量高頻詞)的訓(xùn)練速度會(huì)更快一些。
再用 Physcal 的話解釋一遍:CBOW 直接把上下文平均輸入進(jìn)去更新目標(biāo)詞,相當(dāng)于把幾個(gè)詞看成了一個(gè)詞;而 Skip-Gram 仍然以詞對的形式將窗口內(nèi)的詞逐個(gè)更新。
所以,雖然 Mikolov 論文里畫的圖是對稱的,兩個(gè)模型實(shí)際并非鏡像。Skip-gram 的圖畫成 1 對 n 是結(jié)果的一種呈現(xiàn)而不是計(jì)算過程的說明。
1.3 詞向量 & 詞嵌入
本條參考 Wikipedia。“詞嵌入是NLP中語言模型和表征技術(shù)的統(tǒng)稱,概念上它是把一個(gè)維數(shù)為詞庫大小的高維空間嵌入維數(shù)較低的連續(xù)向量空間中,每個(gè)單詞或詞組被映射為實(shí)數(shù)域上的向量。” Word2Vec 是詞嵌入技術(shù)的一種。
而詞向量是詞或詞組在向量空間中的具體表示形式。
NNLM 通常可以看成三層網(wǎng)絡(luò):input-hidden/projection-output。Input 層填入詞的 one-hot 表示,hidden/projection 層最初是 tanh 函數(shù)、Word2Vec 中簡化為線性運(yùn)算,output 層沒爭議,就是 Softmax 輸出到詞表。
通常,在語料上訓(xùn)練得到 NNLM 后,input-projection 層的權(quán)重作為 DNN 的 embedding layer 使用。此時(shí)輸入的依然是 one-hot 。
考慮 one-hot 的運(yùn)算特性不難看出,(根據(jù)表示方法不同)每個(gè)詞對應(yīng)的“詞向量”就是權(quán)重矩陣/ embedding layer 相應(yīng)行/列的參數(shù)向量。
2 兩條錯(cuò)誤
前面說到,網(wǎng)上很多資料是有問題的。第一個(gè)錯(cuò)誤在上文中已經(jīng)指出,第二個(gè)錯(cuò)誤與 one-hot 表示有關(guān)。這一點(diǎn)由蘇劍林(https://spaces.ac.cn/archives/4122)指出。
很多資料指出/復(fù)制他人的觀點(diǎn)認(rèn)為 one-hot 的原罪在于其巨大二值稀疏矩陣效率低下。這種說法是有問題的。比如上文中蘇劍林說的,詞向量并沒有提升計(jì)算效率,輸入仍為 one-hot 形式,但多了嵌入層之后 one-hot 通過查表操作把長長的 0-1 表示變換到緊密的實(shí)數(shù)域向量上去了。
但蘇劍林其實(shí)說的也不全對。另一半答案可以看這篇博客,依然是 Physcal 的:http://www.cnblogs.com/neopenx/p/4570648.html
推薦本文讀者多讀幾遍 Physcal 的兩篇博文,作者的理解層次還是挺高的。
問題:維度過高
通常一個(gè)詞庫的大小是105,如果繼續(xù)用二進(jìn)制編碼。那么一個(gè)句子的維度是105。
要知道,AlexNet的一張圖片維度才256*256=65536, 就得拿GPU算好久,10^5基本得完蛋了。
實(shí)際上,10^5里,大部分都是維度都是廢的,真正有用的特征就藏在那么幾個(gè)維度中。
這說明,One-hot Representation表達(dá)的特征維度過高,需要降維。然而,這還不是最坑爹的缺陷。
Bengio在2003年的A neural probabilistic language model中指出,維度過高,導(dǎo)致每次學(xué)習(xí),都會(huì)強(qiáng)制改變大部分參數(shù)。
由此發(fā)生蝴蝶效應(yīng),本來很好的參數(shù),可能就因?yàn)橐粋€(gè)小小傳播誤差,就改的亂七八糟。
實(shí)際上,傳統(tǒng)MLP網(wǎng)絡(luò)就是犯了這個(gè)錯(cuò)誤,1D全連接的神經(jīng)元控制了太多參數(shù),不利于學(xué)習(xí)到稀疏特征。
CNN網(wǎng)絡(luò),2D全連接的神經(jīng)元?jiǎng)t控制了局部感受野,有利于解離出稀疏特征。
1.3中已經(jīng)提過,在深度學(xué)習(xí) NLP 任務(wù)中,文本依然以 one-hot 的形式輸入網(wǎng)絡(luò)。
解釋得很清楚了。
one-hot 表示可以看作最粗糙但無損失的詞表示方法,它的缺點(diǎn)并不是稀疏,而是無法表達(dá)詞與詞之間的關(guān)系,即所謂語義鴻溝。在大規(guī)模語料上訓(xùn)練 NNLM,可以利用 NN 學(xué)習(xí)到語料給出的語義信息、詞間關(guān)系,從而克服實(shí)踐中 one-hot 的缺點(diǎn)。
前兩天跟同學(xué)聊天也提到了這個(gè)事情。NNLM 僅僅是詞嵌入的一種工具,在實(shí)踐中不見得哪都有效。他們在做的事情就是想辦法用 CNN +貝葉斯直接在 one-hot 上訓(xùn)練網(wǎng)絡(luò)。據(jù)說騰訊 AI 的 Boss 張潼之前做過這個(gè)工作。但根據(jù)上面的說法我對這種思路表示懷疑……
3 一點(diǎn)想法
3.1 學(xué)習(xí)體會(huì)
看皮果提的博文可以發(fā)現(xiàn),雖然論文里基本沒有理論的證明推導(dǎo),但訓(xùn)練網(wǎng)絡(luò)實(shí)際需要很多計(jì)算,數(shù)學(xué)都在 Hierarchical Softmax 和 Negative Sampling 的 BP 上了。想知道的話可以看他的博文和 Rong Xin 的 Word2Vec 參數(shù)解釋,步驟詳盡。
源碼的編程技巧也不是我能講的,事實(shí)上理解以上內(nèi)容就已經(jīng)十分吃力了。什么內(nèi)存對齊、Huffman 樹構(gòu)建,完全搞不定。
Word2Vec 不是一切,雖然它幾乎可以稱為標(biāo)配——速度快、省內(nèi)存。此外 GloVe 和 FastText 也各有長短,后者同樣以速度著稱。
就 DR 這個(gè)問題來說,很多人認(rèn)為一個(gè)最大的難點(diǎn)在于如何衡量詞表示的好壞。對不同任務(wù)和數(shù)據(jù)集來說,各方法的結(jié)果表現(xiàn)差別很大,這里面水就深了。
有人好奇 Word2Vec 有沒有其他實(shí)現(xiàn)版本。有。Tensorflow 官方有一個(gè),但據(jù)說效率比 C 版差;Gensim 有一個(gè)基于 Python 的實(shí)現(xiàn),用了 Cython + BLAS 加速,號(hào)稱遠(yuǎn)超原版,但據(jù)說出來的結(jié)果跟原版不一樣;國內(nèi)有大佬搞了 HanLP,并加入了自己的 Java 實(shí)現(xiàn),據(jù)說比原版快一倍但精度稍差(http://www.hankcs.com/nlp/word2vec.html)。
最后,有問題去讀源碼、讀源碼、讀源碼。
要說三。
3.2 word2vec 的缺陷(update)
上面說過,word2vec 通過精簡原 NNLM 中的非線性提升效率,得到的結(jié)果非常不錯(cuò),所謂的
v e c ( k i n g ) ? v e c ( m a n ) + v e c ( w o m a n ) ≈ v e c ( q u e e n ) vec(king) - vec(man) + vec(woman) \approx vec(queen) vec(king)?vec(man)+vec(woman)≈vec(queen)
說明訓(xùn)練出的 wordvec 之間竟然具有類似線性的關(guān)系。這是之前沒有想到的。
通過大量類似的簡化,Word2Vec 在保證還不錯(cuò)的準(zhǔn)確度的前提下,具備了極高的效率。但問題也隨之而來,簡化是有代價(jià)的。Bengio 模型中,輸入是窗口詞拼接而來的,保留了先后次序,而 CBOW 和 Skip-Gram 對窗口內(nèi)的詞一視同仁,也就忽略了它們之間的次序關(guān)系。
另外,NNLM 本質(zhì)是利用神經(jīng)網(wǎng)絡(luò)去搜索和記憶數(shù)據(jù)中的有效統(tǒng)計(jì)信息。比如 https://zhuanlan.zhihu.com/p/29364112 文提到的微博語料訓(xùn)練出的有害詞模型,輸入“垃圾”,與之相關(guān)度最高的依次是:
辣雞
拉圾
臘雞
狗屎
廢物
渣子
sb
…
表明這些詞在原文中與“垃圾”的距離最近(在前在后),或者具有相近的含義。但這里的“含義”并不表示模型理解語義,而只是在訓(xùn)練中發(fā)現(xiàn)這些詞在語句中是可以互相替換的——罵人的時(shí)候有用“垃圾”的,有用“辣雞”的。這兩點(diǎn)上文均有提及:相似的句子,相似位置/成分的詞更接近;實(shí)際距離更近的詞更接近。
這樣的結(jié)果也是由網(wǎng)絡(luò)的訓(xùn)練過程決定的。
總結(jié)
以上是生活随笔為你收集整理的Word2Vec 学习心得的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis学习之Redis概述与安装以及
- 下一篇: 区块链共识算法简介