Em_*_*Em_ 3 python nlp neural-network pytorch
我使用 Chris McCormick 关于 BERT 的教程来pytorch-pretained-bert获得句子嵌入,如下所示:
tokenized_text = tokenizer.tokenize(marked_text)
indexed_tokens = tokenizer.convert_tokens_to_ids(tokenized_text)
segments_ids = [1] * len(tokenized_text)
tokens_tensor = torch.tensor([indexed_tokens])
segments_tensors = torch.tensor([segments_ids])
model = BertModel.from_pretrained('bert-base-uncased')
model.eval()
with torch.no_grad():
encoded_layers, _ = model(tokens_tensor, segments_tensors)
# Holds the list of 12 layer embeddings for each token
# Will have the shape: [# tokens, # layers, # features]
token_embeddings = []
# For each token in the sentence...
for token_i in range(len(tokenized_text)):
# Holds 12 layers of hidden states for each token
hidden_layers = []
# For each of the 12 layers...
for layer_i in range(len(encoded_layers)):
# Lookup the vector for `token_i` in `layer_i`
vec = encoded_layers[layer_i][batch_i][token_i]
hidden_layers.append(vec)
token_embeddings.append(hidden_layers)
Run Code Online (Sandbox Code Playgroud)
现在,我尝试通过对最后 4 层求和来获得最终的句子嵌入,如下所示:
summed_last_4_layers = [torch.sum(torch.stack(layer)[-4:], 0) for layer in token_embeddings]
Run Code Online (Sandbox Code Playgroud)
但我没有得到长度为 768 的单个火炬矢量,而是得到以下结果:
[tensor([-3.8930e+00, -3.2564e+00, -3.0373e-01, 2.6618e+00, 5.7803e-01,
-1.0007e+00, -2.3180e+00, 1.4215e+00, 2.6551e-01, -1.8784e+00,
-1.5268e+00, 3.6681e+00, ...., 3.9084e+00]), tensor([-2.0884e+00, -3.6244e-01, ....2.5715e+00]), tensor([ 1.0816e+00,...-4.7801e+00]), tensor([ 1.2713e+00,.... 1.0275e+00]), tensor([-6.6105e+00,..., -2.9349e-01])]
Run Code Online (Sandbox Code Playgroud)
我在这里得到了什么?如何合并最后一层的总和?
谢谢你!
您可以使用迭代的列表理解来创建列表token_embeddings。它是一个列表,其中每个标记包含一个张量 - 而不是您可能想象的那样每层一个张量(从您的来看for layer in token_embeddings)。因此,您将获得一个长度等于标记数量的列表。对于每个 token,您都有一个向量,它是最后 4 层的 BERT 嵌入的总和。
更有效的方法是避免显式的 for 循环和列表推导:
\nsummed_last_4_layers = torch.stack(encoded_layers[-4:]).sum(0)\nRun Code Online (Sandbox Code Playgroud)\n现在,变量summed_last_4_layers包含相同的数据,但以单个维度张量的形式:句子的长度\xc3\x97 768。
要获得单个(即池化)向量,您可以对张量的第一维进行池化。在这种情况下,最大池化或平均池化可能比对所有令牌嵌入求和更有意义。在对值求和时,不同长句子的向量处于不同的范围内,并且没有真正的可比性。
\n| 归档时间: |
|
| 查看次数: |
4559 次 |
| 最近记录: |