Skip to content

[PyTorch] nn.Embedding() 讀取 Gensim 預訓練模型權重方法筆記

Last Updated on 2021-10-13 by Clay

使用 PyTorch 搭建關於自然語言處理相關任務的人,想必都對 PyTorch 當中的 nn.Embedding() 不陌生。nn.Embedding() 是 PyTorch 當中的一個嵌入層,可以讓我們將不同的詞編號之後放入,並產生一組我們可以任意指定的向量回傳。

就像這樣

從文字轉換成向量之後,我們這才可以開始訓練我們的模型 —— 畢竟電腦是只能運算數字的裝置。

Gensim 則是 Google 於 2013 年發表的 Word2Vec 的 Python 實現,讓我們可以通過 CBOW 或 Skip-gram 訓練出將文字轉成向量的預訓練 (Pre-trained) 模型。據我所知,在大部分的任務上,使用預訓練的模型效果往往比直接設置 nn.Embedding() 來得更好。

本文撰寫的目的便在於紀錄『該如何使用 nn.Embedding() 直接讀取 Gensim 的預訓練模型』。這樣一來,我們可以通過預訓練模型有個比較好的『起點』,並依照我們所處理的不同任務去進行微調,希望能得到更好的模型效果。


nn.Embedding() 讀取 Gensim 模型的方法

首先,我們需要有一個已經訓練好的 Gensim 模型。我從前寫過一些關於如何訓練 Gensim 的心得筆記,或許可以參考看看: 在 Python 中使用 Gensim 將文字轉成向量

那麼以下,直接來看段簡單的 Sample Code:

# coding: utf-8
import gensim
import torch
import torch.nn as nn


# Load word2vec pre-train model
model = gensim.models.Word2Vec.load('./word2vec_pretrain_v300.model')
weights = torch.FloatTensor(model.wv.vectors)


# Build nn.Embedding() layer
embedding = nn.Embedding.from_pretrained(weights)
embedding.requires_grad = False


# Query
query = '天氣'
query_id = torch.tensor(model.wv.vocab['天氣'].index)

gensim_vector = torch.tensor(model[query])
embedding_vector = embedding(query_id)

print(gensim_vector==embedding_vector)


Output:

首先將 Gensim 的預訓練模型讀取進來,並將其向量轉換成 PyTorch 所需要的資料格式 Tensor,當作 nn.Embedding() 的初始值。

這裡有個小細節:如果並不打算在模型訓練過程中一併訓練 nn.Emedding(),要記得將其設定為 requires_grad = False

剩下的就很單純了。提取出 Gensim 預訓練模型中詞彙的 Index (編號),同樣轉換成 Tensor 之後,再輸入 nn.Embedding(),就會得到訓練好的 300 維向量。

最後我做了個小實驗,確認 Gensim 模型和 nn.Embedding() 所返回的『天氣』向量都是一樣的。

另外,在實際上使用 nn.Embedding 模型層的時候,仍然要注意所謂的『未知詞』(Unknown word),在 nn.Embedding 中並不會自動幫忙處理,所以我們需要在讀取 weights 的時候手動添加未知詞的向量,看是要填入平均向量亦或者是零向量,然後在將詞彙編碼的時候將不在預訓練詞表中的詞彙編號為未知詞的編號。

以上,就是 PyTorch 中如何透過 nn.Embedding() 讀取 Gensim 預訓練模型的方法筆記。


References


Read More

Leave a Reply