我以前寫過一篇關(guān)于word2vec的文章侨糟,說實(shí)話税朴,寫的一坨回季,我決定以后寫博客認(rèn)認(rèn)真真的去寫。
我的博客來自于網(wǎng)上各位前輩的資料的整理正林,這位這位和這位翻譯的讓我對(duì)word2vec有了深入的理解泡一。word2vec有兩種模型,一個(gè)是skip-gram觅廓,一個(gè)是cbow鼻忠。這兩個(gè)模型應(yīng)該是在一起講的。cbow是輸入詞向量求平均杈绸,二skip-gram輸入只有一個(gè)帖蔓,不要求平均。首先說一點(diǎn)瞳脓,cbow和skip-gram的目標(biāo)函數(shù)塑娇,下圖是cbow的,skip-gram反過來而已
詞向量基礎(chǔ)
詞向量很早以前就有了劫侧。最早的詞向量成為one-hot representation埋酬,它使用的詞向量維度大小為整個(gè)詞匯表的大小,對(duì)于詞匯表中每個(gè)具體的詞,對(duì)應(yīng)位置置為1奇瘦,其余位置為0棘催。例如,我們得到一個(gè)為2000大小的詞匯表耳标,“dog”的詞序?yàn)?醇坝,那么它的詞向量表示為(0,0,1,0,...,0)。是不是感覺這樣很蠢次坡,只是將改詞所在的位置表示出來呼猪,而其余位置都沒有啥意義,占用存儲(chǔ)空間砸琅。如果上千萬大小的詞匯表宋距,一個(gè)詞就需要上千萬的位置,將會(huì)導(dǎo)致維度災(zāi)難症脂。
于是谚赎,人們搞出一個(gè)Distributed representation,它的思路是通過訓(xùn)練诱篷,將每個(gè)詞都映射到一個(gè)較短的詞向量上壶唤,所有的詞向量就構(gòu)成了向量空間,進(jìn)而可以用統(tǒng)計(jì)學(xué)的方法研究詞和詞之間的關(guān)系棕所。比如谷歌用google news訓(xùn)練的詞向量闸盔,維度為300,一般維度自己指定琳省。
上圖僅僅展示了一個(gè)詞匯表中詞向量的一部分迎吵,可以看出“Man”這個(gè)詞和“Woman”這個(gè)詞在“Gender”所占的比重還是很大的,在其他屬性占的比重小针贬。當(dāng)然實(shí)際上击费,我們并不能對(duì)詞向量的每一個(gè)維度做很好的解釋。
使用t-SNE算法對(duì)詞向量進(jìn)行非線性降維桦他,可得到下面映射結(jié)果:
可以看到同一類的詞荡灾,基本上聚集在了一起。例如瞬铸,給定對(duì)應(yīng)關(guān)系“man”對(duì)“woman”批幌,要求機(jī)器類比出“King”對(duì)應(yīng)的詞匯,可發(fā)現(xiàn)詞向量存在數(shù)學(xué)關(guān)系“Man - Woman = King - Queen”
第一部分
模型
在word2vec模型中嗓节,主要有Skip-Gram和CBOW兩種模型荧缘。CBOW是給定上下文,來預(yù)測(cè)input word拦宣,而Skip-Gram是給定input word來預(yù)測(cè)上下文截粗。
我暫時(shí)文章沒怎么看懂信姓,就看懂了最后一篇翻譯的,所以暫時(shí)只寫skip-gram绸罗。
Skip-Gram實(shí)際上分為了兩個(gè)部分意推,第一部分為建立模型,第二部分為通過模型獲取嵌入詞向量珊蟀。word2vec的整個(gè)建模過程實(shí)際上與自編碼器(auto-encoder)相似菊值,即先基于訓(xùn)練數(shù)據(jù)構(gòu)建一個(gè)神經(jīng)網(wǎng)絡(luò),當(dāng)這個(gè)模型訓(xùn)練號(hào)以后育灸,我們并不會(huì)用這個(gè)訓(xùn)練好的模型處理新的任務(wù)腻窒,我們需要的是這個(gè)模型通過訓(xùn)練所學(xué)到的參數(shù),如隱層的權(quán)值矩陣-----這些權(quán)重在word2vec中實(shí)際上就是我們?cè)噲D學(xué)習(xí)的“word vectors(詞向量)”磅崭《樱基于訓(xùn)練數(shù)據(jù)建模的過程,我們給它取一個(gè)名字叫“Fake Task”砸喻,意味著建模不是最終目的柔逼。
上面提到的這種方法實(shí)際上會(huì)在無監(jiān)督特征學(xué)習(xí)(unsupervised feature learning)中見到,最常見的是自編碼器(auto-enconder):通過在隱層將輸入進(jìn)行編碼壓縮割岛,繼而在輸出層將數(shù)據(jù)解碼回復(fù)到初始狀態(tài)卒落,訓(xùn)練完成后,我們將會(huì)去掉輸出層蜂桶,只保留隱層。(ps:讓我想起了生成對(duì)抗網(wǎng)絡(luò))
The Fake Task
“fake task”就是構(gòu)建網(wǎng)絡(luò)也切,但只要訓(xùn)練數(shù)據(jù)得到的隱層扑媚。它的完整過程如下:
假如我們有一個(gè)句子“The fox jumps over the lazy dog”。
- 首先我們選取句子中的一個(gè)詞作為輸入詞(實(shí)際訓(xùn)練過程中雷恃,是依次將句子中的每個(gè)詞作為輸入詞構(gòu)建訓(xùn)練對(duì)的)疆股,例如選取“fox”作為input word;
- 有了input word后倒槐,我們?cè)俣x一個(gè)叫skip_window的參數(shù)旬痹,它代表我們從當(dāng)前input word的一側(cè)選取詞的數(shù)量。如果設(shè)置skip_window = 2讨越,那么我們最終獲得窗口中的詞(包括input word在內(nèi))就是['The', 'fox', 'jumps', 'over']两残。那么整個(gè)窗口大小span =
= 4。另外一個(gè)參數(shù)叫num_skips把跨,它代表我們選取多少個(gè)不同的詞作為我們的output word人弓,當(dāng)skip_window = 2,num_skips = 2時(shí)着逐,我們將會(huì)得到兩組(input word崔赌,output word)形式的訓(xùn)練數(shù)據(jù)意蛀,即('fox', 'jumps'),('fox', 'the')
- 神經(jīng)網(wǎng)絡(luò)基于這些訓(xùn)練數(shù)據(jù)將會(huì)輸出一個(gè)概率分布健芭,這個(gè)概率代表著我們?cè)~典中的每個(gè)詞是output word的可能性县钥。例如,上面我們得到兩組數(shù)據(jù)慈迈。我們先用一組數(shù)據(jù)('fox', 'jumps')來訓(xùn)練神經(jīng)網(wǎng)絡(luò)若贮,那么模型通過前面學(xué)習(xí)這個(gè)訓(xùn)練樣本,會(huì)告訴我們?cè)~匯表中其他單詞的概率大小和“jumps”的概率大小吩翻。
模型的輸出概率代表著我們的詞典中每個(gè)詞有多大可能跟input word同時(shí)出現(xiàn)兜看。例如,我們向神經(jīng)網(wǎng)絡(luò)模型中輸入一個(gè)單詞“Soviet”狭瞎,那么最終模型的輸出概率中细移,像“Union”,“Russia”這些相關(guān)詞的概率遠(yuǎn)遠(yuǎn)高于“dog”熊锭,“l(fā)ove”這些非相關(guān)詞的概率弧轧。
我們將通過給神經(jīng)網(wǎng)絡(luò)輸入文本中成對(duì)的單詞來訓(xùn)練它完成上面所說的概率計(jì)算。下面的圖給出了一個(gè)完整的例子碗殷。我們選定句子“The quick brown fox jumps over lazy dog”精绎,設(shè)定窗口大小為2(skip_window = 2)。下圖中锌妻,藍(lán)色代表input_word代乃,方框內(nèi)代表位于窗口內(nèi)的單詞。
模型細(xì)節(jié)
首先仿粹,神經(jīng)網(wǎng)絡(luò)只能接受數(shù)值輸入搁吓,所以我們必須將單詞進(jìn)行one-hot編碼,上面我們介紹的詞向量發(fā)揮作用了吭历。假設(shè)我們?cè)谟?xùn)練數(shù)據(jù)中只能取出10000個(gè)不重復(fù)的單詞作為詞匯表堕仔,那么我們對(duì)每個(gè)單詞編碼都是的向量。在上面的例子中晌区,如果“** The dog barked at the mailman**”摩骨,按照簡(jiǎn)單的情況,每個(gè)單詞在詞匯表的位置為1朗若,2恼五,3,4哭懈,5唤冈,6,那么這6個(gè)單詞將會(huì)被編碼成
維度的向量银伟,為了表示方便你虹,我只寫出前2個(gè)
模型的輸入是10000為的向量绘搞,那么輸出也是10000維(詞匯表的大小)向量傅物,它包含了10000個(gè)概率夯辖,每一個(gè)概率代表著當(dāng)前詞是輸入樣本中output word的概率大小。如下圖董饰,神經(jīng)網(wǎng)絡(luò)架構(gòu):
隱層不使用任何激活函數(shù)蒿褂,但是輸出層用來softmax
第二部分
上面結(jié)尾我們說輸出層用softmax,但是要知道卒暂,如果真的用softmax來算啄栓,計(jì)算量大的驚人。所以可以用這三個(gè)方法來減少計(jì)算量:
- 將常見的單詞組合(word pairs)或者詞組作為單個(gè)“words”來使用也祠。
- 對(duì)高頻詞進(jìn)行抽樣來減少訓(xùn)練樣本的個(gè)數(shù)
- 最后最重要的一點(diǎn)昙楚,就是“nagative sampling”方法,這樣每個(gè)訓(xùn)練樣本只會(huì)更新一小部分模型權(quán)重诈嘿,從而降低計(jì)算負(fù)擔(dān)堪旧。
其他的我不想講,原作者博客中有奖亚,我想講講nagative sampling(負(fù)采樣)淳梦。不同于原本每個(gè)訓(xùn)練樣本更新所有的權(quán)重,負(fù)采樣每次讓一個(gè)訓(xùn)練樣本僅僅更新一部分的權(quán)重昔字,這樣就好降低梯度下降過程中的計(jì)算量爆袍。
當(dāng)我們用訓(xùn)練樣本(input word:"fox", output word:"quick")來訓(xùn)練我們的神經(jīng)網(wǎng)絡(luò)時(shí),“fox”和“quick”都是經(jīng)過one-hot編碼的作郭。如果我們的vocabulary大小為10000時(shí)陨囊,在輸出層,我們希望“quick”單詞那個(gè)位置輸出1所坯,其余都是0。這些其余我們期望輸出0的位置所對(duì)應(yīng)的單詞我們成為“negative” word挂捅。
當(dāng)使用負(fù)采樣時(shí)芹助,我們將隨機(jī)選擇一小部分的negative words(比如選5個(gè)negative words)來更新對(duì)應(yīng)的權(quán)重。我們也會(huì)對(duì)我們的positive word進(jìn)行權(quán)重更新(上面的例子指的是"quick")闲先。
- 在論文中状土,作者指出指出對(duì)于小規(guī)模數(shù)據(jù)集,選擇5-20個(gè)negative words會(huì)比較好伺糠,對(duì)于大規(guī)模數(shù)據(jù)集可以僅選擇2-5個(gè)negative words蒙谓。
回憶一下我們的隱層-輸出層擁有300 x 10000的權(quán)重矩陣。如果使用了負(fù)采樣的方法我們僅僅去更新我們的positive word-“quick”的和我們選擇的其他5個(gè)negative words的結(jié)點(diǎn)對(duì)應(yīng)的權(quán)重训桶,共計(jì)6個(gè)輸出神經(jīng)元累驮,相當(dāng)于每次只更新300 6 = 1800個(gè)權(quán)重酣倾。對(duì)于3百萬的權(quán)重來說,相當(dāng)于只計(jì)算了0.06%的權(quán)重谤专,這樣計(jì)算效率就大幅度提高躁锡。
寫到這里,其實(shí)還有很多東西沒說明白置侍。但這個(gè)主題說大了映之,我暫時(shí)先擱置著,等研究透了再來修改增加蜡坊。