web-dev-qa-db-fra.com

PyTorch/Gensim - Comment charger des incorporations Word pré-formées

Je souhaite charger une incorporation Word2vec pré-formée avec gensim dans une couche d'intégration PyTorch.

Ma question est donc la suivante: comment puis-je obtenir les poids d’incorporation intégrés par gensim dans la couche d’incorporation PyTorch?.

Merci d'avance!

9
blue-phoenox

Je voulais juste faire part de mes découvertes concernant le chargement d’un groupe de personnes incorporant PyTorch.

A partir de v0.4.0 il y a une nouvelle fonction from_pretrained() qui rend le chargement d'une intégration très confortable ..__ Voici un exemple tiré de la documentation.

>> # 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)

Les poids de gensim peuvent être facilement obtenus par:

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

Cependant, j'utilise les versions 0.3.1 et from_pretrained() n'est pas disponible dans cette version.

J'ai donc créé mon propre from_pretrained afin que je puisse également l'utiliser avec 0.3.1.

Code pour from_pretrained pour les versions de PyTorch 0.3.1 ou inférieur:

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

L'incorporation peut être chargée alors comme ceci:

embedding = from_pretrained(weights)

J'espère que cela est utile pour quelqu'un.

16
blue-phoenox

Je pense que c'est facile. Copiez simplement le poids d’intégration du gensim sur le poids correspondant dans PyTorch couche d’inclusion .

Vous devez vous assurer que deux choses sont correctes: premièrement, la forme du poids doit être correcte, deuxièmement, le poids doit être converti au type 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)
0
Jibin Mathew

J'avais la même question, sauf que j'utilise torchtext library avec pytorch, car cela facilite le remplissage, le traitement par lots et d'autres éléments. C’est ce que j’ai fait pour charger les intégrations pré-formées avec Torchtext 0.3.0 et les transmettre à pytorch 0.4.1 (la partie pytorch utilise la méthode décrite par 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)
0
robodasha