今日資料:
https://www.tensorflow.org/tutorials/word2vec
中文版:
http://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/word2vec.html
這一節(jié)是關(guān)于 word2vec 模型的,可以用來(lái)學(xué)習(xí)詞的向量表達(dá),也叫‘word embeddings’。
之前寫過(guò)一篇:word2vec 模型思想和代碼實(shí)現(xiàn),里面有 skip-gram 算法的簡(jiǎn)單實(shí)現(xiàn)。
http://www.lxweimin.com/p/86134284fa14
今天要看的是如何在 TensorFlow 中訓(xùn)練詞向量,主要看一下這個(gè)代碼:
tensorflow/examples/tutorials/word2vec/word2vec_basic.py
詞向量就是用一個(gè)具有一定維度的向量來(lái)表示一個(gè)單詞,這樣在分布式假設(shè)的思想下,我們可以認(rèn)為出現(xiàn)在相同上下文情景中的詞匯都有類似的語(yǔ)義。
word2vec 可以很有效地從文本中學(xué)習(xí)出詞向量,主要有兩種算法,Continuous Bag-of-Words model (CBOW) 和 Skip-Gram ,CBOW 根據(jù)上下文('the cat sits on the')來(lái)預(yù)測(cè)目標(biāo)詞匯(例如,‘mat’),而 Skip-Gram 則相反,它通過(guò)已知的目標(biāo)詞匯來(lái)預(yù)測(cè)上下文。
通常的 Neural probabilistic language 是通過(guò)極大似然法來(lái)?xiàng)l件概率:在給定前面語(yǔ)境的情況下,最大化目標(biāo)詞的概率。
而在 word2vec 中不需要用全概率模型,而是用 logistic regression 來(lái)把真實(shí)的目標(biāo)詞匯和制造的噪音詞匯分開。
目標(biāo)函數(shù)就是,這個(gè)也叫 Negative Sampling,
即現(xiàn)在的 loss function 只和隨機(jī)選出來(lái)的 k 個(gè) 噪聲單詞有關(guān),而不是整個(gè)語(yǔ)料庫(kù) V,這樣訓(xùn)練比較快。
本節(jié)的代碼就是用一個(gè) Skip-gram 模型來(lái)訓(xùn)練詞向量:
例如我們有數(shù)據(jù)集:
the quick brown fox jumped over the lazy dog
假設(shè)使用大小為1的窗口,這樣就得到這樣一個(gè)由(上下文, 目標(biāo)單詞) 組成的數(shù)據(jù)集:
([the, brown], quick), ([quick, fox], brown), ([brown, jumped], fox), ...
Skip-Gram 模型是把目標(biāo)單詞和上下文顛倒過(guò)來(lái),因此數(shù)據(jù)集就變成由(輸入, 輸出)組成的:
(quick, the), (quick, brown), (brown, quick), (brown, fox), ...
我們會(huì)計(jì)算每一對(duì)觀察值和噪聲值的損失函數(shù),例如 sheep 就是個(gè)噪音:
整個(gè)計(jì)算的過(guò)程就是我們求出目標(biāo)函數(shù)對(duì) theta 的梯度,然后通過(guò)梯度下降法來(lái)更新 embedding parameters theta 來(lái)最大化目標(biāo)函數(shù),結(jié)果就是 embedding vectors 會(huì)不斷地移動(dòng),直到可以把真實(shí)單詞和噪聲單詞很好得區(qū)分開。
最后還可以用 t-SNE 來(lái)可視化最后的詞向量間的距離關(guān)系,可以發(fā)現(xiàn)具有相似信息的單詞距離較近。
1. 先下載數(shù)據(jù),words 有17005207 個(gè)單詞:
url = 'http://mattmahoney.net/dc/'
...
filename = maybe_download('text8.zip', 31344016)
...
words = read_data(filename)
count 就是要統(tǒng)計(jì)出 words 里面最高頻的 5 萬(wàn)個(gè)單詞。
dictionary 里的 key 就是 count 里的單詞,value 就是頻率的排序號(hào)。
data 里存的是 words 中每個(gè)單詞在 dictionary 中的序號(hào),如果不在 5 萬(wàn)里面,就標(biāo)記為 0.
reverse_dictionary 就是 key value 和 dictionary 里面的互換一下位置:
2. 用 最大長(zhǎng)度為 span 的 deque 做一個(gè)窗口:
span = 2 * skip_window + 1
buffer = collections.deque(maxlen=span)
從 data 中一個(gè)一個(gè)讀,先把一個(gè)窗口給讀滿。
要生成 batch_size 個(gè)樣本,
每個(gè)樣本是,先找到當(dāng)前窗口的 target,然后在這個(gè)窗口中,隨機(jī)生成 num_skips 個(gè) target-context 對(duì),
即會(huì)生成:3084 originated -> 12 as 這樣的對(duì)。
每次生成完一個(gè)樣本后,窗口向后移動(dòng)一位,
一直到生成完 batch_size 個(gè)。
embeddings 是先隨機(jī)生成 5萬(wàn)*128 維,
3. NCE loss 就是訓(xùn)練目標(biāo):
4. 用 SGD 優(yōu)化器去優(yōu)化目標(biāo),
valid_embeddings 是用來(lái)檢驗(yàn)的 16 個(gè)單詞的詞向量表示,
similarity 是定義驗(yàn)證單詞與詞匯表中所有單詞的相似度:
5. 然后就開始訓(xùn)練模型,num_steps = 100001
每 2000 次迭代后,顯示一下平均 loss,
每 10000 次后,計(jì)算一下驗(yàn)證單詞與所有單詞的相似度,并將最相似的 8 個(gè)單詞顯示出來(lái):
6. 最后用 TSNE 將 128 維的詞向量降到 2 維,并展示頻率最高的 100 個(gè)單詞:
推薦閱讀 歷史技術(shù)博文鏈接匯總
http://www.lxweimin.com/p/28f02bb59fe5
也許可以找到你想要的