51 votes

PyTorch / Gensim - Comment charger des incorporations de mots pré-formés

Je veux charger une intégration pré-formée de word2vec avec gensim dans une couche d'intégration PyTorch.

Donc ma question est, comment puis-je obtenir les poids d'intégration incorporés par gensim dans la couche d'intégration PyTorch.

Merci d'avance!

82voto

blue-phoenox Points 4555

Je voulais juste faire part de mes constatations sur le chargement d'un gensim intégration avec des PyTorch.


  • Solution pour PyTorch 0.4.0 et plus récent:

D' v0.4.0 il y a une nouvelle fonction from_pretrained() qui rend le chargement d'une incorporation très à l'aise. 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)

Le poids de gensim peut facilement être obtenue par:

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

  • Solution pour PyTorch version 0.3.1 et plus:

J'utilise la version 0.3.1 et from_pretrained() n'est pas disponible dans cette version.

Donc j'ai créé mon propre from_pretrained donc je peux aussi l'utiliser avec 0.3.1.

Code pour from_pretrained pour PyTorch versions 0.3.1 ou plus bas:

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é alors comme cela:

embedding = from_pretrained(weights)

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

4voto

jdhao Points 3136

Je pense que c'est facile. Copiez simplement le poids d'intégration de gensim vers le poids correspondant dans la couche d'intégration PyTorch.

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 en type PyTorch FloatTensor.

3voto

robodasha Points 236

J'ai eu la même question, sauf que j'utilise la bibliothèque torchtext avec pytorch car elle aide au rembourrage, au traitement par lots et à d'autres choses. Voici ce que j'ai fait pour charger des incorporations pré-entraînées avec torchtext 0.3.0 et pour les passer à pytorch 0.4.1 (la partie pytorch utilise la méthode mentionnée 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)
 

3voto

Jibin Mathew Points 478
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)

0voto

Victor Zuanazzi Points 312

J'ai eu pas mal de problèmes à comprendre la documentation moi-même et il n'y a pas beaucoup de bons exemples. Espérons que cet exemple aide d'autres personnes. C'est un classificateur simple, qui prend les plongements pré-formés dans le matrix_embeddings . En définissant requires_grad sur false, nous nous assurons de ne pas les modifier.

 class 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 est un vecteur avec les index de matrix_embeddings au lieu des mots.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X