webentwicklung-frage-antwort-db.com.de

PyTorch/Gensim - Laden vorbereiteter Word-Einbettungen

Ich möchte eine vorbereitete Word2vec-Einbettung mit gensim in eine PyTorch-Einbettungsebene laden.

Meine Frage ist also, wie bekomme ich die von gensim geladenen Einbettungsgewichte in die PyTorch-Einbettungsschicht.

Danke im Voraus!

9
blue-phoenox

Ich wollte nur meine Ergebnisse zum Laden einer Gensim-Einbettung mit PyTorch berichten.

Von v0.4.0 gibt es eine neue Funktion from_pretrained() , die das Laden einer Einbettung sehr komfortabel macht .. Hier ein Beispiel aus der Dokumentation.

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

Die Gewichte aus gensim können leicht durch folgende Werte erhalten werden:

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

Ich verwende jedoch Version 0.3.1 und from_pretrained() ist in dieser Version nicht verfügbar.

Deshalb habe ich meinen eigenen from_pretrained erstellt, damit ich ihn auch mit 0.3.1 verwenden kann.

Code für from_pretrained für PyTorch-Versionen 0.3.1 oder niedriger:

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

Die Einbettung kann dann einfach so geladen werden:

embedding = from_pretrained(weights)

Ich hoffe das ist hilfreich für jemanden.

16
blue-phoenox

Ich denke es ist einfach. Kopieren Sie einfach das Einbettungsgewicht von gensim auf das entsprechende Gewicht in PyTorch Einbettungsschicht .

Sie müssen sicherstellen, dass zwei Dinge richtig sind: erstens muss die Gewichtsform korrekt sein, zweitens muss das Gewicht in den PyTorch FloatTensor-Typ umgewandelt werden.

4
jdhao

Hatte ähnliches Problem: "Nach dem Training und dem Speichern von Einbettungen im Binärformat mit gensim, wie lade ich sie in torchtext?"

Ich habe die Datei gerade im TXT-Format gespeichert und befolge dann das hervorragende Tutorial zum Laden benutzerdefinierter Word-Einbettungen.

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

getestet auf: PyTorch: 1.2.0 und TorchText: 0.4.0.

Ich fügte diese Antwort hinzu, weil ich mit der akzeptierten Antwort nicht sicher war, wie ich dem verknüpften Tutorial folgen und alle Wörter, die nicht in den Einbettungen enthalten sind, mit der Normalverteilung initialisieren und wie man die Vektoren und gleich Null macht.

0
damianosmel
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

Ich hatte die gleiche Frage, mit der Ausnahme, dass ich torchtext library mit pytorch verwende, da es beim Padding, Batching und anderen Dingen hilft. So habe ich vorgelernte Einbettungen mit torchtext 0.3.0 geladen und an pytorch 0.4.1 übergeben (der pytorch-Teil verwendet die von blue-phoenox genannte Methode):

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

Ich hatte einige Probleme, die Dokumentation selbst zu verstehen, und es gibt nicht so viele gute Beispiele. Hoffentlich hilft dieses Beispiel anderen Menschen. Es ist ein einfacher Klassifikator, der die vorgefertigten Einbettungen in die matrix_embeddings. Indem man es einstellt requires_grad auf false stellen wir sicher, dass wir sie nicht ändern.

klasse 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 ist ein Vektor mit den Indizes von matrix_embeddings statt Worte.

0
Victor Zuanazzi