回覆列表
-
1 # 機器之心Pro
-
2 # 傑克經典剪影
在本教程中,我想向你展示如何在 tensorflow 中實現一個 skip gram 模型,以便為你正在處理的任何文字生成單詞向量,然後用 tensorboard 對它們進行視覺化。我發現這個練習首先對於我理解 skip gram 模型是如何工作的非常有幫助;其次,你後續在 CNN 或 RNN 中使用它們之前,能夠形成對於向量捕獲你的文字關係的直觀感受。
我在 text8 資料集上訓練了一個 skip gram 模型,這個資料集是英文維基百科文章的集合。我用 Tensorboard 來視覺化這些嵌入。Tensorboard 允許您透過使用 PCA 選擇 3 主軸來投影資料來看到整個文字雲。超級酷!你可以輸入任何單詞,它會顯示相鄰的單詞。你也可以隔離最靠近它的 101 個點。
在本教程中,我想向你展示如何在 tensorflow 中實現一個 skip gram 模型,以便為你正在處理的任何文字生成單詞向量,然後用 tensorboard 對它們進行視覺化。我發現這個練習首先對於我理解 skip gram 模型是如何工作的非常有幫助;其次,你後續在 CNN 或 RNN 中使用它們之前,能夠形成對於向量捕獲你的文字關係的直觀感受。
我在 text8 資料集上訓練了一個 skip gram 模型,這個資料集是英文維基百科文章的集合。我用 Tensorboard 來視覺化這些嵌入。Tensorboard 允許您透過使用 PCA 選擇 3 主軸來投影資料來看到整個文字雲。超級酷!你可以輸入任何單詞,它會顯示相鄰的單詞。你也可以隔離最靠近它的 101 個點。
看看下面的片段。
你可以在我的 Github 儲存庫中找到完整的程式碼。
為了視覺化訓練過程,我還持續跟蹤一組隨機單詞在模型中最靠近的預測單詞。在第一次迭代中,最接近的預測單詞看起來非常隨機。這很合理,因為所有單詞向量都是隨機初始化的。
距離花費(cost)最近的有:譁眾取寵(sensationalism)、逆境(adversity)、自民黨(ldp)、榴蓮(durians)、hennepin、解釋(expound)、雲雀(skylark)、wolfowitz
距離引擎(engine)最近的有:推導符(vdash)、合金(alloys)、聯邦安全域性(fsb)、航海業(seafaring)、凍土(tundra)、frot、砒霜(arsenic)、作廢(invalidate)
距離建設(construction)最近的有:海豚(dolphins),駱駝(camels),量詞(quantifier),希臘人(hellenes),口音(accents),當代(contemporary),colm,放蕩的(cyprian)
距離超文字傳輸協議(http)最近的有:內部地(internally)、chaffee、避免(avoid)、加油器(oilers)、神秘(mystic)、chappell、vascones、cruciger
在訓練結束的時候,這個模型已經能更好地找到單詞之間的關係。
距離花費(cost)最近的有:開銷(expense)、昂貴(expensive)、購買(purchase)、技術(technologies)、不一致(inconsistent)、部分(part)、美元(dollars)、商業(commercial)
距離引擎(engine)最近的有:發動機(engines)、燃燒(combustion)、活塞(piston)、衝程(stroke)、排氣(exhaust)、汽缸(cylinder)、噴氣(jet)、推力(thrust)
距離建設(construction)最近的有:完成的(completed)、建造(constructed)、橋樑(bridge)、旅遊(tourism)、建築(built)、材料(materials)、建築(building)、設計(designed)
距離超文字傳輸協議(http)最近的有:www、htm、com、edu、html、org、php、ac
Word2Vec 和 Skip Gram 模型
建立單詞向量是一個過程,基於巨大的文字語料庫,併為每個單詞建立一個向量。建立的標準是,在語料庫中語境相似的單詞對應的向量會在向量空間中非常接近。
這些單詞向量可以很好地捕捉單詞之間的上下文關係(例如,黑色、白色和紅色的示例向量會緊密地結合在一起),而且使用這些向量而不是單詞本身來完成像文字分類或新文字生成這樣的自然語言處理(NPL)任務,我們會得到更好的結果。
有兩個主要的模型來生成這些單詞向量——連續單詞包 (CBOW) 和 Skip Gram 模型。CBOW 模型試圖在給定語境詞後預測中心詞,而 skip gram 模型試圖在給定中心詞時預測語境詞。我們可以看一個簡化的例子:
CBOW:這隻貓吃了________。(句子填充)本例中,應該填「食物」。
Skip-gram:_______________食物。(造句)本例中,可以填「這隻貓吃了」
如果您有興趣對這兩種方法進行更詳細的比較,請參見此連結。(連結:https://iksinc.wordpress.com/tag/continuous-bag-of-words-cbow/)
眾多論文發現,Skip gram 模型能產生更好的單詞向量,所以我將重點放在實現這個模型上。
在 Tensorflow 中實現 Skip Gram 模型
在這裡,我只列出構建模型的主要步驟。請在我的 Github 上檢視詳細的實現。(連結:https://github.com/priya-dwivedi/Deep-Learning/blob/master/word2vec_skipgram/Skip-Grams-Solution.ipynb)
1、資料預處理
counts = collections.Counter(words)
vocab = sorted(counts, key=counts.get, reverse=True)
vocab_to_int = {word: ii for ii, word in enumerate(vocab, 0)}
2、次級取樣
經常出現的單詞,例如「the」、「of」和「for」,並沒有給附近的單詞提供太多的語境。如果我們丟棄其中的一些,我們可以消除我們的資料中的部分噪聲,並且能夠更快地訓練並獲得更好的表示結果。這個過程被 Mikolov 稱為次級取樣(subsampling)。對於訓練集中的每一個單詞,我們以它出現頻率的倒數給出的機率來丟棄他。
3、建立輸入和目標
Skip gram 模型的輸入是每個單詞(編碼成為的整數),而目標是圍繞該視窗的單詞。Mikolov 等人發現,如果這個視窗的大小是可變的,同時更接近中心單詞的單詞采樣次數較多時,效能會更好。
「由於距離更遠的詞通常不如距離更近的詞與目標單詞的關係那麼緊密,我們透過在訓練我們的樣本時更少對遠距離的詞采樣,以減少其權重……如果我們選擇視窗大小= 5,我們將為每一個訓練詞隨機選擇一個 1 和視窗大小 5 之間的數字 R,然後將目標單詞在句子中的前後 R 個單詞納入訓練,作為正確的標籤。」
R = np.random.randint(1, window_size+1)
start = idx—R if (idx—R) > 0 else 0
stop = idx + R
target_words = set(words[start:idx] + words[idx+1:stop+1])
4、建立模型
從 Chris McCormick 的部落格,我們可以看到我們將要建立的網路的一般結構。
我們將把一個「螞蟻」之類的輸入詞表示為一個獨熱向量。這個向量將有 10,000 個分量(每個分量都對應於我們詞彙表中的一個單詞),我們將對應單詞「ants」的分量設為「1」,所有其他分量都對應 0。
網路的輸出是一個單向量(也包含 10,000 個分量)。這個向量包含的分量大小即對應於我們隨機選擇的附近單詞正好是這個詞彙表單詞的機率。
在訓練結束時,隱藏層將會有經過訓練的單詞向量。隱藏層的大小相當於我們向量中的維數。在上面的例子中,每個單詞都有一個長度為 300 的向量。
你可能已經注意到,skip-gram 神經網路包含大量的權重數……在我們的例子中有 300 特性和 10000 個單詞的詞彙表,也就是說在隱藏層和輸出層都有 3 百萬個權重數!在一個大資料集上進行這樣的訓練將會是令人望而卻步的,因此 word2vec 的作者引入了一些調整來使訓練變得可行。你可以在這個連結(http://mccormickml.com/2017/01/11/word2vec-tutorial-part-2-negative-sampling/)中看到更多關於它們的資訊。Github 上的這些程式碼(https://github.com/priya-dwivedi/Deep-Learning/blob/master/word2vec_skipgram/Skip-Grams-Solution.ipynb)實現了這些最佳化以加速訓練。
5、用 Tensorboard 來進行視覺化
您可以使用 Tensorboard 中的「嵌入投影機」視覺化嵌入。要實現這個功能,你需要完成以下步驟:
在檢查點目錄的訓練結束時儲存您的模型
建立一個 metadata.tsv 檔案包含每個整數返回單詞的對映關係,這樣 Tensorboard 就會顯示單詞而不是整數。將這個 tsv 檔案儲存在同一個檢查點目錄中
執行這段程式碼:
from tensorflow.contrib.tensorboard.plugins import projector
summary_writer = tf.summary.FileWriter(『checkpoints』, sess.graph)
config = projector.ProjectorConfig()
embedding_conf = config.embeddings.add()
# embedding_conf.tensor_name = 『embedding:0』
embedding_conf.metadata_path = os.path.join(『checkpoints』, 『metadata.tsv』)
projector.visualize_embeddings(summary_writer, config)
開啟 tensorboard,將其指向檢查點目錄
大功告成!
如果你喜歡這個推送請幫我點贊!希望你能弄明白這些程式碼並自己嘗試執行一下。如果你對這個話題有其他想法,請在這篇文章下留言或者發郵件到 [email protected] (mailto:[email protected])
我的其他文章:https://medium.com/@priya.dwivedi/
PS:我住在多倫多,正想跳槽到深度學習領域。如果你喜歡我的文章而且能幫我聯絡到合適的崗位,我會超級感激!我的郵件地址是 [email protected] (mailto:[email protected])