理解 Word2Vec 之 Skip-Gram 模型
20211003
NLP系列:Word2Vec原始論文:Efficient Estimation of Word Representations in Vector Space - 簡(jiǎn)書(shū)
原始論文翻譯
視頻回憶
20210401
NLP之---word2vec算法skip-gram原理詳解_Ricky-CSDN博客_skipgram
Word2vec之Skip-gram理解_以python追時(shí)間的博客-CSDN博客
總結(jié)在這里
Word2Vec的參數(shù)解釋_小白_努力-CSDN博客_word2vec參數(shù)
word2vec 參數(shù)
1.什么是Skip-gram算法
Skip-gram算法就是在給出目標(biāo)單詞(中心單詞)的情況下,預(yù)測(cè)它的上下文單詞(除中心單詞外窗口內(nèi)的其他單詞,這里的窗口大小是2,也就是左右各兩個(gè)單詞)。
以下圖為例:
、?
2.目標(biāo)是什么
理解了Skip-gram算法的定義,我們很容易得出:我們的目標(biāo)是計(jì)算在給定單詞的條件下,其他單詞出現(xiàn)的概率!
問(wèn)題來(lái)了,在實(shí)踐中,怎么計(jì)算這個(gè)概率?
接下來(lái)讓我們一步一步理解這個(gè)過(guò)程,首先從定義表示法開(kāi)始。
還是以我們的例句"Do you love deep learning"為例。
love的one-hot向量就是:
第三步:求softmax
這步比較簡(jiǎn)單,把得到的相似度矩陣代入softmax公式,就得到了一個(gè)滿足概率分布的矩陣。
至此,我們的目標(biāo)已經(jīng)實(shí)現(xiàn):得到了一個(gè)向量。
向量中的數(shù)值代表在給定單詞的條件下,其他單詞出現(xiàn)的概率!大功告成!
理解 Word2Vec 之 Skip-Gram 模型
這次的分享主要是對(duì)Word2Vec模型的兩篇英文文檔的翻譯、理解和整合,這兩篇英文文檔都是介紹Word2Vec中的Skip-Gram模型。下一篇專欄文章將會(huì)用TensorFlow實(shí)現(xiàn)基礎(chǔ)版Word2Vec的skip-gram模型,所以本篇文章先做一個(gè)理論鋪墊。
原文英文文檔請(qǐng)參考鏈接:
-?Word2Vec Tutorial - The Skip-Gram Model
-?Word2Vec (Part 1): NLP With Deep Learning with Tensorflow (Skip-gram)
什么是Word2Vec和Embeddings?
Word2Vec是從大量文本語(yǔ)料中以無(wú)監(jiān)督的方式學(xué)習(xí)語(yǔ)義知識(shí)的一種模型,它被大量地用在自然語(yǔ)言處理(NLP)中。那么它是如何幫助我們做自然語(yǔ)言處理呢?Word2Vec其實(shí)就是通過(guò)學(xué)習(xí)文本來(lái)用詞向量的方式表征詞的語(yǔ)義信息,即通過(guò)一個(gè)嵌入空間使得語(yǔ)義上相似的單詞在該空間內(nèi)距離很近。Embedding其實(shí)就是一個(gè)映射,將單詞從原先所屬的空間映射到新的多維空間中,也就是把原先詞所在空間嵌入到一個(gè)新的空間中去。我們從直觀角度上來(lái)理解一下,cat這個(gè)單詞和kitten屬于語(yǔ)義上很相近的詞,而dog和kitten則不是那么相近,iphone這個(gè)單詞和kitten的語(yǔ)義就差的更遠(yuǎn)了。通過(guò)對(duì)詞匯表中單詞進(jìn)行這種數(shù)值表示方式的學(xué)習(xí)(也就是將單詞轉(zhuǎn)換為詞向量),能夠讓我們基于這樣的數(shù)值進(jìn)行向量化的操作從而得到一些有趣的結(jié)論。比如說(shuō),如果我們對(duì)詞向量kitten、cat以及dog執(zhí)行這樣的操作:kitten - cat + dog,那么最終得到的嵌入向量(embedded vector)將與puppy這個(gè)詞向量十分相近。
第一部分
模型
Word2Vec模型中,主要有Skip-Gram和CBOW兩種模型,從直觀上理解,Skip-Gram是給定input word來(lái)預(yù)測(cè)上下文。而CBOW是給定上下文,來(lái)預(yù)測(cè)input word。本篇文章僅講解Skip-Gram模型。
Skip-Gram模型的基礎(chǔ)形式非常簡(jiǎn)單,為了更清楚地解釋模型,我們先從最一般的基礎(chǔ)模型來(lái)看Word2Vec(下文中所有的Word2Vec都是指Skip-Gram模型)。
Word2Vec模型實(shí)際上分為了兩個(gè)部分,第一部分為建立模型,第二部分是通過(guò)模型獲取嵌入詞向量。Word2Vec的整個(gè)建模過(guò)程實(shí)際上與自編碼器(auto-encoder)的思想很相似,即先基于訓(xùn)練數(shù)據(jù)構(gòu)建一個(gè)神經(jīng)網(wǎng)絡(luò),當(dāng)這個(gè)模型訓(xùn)練好以后,我們并不會(huì)用這個(gè)訓(xùn)練好的模型處理新的任務(wù),我們真正需要的是這個(gè)模型通過(guò)訓(xùn)練數(shù)據(jù)所學(xué)得的參數(shù),例如隱層的權(quán)重矩陣——后面我們將會(huì)看到這些權(quán)重在Word2Vec中實(shí)際上就是我們?cè)噲D去學(xué)習(xí)的“word vectors”?;谟?xùn)練數(shù)據(jù)建模的過(guò)程,我們給它一個(gè)名字叫“Fake Task”,意味著建模并不是我們最終的目的。
上面提到的這種方法實(shí)際上會(huì)在無(wú)監(jiān)督特征學(xué)習(xí)(unsupervised feature learning)中見(jiàn)到,最常見(jiàn)的就是自編碼器(auto-encoder):通過(guò)在隱層將輸入進(jìn)行編碼壓縮,繼而在輸出層將數(shù)據(jù)解碼恢復(fù)初始狀態(tài),訓(xùn)練完成后,我們會(huì)將輸出層“砍掉”,僅保留隱層。
The Fake Task
我們?cè)谏厦嫣岬?#xff0c;訓(xùn)練模型的真正目的是獲得模型基于訓(xùn)練數(shù)據(jù)學(xué)得的隱層權(quán)重。為了得到這些權(quán)重,我們首先要構(gòu)建一個(gè)完整的神經(jīng)網(wǎng)絡(luò)作為我們的“Fake Task”,后面再返回來(lái)看通過(guò)“Fake Task”我們?nèi)绾伍g接地得到這些詞向量。
接下來(lái)我們來(lái)看看如何訓(xùn)練我們的神經(jīng)網(wǎng)絡(luò)。假如我們有一個(gè)句子“The dog barked at the mailman”。
我們的模型將會(huì)從每對(duì)單詞出現(xiàn)的次數(shù)中習(xí)得統(tǒng)計(jì)結(jié)果。例如,我們的神經(jīng)網(wǎng)絡(luò)可能會(huì)得到更多類似(“Soviet“,”Union“)這樣的訓(xùn)練樣本對(duì),而對(duì)于(”Soviet“,”Sasquatch“)這樣的組合卻看到的很少。因此,當(dāng)我們的模型完成訓(xùn)練后,給定一個(gè)單詞”Soviet“作為輸入,輸出的結(jié)果中”Union“或者”Russia“要比”Sasquatch“被賦予更高的概率。
模型細(xì)節(jié)
我們?nèi)绾蝸?lái)表示這些單詞呢?
首先,我們都知道神經(jīng)網(wǎng)絡(luò)只能接受數(shù)值輸入,我們不可能把一個(gè)單詞字符串作為輸入,因此我們得想個(gè)辦法來(lái)表示這些單詞。最常用的辦法就是基于訓(xùn)練文檔來(lái)構(gòu)建我們自己的詞匯表(vocabulary)再對(duì)單詞進(jìn)行one-hot編碼。
還是上面的例子,“The dog barked at the mailman”,那么我們基于這個(gè)句子,可以構(gòu)建一個(gè)大小為5的詞匯表(忽略大小寫和標(biāo)點(diǎn)符號(hào)):("the", "dog", "barked", "at", "mailman"),我們對(duì)這個(gè)詞匯表的單詞進(jìn)行編號(hào)0-4。那么”dog“就可以被表示為一個(gè)5維向量[0, 1, 0, 0, 0]。
模型的輸入如果為一個(gè)10000維的向量,那么輸出也是一個(gè)10000維度(詞匯表的大小)的向量,它包含了10000個(gè)概率,每一個(gè)概率代表著當(dāng)前詞是輸入樣本中output word的概率大小。
下圖是我們神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu):
我們基于成對(duì)的單詞來(lái)對(duì)神經(jīng)網(wǎng)絡(luò)進(jìn)行訓(xùn)練,訓(xùn)練樣本是 ( input word, output word ) 這樣的單詞對(duì),input word和output word都是one-hot編碼的向量。最終模型的輸出是一個(gè)概率分布。
隱層
說(shuō)完單詞的編碼和訓(xùn)練樣本的選取,我們來(lái)看下我們的隱層。如果我們現(xiàn)在想用300個(gè)特征來(lái)表示一個(gè)單詞(即每個(gè)詞可以被表示為300維的向量)。那么隱層的權(quán)重矩陣應(yīng)該為10000行,300列(隱層有300個(gè)結(jié)點(diǎn))。
Google在最新發(fā)布的基于Google news數(shù)據(jù)集訓(xùn)練的模型中使用的就是300個(gè)特征的詞向量。詞向量的維度是一個(gè)可以調(diào)節(jié)的超參數(shù)(在Python的gensim包中封裝的Word2Vec接口默認(rèn)的詞向量大小為100, window_size為5)。
看下面的圖片,左右兩張圖分別從不同角度代表了輸入層-隱層的權(quán)重矩陣。左圖中每一列代表一個(gè)10000維的詞向量和隱層單個(gè)神經(jīng)元連接的權(quán)重向量。從右邊的圖來(lái)看,每一行實(shí)際上代表了每個(gè)單詞的詞向量。
所以我們最終的目標(biāo)就是學(xué)習(xí)這個(gè)隱層的權(quán)重矩陣。
我們現(xiàn)在回來(lái)接著通過(guò)模型的定義來(lái)訓(xùn)練我們的這個(gè)模型。
上面我們提到,input word和output word都會(huì)被我們進(jìn)行one-hot編碼。仔細(xì)想一下,我們的輸入被one-hot編碼以后大多數(shù)維度上都是0(實(shí)際上僅有一個(gè)位置為1),所以這個(gè)向量相當(dāng)稀疏,那么會(huì)造成什么結(jié)果呢。如果我們將一個(gè)1 x 10000的向量和10000 x 300的矩陣相乘,它會(huì)消耗相當(dāng)大的計(jì)算資源,為了高效計(jì)算,它僅僅會(huì)選擇矩陣中對(duì)應(yīng)的向量中維度值為1的索引行(這句話很繞),看圖就明白。
?
為了有效地進(jìn)行計(jì)算,這種稀疏狀態(tài)下不會(huì)進(jìn)行矩陣乘法計(jì)算,可以看到矩陣的計(jì)算的結(jié)果實(shí)際上是矩陣對(duì)應(yīng)的向量中值為1的索引,上面的例子中,左邊向量中取值為1的對(duì)應(yīng)維度為3(下標(biāo)從0開(kāi)始),那么計(jì)算結(jié)果就是矩陣的第3行(下標(biāo)從0開(kāi)始)—— [10, 12, 19],這樣模型中的隱層權(quán)重矩陣便成了一個(gè)”查找表“(lookup table),進(jìn)行矩陣計(jì)算時(shí),直接去查輸入向量中取值為1的維度下對(duì)應(yīng)的那些權(quán)重值。隱層的輸出就是每個(gè)輸入單詞的“嵌入詞向量”。
輸出層
經(jīng)過(guò)神經(jīng)網(wǎng)絡(luò)隱層的計(jì)算,ants這個(gè)詞會(huì)從一個(gè)1 x 10000的向量變成1 x 300的向量,再被輸入到輸出層。輸出層是一個(gè)softmax回歸分類器,它的每個(gè)結(jié)點(diǎn)將會(huì)輸出一個(gè)0-1之間的值(概率),這些所有輸出層神經(jīng)元結(jié)點(diǎn)的概率之和為1。
下面是一個(gè)例子,訓(xùn)練樣本為 (input word: “ants”, output word: “car”) 的計(jì)算示意圖。
直覺(jué)上的理解
下面我們將通過(guò)直覺(jué)來(lái)進(jìn)行一些思考。
如果兩個(gè)不同的單詞有著非常相似的“上下文”(也就是窗口單詞很相似,比如“Kitty climbed the tree”和“Cat climbed the tree”),那么通過(guò)我們的模型訓(xùn)練,這兩個(gè)單詞的嵌入向量將非常相似。
那么兩個(gè)單詞擁有相似的“上下文”到底是什么含義呢?比如對(duì)于同義詞“intelligent”和“smart”,我們覺(jué)得這兩個(gè)單詞應(yīng)該擁有相同的“上下文”。而例如”engine“和”transmission“這樣相關(guān)的詞語(yǔ),可能也擁有著相似的上下文。
實(shí)際上,這種方法實(shí)際上也可以幫助你進(jìn)行詞干化(stemming),例如,神經(jīng)網(wǎng)絡(luò)對(duì)”ant“和”ants”兩個(gè)單詞會(huì)習(xí)得相似的詞向量。
詞干化(stemming)就是去除詞綴得到詞根的過(guò)程。
---第一部分與第二部分分割線---
第二部分
第一部分我們了解skip-gram的輸入層、隱層、輸出層。在第二部分,會(huì)繼續(xù)深入講如何在skip-gram模型上進(jìn)行高效的訓(xùn)練。
在第一部分講解完成后,我們會(huì)發(fā)現(xiàn)Word2Vec模型是一個(gè)超級(jí)大的神經(jīng)網(wǎng)絡(luò)(權(quán)重矩陣規(guī)模非常大)。
舉個(gè)栗子,我們擁有10000個(gè)單詞的詞匯表,我們?nèi)绻肭度?00維的詞向量,那么我們的輸入-隱層權(quán)重矩陣和隱層-輸出層的權(quán)重矩陣都會(huì)有 10000 x 300 = 300萬(wàn)個(gè)權(quán)重,在如此龐大的神經(jīng)網(wǎng)絡(luò)中進(jìn)行梯度下降是相當(dāng)慢的。更糟糕的是,你需要大量的訓(xùn)練數(shù)據(jù)來(lái)調(diào)整這些權(quán)重并且避免過(guò)擬合。百萬(wàn)數(shù)量級(jí)的權(quán)重矩陣和億萬(wàn)數(shù)量級(jí)的訓(xùn)練樣本意味著訓(xùn)練這個(gè)模型將會(huì)是個(gè)災(zāi)難(太兇殘了)。
Word2Vec的作者在它的第二篇論文中強(qiáng)調(diào)了這些問(wèn)題,下面是作者在第二篇論文中的三個(gè)創(chuàng)新:
- 將常見(jiàn)的單詞組合(word pairs)或者詞組作為單個(gè)“words”來(lái)處理。
- 對(duì)高頻次單詞進(jìn)行抽樣來(lái)減少訓(xùn)練樣本的個(gè)數(shù)。
- 對(duì)優(yōu)化目標(biāo)采用“negative sampling”方法,這樣每個(gè)訓(xùn)練樣本的訓(xùn)練只會(huì)更新一小部分的模型權(quán)重,從而降低計(jì)算負(fù)擔(dān)。
Word pairs and "phases"
論文的作者指出,一些單詞組合(或者詞組)的含義和拆開(kāi)以后具有完全不同的意義。比如“Boston Globe”是一種報(bào)刊的名字,而單獨(dú)的“Boston”和“Globe”這樣單個(gè)的單詞卻表達(dá)不出這樣的含義。因此,在文章中只要出現(xiàn)“Boston Globe”,我們就應(yīng)該把它作為一個(gè)單獨(dú)的詞來(lái)生成其詞向量,而不是將其拆開(kāi)。同樣的例子還有“New York”,“United Stated”等。
在Google發(fā)布的模型中,它本身的訓(xùn)練樣本中有來(lái)自Google News數(shù)據(jù)集中的1000億的單詞,但是除了單個(gè)單詞以外,單詞組合(或詞組)又有3百萬(wàn)之多。
如果你對(duì)模型的詞匯表感興趣,可以點(diǎn)擊這里,你還可以直接瀏覽這個(gè)詞匯表。
如果想了解這個(gè)模型如何進(jìn)行文檔中的詞組抽取,可以看論文中“Learning Phrases”這一章,對(duì)應(yīng)的代碼word2phrase.c被發(fā)布在這里。
對(duì)高頻詞抽樣
在第一部分的講解中,我們展示了訓(xùn)練樣本是如何從原始文檔中生成出來(lái)的,這里我再重復(fù)一次。我們的原始文本為“The quick brown fox jumps over the laze dog”,如果我使用大小為2的窗口,那么我們可以得到圖中展示的那些訓(xùn)練樣本。
但是對(duì)于“the”這種常用高頻單詞,這樣的處理方式會(huì)存在下面兩個(gè)問(wèn)題:
- 當(dāng)我們得到成對(duì)的單詞訓(xùn)練樣本時(shí),("fox", "the") 這樣的訓(xùn)練樣本并不會(huì)給我們提供關(guān)于“fox”更多的語(yǔ)義信息,因?yàn)椤皌he”在每個(gè)單詞的上下文中幾乎都會(huì)出現(xiàn)。
- 由于在文本中“the”這樣的常用詞出現(xiàn)概率很大,因此我們將會(huì)有大量的(”the“,...)這樣的訓(xùn)練樣本,而這些樣本數(shù)量遠(yuǎn)遠(yuǎn)超過(guò)了我們學(xué)習(xí)“the”這個(gè)詞向量所需的訓(xùn)練樣本數(shù)。
?
這句話應(yīng)該這么理解,假如我們的文本中僅出現(xiàn)了一個(gè)“the”,那么當(dāng)這個(gè)“the”作為input word時(shí),我們?cè)O(shè)置span=10,此時(shí)會(huì)得到10個(gè)訓(xùn)練樣本 ("the", ...) ,如果刪掉這個(gè)“the”,我們就會(huì)減少10個(gè)訓(xùn)練樣本。實(shí)際中我們的文本中不止一個(gè)“the”,因此當(dāng)“the”作為input word的時(shí)候,至少會(huì)減少10個(gè)訓(xùn)練樣本。
上面提到的這兩個(gè)影響結(jié)果實(shí)際上就幫助我們解決了高頻詞帶來(lái)的問(wèn)題。
抽樣率
如果你去看那篇論文的話,你會(huì)發(fā)現(xiàn)作者在論文中對(duì)函數(shù)公式的定義和在C語(yǔ)言代碼的實(shí)現(xiàn)上有一些差別,但我認(rèn)為C語(yǔ)言代碼的公式實(shí)現(xiàn)是更權(quán)威的一個(gè)版本。?
負(fù)采樣(negative sampling)
訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)意味著要輸入訓(xùn)練樣本并且不斷調(diào)整神經(jīng)元的權(quán)重,從而不斷提高對(duì)目標(biāo)的準(zhǔn)確預(yù)測(cè)。每當(dāng)神經(jīng)網(wǎng)絡(luò)經(jīng)過(guò)一個(gè)訓(xùn)練樣本的訓(xùn)練,它的權(quán)重就會(huì)進(jìn)行一次調(diào)整。
正如我們上面所討論的,vocabulary的大小決定了我們的Skip-Gram神經(jīng)網(wǎng)絡(luò)將會(huì)擁有大規(guī)模的權(quán)重矩陣,所有的這些權(quán)重需要通過(guò)我們數(shù)以億計(jì)的訓(xùn)練樣本來(lái)進(jìn)行調(diào)整,這是非常消耗計(jì)算資源的,并且實(shí)際中訓(xùn)練起來(lái)會(huì)非常慢。
負(fù)采樣(negative sampling)解決了這個(gè)問(wèn)題,它是用來(lái)提高訓(xùn)練速度并且改善所得到詞向量的質(zhì)量的一種方法。不同于原本每個(gè)訓(xùn)練樣本更新所有的權(quán)重,負(fù)采樣每次讓一個(gè)訓(xùn)練樣本僅僅更新一小部分的權(quán)重,這樣就會(huì)降低梯度下降過(guò)程中的計(jì)算量。
當(dāng)我們用訓(xùn)練樣本 ( input word: "fox",output word: "quick") 來(lái)訓(xùn)練我們的神經(jīng)網(wǎng)絡(luò)時(shí),“ fox”和“quick”都是經(jīng)過(guò)one-hot編碼的。如果我們的vocabulary大小為10000時(shí),在輸出層,我們期望對(duì)應(yīng)“quick”單詞的那個(gè)神經(jīng)元結(jié)點(diǎn)輸出1,其余9999個(gè)都應(yīng)該輸出0。在這里,這9999個(gè)我們期望輸出為0的神經(jīng)元結(jié)點(diǎn)所對(duì)應(yīng)的單詞我們稱為“negative” word。
當(dāng)使用負(fù)采樣時(shí),我們將隨機(jī)選擇一小部分的negative words(比如選5個(gè)negative words)來(lái)更新對(duì)應(yīng)的權(quán)重。我們也會(huì)對(duì)我們的“positive” word進(jìn)行權(quán)重更新(在我們上面的例子中,這個(gè)單詞指的是”quick“)。
在論文中,作者指出指出對(duì)于小規(guī)模數(shù)據(jù)集,選擇5-20個(gè)negative words會(huì)比較好,對(duì)于大規(guī)模數(shù)據(jù)集可以僅選擇2-5個(gè)negative words。
如何選擇negative words
我們使用“一元模型分布(unigram distribution)”來(lái)選擇“negative words”。
要注意的一點(diǎn)是,一個(gè)單詞被選作negative sample的概率跟它出現(xiàn)的頻次有關(guān),出現(xiàn)頻次越高的單詞越容易被選作negative words。
在word2vec的C語(yǔ)言實(shí)現(xiàn)中,你可以看到對(duì)于這個(gè)概率的實(shí)現(xiàn)公式。每個(gè)單詞被選為“negative words”的概率計(jì)算公式與其出現(xiàn)的頻次有關(guān)。
代碼中的公式實(shí)現(xiàn)如下:
有了這張表以后,每次去我們進(jìn)行負(fù)采樣時(shí),只需要在0-1億范圍內(nèi)生成一個(gè)隨機(jī)數(shù),然后選擇表中索引號(hào)為這個(gè)隨機(jī)數(shù)的那個(gè)單詞作為我們的negative word即可。一個(gè)單詞的負(fù)采樣概率越大,那么它在這個(gè)表中出現(xiàn)的次數(shù)就越多,它被選中的概率就越大。
到目前為止,Word2Vec中的Skip-Gram模型就講完了,對(duì)于里面具體的數(shù)學(xué)公式推導(dǎo)細(xì)節(jié)這里并沒(méi)有深入。這篇文章只是對(duì)于實(shí)現(xiàn)細(xì)節(jié)上的一些思想進(jìn)行了闡述。
其他資料
如果想了解更多的實(shí)現(xiàn)細(xì)節(jié),可以去查看C語(yǔ)言的實(shí)現(xiàn)源碼。
其他Word2Vec教程請(qǐng)參考這里。
一文詳解 Word2vec 之 Skip-Gram 模型(結(jié)構(gòu)篇)_qq_24003917的博客-CSDN博客_skip-gram
漫談Word2vec之skip-gram模型 - 知乎
下一篇文章將會(huì)介紹如何用TensorFlow實(shí)現(xiàn)一個(gè)Word2Vec中的Skip-Gram模型。
20201108
初始化的矩陣剛開(kāi)始沒(méi)有意義 通過(guò)反向傳播更新之后才得到實(shí)際的意義
總結(jié)
以上是生活随笔為你收集整理的理解 Word2Vec 之 Skip-Gram 模型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 漫谈Word2vec之skip-gram
- 下一篇: Python zip() 函数