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!
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.
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.
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.
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)
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)
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.