PyTorch:将词向量加载到字段词汇表与嵌入层
PyTorch: Loading word vectors into Field vocabulary vs. Embedding layer
我正从 Keras 转到 PyTorch。 我想创建一个 PyTorch 嵌入层(大小为 V x D
的矩阵,其中 V
是词汇索引,D
是嵌入矢量维度)与 GloVe 向量,但对所需的步骤感到困惑。
在 Keras 中,you can load the GloVe vectors 通过让嵌入层构造函数采用 weights
参数:
# Keras code.
embedding_layer = Embedding(..., weights=[embedding_matrix])
在查看 PyTorch 和 TorchText 库时,我看到嵌入应该加载 两次 ,一次在 Field
中,然后在 [=17] 中再次加载=]层。这是我发现的sample code:
# 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)
具体来说:
- 除了
Embedding
之外,为什么还要在 Field
中加载 GloVe 嵌入?
- 我认为
Field
函数 build_vocab()
只是从训练数据中构建词汇表。在此步骤中,GloVe 嵌入如何参与?
以下是 没有 回答我的问题的其他 Whosebug 问题:
Embedding in pytorch
感谢您的帮助。
当 torchtext
构建词汇表时,它会将标记索引与嵌入对齐。如果您的词汇表与预训练嵌入的大小和顺序不同,则无法保证索引匹配,因此您可能会查找不正确的嵌入。 build_vocab()
使用相应的嵌入为您的数据集创建词汇表并丢弃其余的嵌入,因为它们未被使用。
GloVe-6B 嵌入包含一个大小为 400K 的词汇表。例如 IMDB dataset 只使用其中的大约 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
使用嵌入构建词汇表后,输入序列将以标记化版本给出,其中每个标记均由其索引表示。在模型中你想使用这些的嵌入,所以你需要创建嵌入层,但要使用你的词汇表的嵌入。最简单也是推荐的方式是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)
您没有提到 embedding_matrix
是如何在 Keras 版本中创建的,也没有提到词汇表是如何构建的以便它可以与 embedding_matrix
一起使用。如果您手动(或使用任何其他实用程序)执行此操作,则根本不需要 torchtext
,并且您可以像在 Keras 中一样初始化嵌入。 torchtext
纯粹是为了方便常见的数据相关任务。
我正从 Keras 转到 PyTorch。 我想创建一个 PyTorch 嵌入层(大小为 V x D
的矩阵,其中 V
是词汇索引,D
是嵌入矢量维度)与 GloVe 向量,但对所需的步骤感到困惑。
在 Keras 中,you can load the GloVe vectors 通过让嵌入层构造函数采用 weights
参数:
# Keras code.
embedding_layer = Embedding(..., weights=[embedding_matrix])
在查看 PyTorch 和 TorchText 库时,我看到嵌入应该加载 两次 ,一次在 Field
中,然后在 [=17] 中再次加载=]层。这是我发现的sample code:
# 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)
具体来说:
- 除了
Embedding
之外,为什么还要在Field
中加载 GloVe 嵌入? - 我认为
Field
函数build_vocab()
只是从训练数据中构建词汇表。在此步骤中,GloVe 嵌入如何参与?
以下是 没有 回答我的问题的其他 Whosebug 问题:
Embedding in pytorch
感谢您的帮助。
当 torchtext
构建词汇表时,它会将标记索引与嵌入对齐。如果您的词汇表与预训练嵌入的大小和顺序不同,则无法保证索引匹配,因此您可能会查找不正确的嵌入。 build_vocab()
使用相应的嵌入为您的数据集创建词汇表并丢弃其余的嵌入,因为它们未被使用。
GloVe-6B 嵌入包含一个大小为 400K 的词汇表。例如 IMDB dataset 只使用其中的大约 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
使用嵌入构建词汇表后,输入序列将以标记化版本给出,其中每个标记均由其索引表示。在模型中你想使用这些的嵌入,所以你需要创建嵌入层,但要使用你的词汇表的嵌入。最简单也是推荐的方式是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)
您没有提到 embedding_matrix
是如何在 Keras 版本中创建的,也没有提到词汇表是如何构建的以便它可以与 embedding_matrix
一起使用。如果您手动(或使用任何其他实用程序)执行此操作,则根本不需要 torchtext
,并且您可以像在 Keras 中一样初始化嵌入。 torchtext
纯粹是为了方便常见的数据相关任务。