在 Pytorch 中使用带有 nn.Embedding 的 Autograd 时出现问题

数据挖掘 深度学习 词嵌入 火炬
2022-02-19 06:13:47

我在logits对输入进行输出导数方面遇到了麻烦input_ids这是我的输入示例:

# input_ids is a list of token ids got from BERT tokenizer
input_ids = torch.tensor([101., 1996., 2833., 2003., 2779., 1024., 6350., 102.], requires_grad=True)

content_outputs = self.bert(input_ids,
                        position_ids=position_ids, token_type_ids=token_type_ids,
                        attention_mask=attention_mask, head_mask=head_mask)

# content_outputs[1] is sentence embedding
logits = F.linear(content_outputs[1], self.W_s, self.b_s)

# Notes:
# - input_ids.dtype = torch.float32
# - input_ids.is_leaf = True
# - input_ids.requires_grad = True
# - Torch version: 1.0.1

要计算 的梯度input_idsinput_ids.dtype必须是浮点数;否则,我将收到以下错误:

RuntimeError:只有浮点 dtype 的张量才能需要渐变

但是,我的模型正在使用一个嵌入层,dtype=long如果我使用上面用浮点类型初始化的 input_ids,它需要输入会导致另一个问题:

RuntimeError:参数#1 'indices' 的预期张量具有标量类型 Long;但得到了 torch.FloatTensor (在检查嵌入参数时)

我也在 Stack Overflow 和 Stack Exchange 上进行了搜索,但没有发现与此问题相关的内容。请帮我解决一下这个。任何意见将不胜感激!

1个回答

所以,这只是一半的答案,我把它写在这里是为了能够清楚地格式化文本。您正面临麻烦,因为您正在尝试做一些您不应该做的事情,即将梯度应用于索引而不是嵌入。当使用嵌入(所有类型,不仅是 BERT)时,在将它们输入模型之前,句子必须用嵌入索引表示,这些索引只是与特定嵌入向量相关联的数字。这些索引只是将单词映射到向量的值,您永远不会对它们应用任何操作,尤其是您永远不会训练它们,因为它们不是参数。

['Just an example...'] # text
       |
       | Words are turned into indices 
       v
[1., 2., 3., 4., 4., 4.] # indices, tensor type long, no sense in applying gradient here
       |
       | Indices are used to retrieve the real embedding vectors
       v
[0.3242, 0.2354, 0.8763, 0.4325, 0.4325, 0.4325] # embeddings, tensor type float, this is what you want to train

如果你想为特定任务微调 BERT,我建议你看看这个教程BERT-fine-tuning