web-dev-qa-db-ja.com

PyTorch / Gensim-事前学習済みのWord埋め込みを読み込む方法

事前に訓練されたgensimを含むWord2vec埋め込みをPyTorch埋め込みレイヤーにロードしたい。

私の質問は、gensimによってPyTorch埋め込みレイヤーに読み込まれた埋め込みウェイトをどのように取得するかです。

前もって感謝します!

18
blue-phoenox

PyTorchでgensim埋め込みを読み込むことに関する私の調査結果を報告したかっただけです。


  • PyTorch _0.4.0_以降のソリューション:

_v0.4.0_から、新しい関数 from_pretrained() が追加されました。これにより、埋め込みのロードが非常に快適になります。これはドキュメントの例です。

_>> # FloatTensor containing pretrained weights
>> weight = torch.FloatTensor([[1, 2.3, 3], [4, 5.1, 6.3]])
>> embedding = nn.Embedding.from_pretrained(weight)
>> # Get embeddings for index 1
>> input = torch.LongTensor([1])
>> embedding(input)
_

gensim の重みは、次の方法で簡単に取得できます。

_import gensim
model = gensim.models.KeyedVectors.load_Word2vec_format('path/to/file')
weights = torch.FloatTensor(model.vectors) # formerly syn0, which is soon deprecated
_

  • PyTorchバージョン_0.3.1_以前のソリューション:

バージョン_0.3.1_を使用していますが、このバージョンでは from_pretrained() は使用できません。

したがって、独自の_from_pretrained_を作成したので、_0.3.1_でも使用できます。

PyTorchバージョンの_from_pretrained_のコード_0.3.1_以下:

_def from_pretrained(embeddings, freeze=True):
    assert embeddings.dim() == 2, \
         'Embeddings parameter is expected to be 2-dimensional'
    rows, cols = embeddings.shape
    embedding = torch.nn.Embedding(num_embeddings=rows, embedding_dim=cols)
    embedding.weight = torch.nn.Parameter(embeddings)
    embedding.weight.requires_grad = not freeze
    return embedding
_

埋め込みは次のようにロードできます:

_embedding = from_pretrained(weights)
_

これが誰かに役立つことを願っています。

29
blue-phoenox

簡単だと思います。埋め込みウェイトをgensimからPyTorch embedding layer の対応するウェイトにコピーするだけです。

2つのことが正しいことを確認する必要があります。1つ目は重量の形状が正しいこと、2つ目は重量をPyTorch FloatTensorタイプに変換する必要があることです。

4
jdhao
from gensim.models import Word2Vec

model = Word2Vec(reviews,size=100, window=5, min_count=5, workers=4)
#gensim model created

import torch

weights = torch.FloatTensor(model.wv.vectors)
embedding = nn.Embedding.from_pretrained(weights)
1
Jibin Mathew

torchtext pytorchでライブラリを使用することを除いて、同じ質問がありました。これは、パディング、バッチ処理などに役立つからです。これは、事前に訓練された埋め込みをtorchtext 0.3.0でロードし、それらをpytorch 0.4.1に渡すために行ったことです(pytorch部分は blue-phoenox で言及された方法を使用します):

import torch
import torch.nn as nn
import torchtext.data as data
import torchtext.vocab as vocab

# use torchtext to define the dataset field containing text
text_field = data.Field(sequential=True)

# load your dataset using torchtext, e.g.
dataset = data.Dataset(examples=..., fields=[('text', text_field), ...])

# build vocabulary
text_field.build_vocab(dataset)

# I use embeddings created with
# model = gensim.models.Word2Vec(...)
# model.wv.save_Word2vec_format(path_to_embeddings_file)

# load embeddings using torchtext
vectors = vocab.Vectors(path_to_embeddings_file) # file created by gensim
text_field.vocab.set_vectors(vectors.stoi, vectors.vectors, vectors.dim)

# when defining your network you can then use the method mentioned by blue-phoenox
embedding = nn.Embedding.from_pretrained(torch.FloatTensor(text_field.vocab.vectors))

# pass data to the layer
dataset_iter = data.Iterator(dataset, ...)
for batch in dataset_iter:
    ...
    embedding(batch.text)
1
robodasha

同様の問題がありました:「gensimを使用してbinary形式で埋め込みをトレーニングおよび保存した後、トーチテキストに読み込む方法は?」

ファイルをtxt形式で保存し、カスタムWord埋め込みの読み込みの素晴らしい tutorial を実行しました。

def convert_bin_emb_txt(out_path,emb_file):
    txt_name = basename(emb_file).split(".")[0] +".txt"
    emb_txt_file = os.path.join(out_path,txt_name)
    emb_model = KeyedVectors.load_Word2vec_format(emb_file,binary=True)
    emb_model.save_Word2vec_format(emb_txt_file,binary=False)
    return emb_txt_file

emb_txt_file = convert_bin_emb_txt(out_path,emb_bin_file)
custom_embeddings = vocab.Vectors(name=emb_txt_file,
                                  cache='custom_embeddings',
                                  unk_init=torch.Tensor.normal_)

TEXT.build_vocab(train_data,
                 max_size=MAX_VOCAB_SIZE,
                 vectors=custom_embeddings,
                 unk_init=torch.Tensor.normal_)

テスト対象:PyTorch:1.2.0およびTorchText:0.4.0。

受け入れられた答えでは、リンクされた tutorial をたどり、正規分布を使用して埋め込みにないすべての単語を初期化する方法とベクトルをゼロに等しくする方法を初期化する方法がわからなかったため、この答えを追加しました。

0
damianosmel

私は自分でドキュメントを理解するのにかなりの問題を抱えており、周りにはそれほど良い例はありません。この例が他の人に役立つことを願っています。これは、matrix_embeddingsの事前トレーニング済み埋め込みを使用する単純な分類子です。 requires_gradをfalseに設定することで、それらを変更していないことを確認します。

クラスInferClassifier(nn.Module):

def __init__(self, input_dim, n_classes, matrix_embeddings):
    """initializes a 2 layer MLP for classification.
    There are no non-linearities in the original code, Katia instructed us 
    to use tanh instead"""

    super(InferClassifier, self).__init__()

    #dimensionalities
    self.input_dim = input_dim
    self.n_classes = n_classes
    self.hidden_dim = 512

    #embedding
    self.embeddings = nn.Embedding.from_pretrained(matrix_embeddings)
    self.embeddings.requires_grad = False

    #creates a MLP
    self.classifier = nn.Sequential(
            nn.Linear(self.input_dim, self.hidden_dim),
            nn.Tanh(), #not present in the original code.
            nn.Linear(self.hidden_dim, self.n_classes))

def forward(self, sentence):
    """forward pass of the classifier
    I am not sure it is necessary to make this explicit."""

    #get the embeddings for the inputs
    u = self.embeddings(sentence)

    #forward to the classifier
    return self.classifier(x)

sentenceは、単語ではなくmatrix_embeddingsのインデックスを持つベクトルです。

0
Victor Zuanazzi