PyTorch:将词向量加载到字段词汇表与嵌入层中

sta*_*010 6 python machine-learning word-embedding pytorch

我从 Keras 转到 PyTorch。我想使用 GloVe 向量创建一个 PyTorch 嵌入层(大小为 的矩阵V x D,其中V是词汇单词索引,D是嵌入向量维度),但对所需的步骤感到困惑。

在 Keras 中,您可以通过让 Embedding 层构造函数采用参数来加载 GloVe 向量weights

# Keras code.
embedding_layer = Embedding(..., weights=[embedding_matrix])
Run Code Online (Sandbox Code Playgroud)

在查看 PyTorch 和 TorchText 库时,我发现嵌入应该加载两次,一次在 a 中Field,然后在一个Embedding层中再次加载。这是我找到的示例代码:

# PyTorch code.

# Create a field for text and build a vocabulary with 'glove.6B.100d'
# pretrained embeddings.
TEXT = data.Field(tokenize = 'spacy', include_lengths = True)

TEXT.build_vocab(train_data, vectors='glove.6B.100d')


# Build an RNN model with an Embedding layer.
class RNN(nn.Module):
    def __init__(self, ...):

        super().__init__()
        self.embedding = nn.Embedding(vocab_size, embedding_dim)

        ...

# Initialize the embedding layer with the Glove embeddings from the
# vocabulary. Why are two steps needed???
model = RNN(...)
pretrained_embeddings = TEXT.vocab.vectors
model.embedding.weight.data.copy_(pretrained_embeddings)
Run Code Online (Sandbox Code Playgroud)

具体来说:

  1. Field为什么除了 之外,GloVe 嵌入还要加载到 中Embedding
  2. 我认为该Field函数build_vocab()只是根据训练数据构建词汇表。在此步骤中,GloVe 嵌入是如何参与的?

以下是其他未回答我问题的 StackOverflow 问题:

PyTorch / Gensim - 如何加载预训练的词嵌入

嵌入到pytorch中

PyTorch LSTM - 使用词嵌入代替 nn.Embedding()

谢谢你的帮助。

Mic*_*ngo 9

构建词汇表时torchtext,它将标记索引与嵌入对齐。如果您的词汇表的大小和顺序与预训练的嵌入不同,则无法保证索引匹配,因此您可能会查找不正确的嵌入。build_vocab()使用相应的嵌入为数据集创建词汇表,并丢弃其余的嵌入,因为这些嵌入未使用。

GloVe-6B 嵌入包含大小为 400K 的词汇表。例如,IMDB 数据集仅使用其中约 120K,其余 280K 未使用。

import torch
from torchtext import data, datasets, vocab

TEXT = data.Field(tokenize='spacy', include_lengths=True)
LABEL = data.LabelField()

train_data, test_data = datasets.IMDB.splits(TEXT, LABEL)
TEXT.build_vocab(train_data, vectors='glove.6B.100d')

TEXT.vocab.vectors.size() # => torch.Size([121417, 100])

# For comparison the full GloVe
glove = vocab.GloVe(name="6B", dim=100)
glove.vectors.size() # => torch.Size([400000, 100])

# Embedding of the first token is not the same
torch.equal(TEXT.vocab.vectors[0], glove.vectors[0]) # => False

# Index of the word "the"
TEXT.vocab.stoi["the"] # => 2
glove.stoi["the"] # => 0

# Same embedding when using the respective index of the same word
torch.equal(TEXT.vocab.vectors[2], glove.vectors[0]) # => True
Run Code Online (Sandbox Code Playgroud)

在使用嵌入构建词汇表后,输入序列将以标记化版本给出,其中每个标记都由其索引表示。在模型中,您想要使用这些的嵌入,因此您需要创建嵌入层,但要使用词汇表的嵌入。最简单也是推荐的方式是nn.Embedding.from_pretrained,与 Keras 版本基本相同。

embedding_layer = nn.Embedding.from_pretrained(TEXT.vocab.vectors)

# Or if you want to make it trainable
trainable_embedding_layer = nn.Embedding.from_pretrained(TEXT.vocab.vectors, freeze=False)
Run Code Online (Sandbox Code Playgroud)

您没有提到embedding_matrixKeras 版本中如何创建 ,也没有提到如何构建词汇表以便可以与embedding_matrix. 如果您手动(或使用任何其他实用程序)执行此操作,则torchtext根本不需要,并且可以像在 Keras 中一样初始化嵌入。torchtext纯粹是为了方便常见的数据相关任务。