Я хочу загрузить предварительно подготовленное вложение word2vec с gensim в слой внедрения PyTorch.
Поэтому мой вопрос заключается в том, как получить весы внедрения, загруженные gensim, в слой внедрения PyTorch.
Заранее спасибо!
Я хочу загрузить предварительно подготовленное вложение word2vec с gensim в слой внедрения PyTorch.
Поэтому мой вопрос заключается в том, как получить весы внедрения, загруженные gensim, в слой внедрения 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
0.3.1
и старше:Я использую версию 0.3.1
, а from_pretrained()
недоступен в этой версии.
Поэтому я создал свой собственный from_pretrained
, чтобы я мог также использовать его с 0.3.1
.
Код для from_pretrained
для версий PyTorch 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)
Надеюсь, это кому-нибудь пригодится.
Я думаю, что это легко. Просто скопируйте вес внедрения с gensim на соответствующий вес в слое внедрения PyTorch.
Вы должны убедиться, что две вещи верны: во-первых, должна быть правильная форма веса, во-вторых, что вес должен быть преобразован в тип PyTorch FloatTensor.
У меня был тот же вопрос, за исключением того, что я использую библиотеку 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)
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)
У меня были некоторые проблемы с пониманием документации, и хороших примеров не так много. Надеюсь, этот пример поможет другим людям. Это простой классификатор, который берет предварительно обученные вложения в matrix_embeddings
. Устанавливая requires_grad
в false, мы убеждаемся, что не меняем их.
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
- это вектор с индексами matrix_embeddings
вместо слов.
Возникла похожая проблема: "после обучения и сохранения вложений в двоичном формате с использованием gensim, как я загружаю их в torchtext?"
Я просто сохранил файл в формате txt, а затем следовал превосходному учебнику по загрузке пользовательских вложений слов.
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.
Я добавил этот ответ, потому что с принятым ответом я не был уверен, как следовать связанному учебнику и инициализировать все слова, не входящие во вложения, используя нормальное распределение, и как сделать векторы и равными нулю.