Deep learning 序列间丢失
我想弄清楚如何计算顺序间的损失。在本例中,我使用的是huggingface transformers库,但这实际上可能与其他DL库相关 因此,为了获得所需的数据,我们可以:Deep learning 序列间丢失,deep-learning,pytorch,huggingface-transformers,Deep Learning,Pytorch,Huggingface Transformers,我想弄清楚如何计算顺序间的损失。在本例中,我使用的是huggingface transformers库,但这实际上可能与其他DL库相关 因此,为了获得所需的数据,我们可以: 从transformers导入EncoderCodermodel,BertTokenizer 进口火炬 导入torch.nn.功能为F 手电筒。手动种子(42) 标记器=BertTokenizer.from_pretrained('bert-base-uncased')) 最大长度=128 tokenize=lambda x
从transformers导入EncoderCodermodel,BertTokenizer
进口火炬
导入torch.nn.功能为F
手电筒。手动种子(42)
标记器=BertTokenizer.from_pretrained('bert-base-uncased'))
最大长度=128
tokenize=lambda x:tokenizer(x,max_length=max_LEN,truncation=True,padding=True,return_tensors=“pt”)
model=encoderCodermodel。从“编码器”到“解码器”预训练(“bert-base-uncased”,“bert-base-uncased”)#从预先训练的检查点初始化Bert2Bert
input_seq=[“你好,我的狗很可爱”,“我的猫很可爱”]
输出顺序=[“是的”,“确定”]
输入标记=标记化(输入顺序)
输出标记=标记化(输出顺序)
输出=模型(
输入标识=输入标识[“输入标识”],
注意屏蔽=输入令牌[“注意屏蔽”],
解码器输入标识=输出标识[“输入标识”],
解码器\u注意\u掩码=输出\u令牌[“注意\u掩码”],
标签=输出令牌[“输入标识”],
返回(dict=True)
idx=输出令牌[“输入令牌”]
logits=F.log\u softmax(输出[“logits”],dim=-1)
掩码=输出令牌[“注意掩码”]
编辑1
多亏了@cronoik,我才能够将huggingface计算的损失复制为:
output_logits=logits[:,:-1,:]
输出_掩码=掩码[:,:-1]
label_-tokens=输出_-tokens[“输入_-id”][:,1:]。取消查询(-1)
选择\u logits=torch.gather(输出\u logits,-1,标记\u令牌)。挤压()
huggingface\u loss=-select\u logits.mean()
但是,由于第二个输入的最后两个标记只是填充,我们不应该将损失计算为:
seq_loss=(选择_logits*output_mask).sum(dim=-1,keepdims=True)/output_mask.sum(dim=-1,keepdims=True)
seq_损失=-seq_损失平均值()
^这将考虑到每行输出序列的长度,以及通过掩蔽它而进行的填充。当我们有成批不同长度的输出时,我认为这特别有用。好的,我找到了我犯错误的地方。这一切都要感谢你
-100
。transoformers图书馆不为您提供这项服务output\u mask=mask[:,1://code>而不是:-1
labels=output_令牌[“input_id”].clone()
标签[output_tokens[“attention_mask”]==0]=-100
输出=模型(
输入标识=输入标识[“输入标识”],
注意屏蔽=输入令牌[“注意屏蔽”],
解码器输入标识=输出标识[“输入标识”],
解码器\u注意\u掩码=输出\u令牌[“注意\u掩码”],
标签=标签,
返回(dict=True)
2.计算损失
因此,复制它的最终方法如下:
idx=output\u令牌[“input\u id”]
logits=F.log\u softmax(输出[“logits”],dim=-1)
掩码=输出令牌[“注意掩码”]
#转移东西
output_logits=logits[:,:-1,:]
label_tokens=idx[:,1::]。取消查询(-1)
输出屏蔽=屏蔽[:,1:]
#收集日志和掩码
选择\u logits=torch.gather(输出\u logits,-1,标记\u令牌)。挤压()
-选择\u logits[output\u mask==1].mean(),output[“loss”]
然而,上面忽略了一个事实,即这来自两条不同的线路。因此,计算损失的另一种方法可以是:
seq_loss=(选择_logits*output_mask).sum(dim=-1,keepdims=True)/output_mask.sum(dim=-1,keepdims=True)
seq_损失平均值()
。