python - 在 Pytorch F.nll_loss() 中预期的类型为 torch.LongTensor 的对象,但为参数 #2 'target' 找到了类型 torch.FloatTensor
问题描述
为什么会出现这个错误。
我正在尝试编写一个自定义损失函数,它最终具有负对数可能性。
根据我的理解,NLL 是在两个概率值之间计算的?
>>> loss = F.nll_loss(sigm, trg_, ignore_index=250, weight=None, size_average=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home//lib/python3.5/site-packages/torch/nn/functional.py", line 1332, in nll_loss
return torch._C._nn.nll_loss(input, target, weight, size_average, ignore_index, reduce)
RuntimeError: Expected object of type torch.LongTensor but found type torch.FloatTensor for argument #2 'target'
这里的输入如下:
>>> sigm.size()
torch.Size([151414, 80])
>>> sigm
tensor([[ 0.3283, 0.6472, 0.8278, ..., 0.6756, 0.2168, 0.5659],
[ 0.6603, 0.5957, 0.8375, ..., 0.2274, 0.4523, 0.4665],
[ 0.5262, 0.4223, 0.5009, ..., 0.5734, 0.3151, 0.2076],
...,
[ 0.4083, 0.2479, 0.5996, ..., 0.8355, 0.6681, 0.7900],
[ 0.6373, 0.3771, 0.6568, ..., 0.4356, 0.8143, 0.4704],
[ 0.5888, 0.4365, 0.8587, ..., 0.2233, 0.8264, 0.5411]])
我的目标张量是:
>>> trg_.size()
torch.Size([151414])
>>> trg_
tensor([-7.4693e-01, 3.5152e+00, 2.9679e-02, ..., 1.6316e-01,
3.6594e+00, 1.3366e-01])
如果我将其转换为 long 我会丢失所有数据:
>>> sigm.long()
tensor([[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
...,
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0]])
>>> trg_.long()
tensor([ 0, 3, 0, ..., 0, 3, 0])
如果我将目标张量的原始值也转换为sigmoid
:
>>> F.sigmoid(trg_)
tensor([ 0.3215, 0.9711, 0.5074, ..., 0.5407, 0.9749, 0.5334])
>>> loss = F.nll_loss(sigm, F.sigmoid(trg_), ignore_index=250, weight=None, size_average=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/lib/python3.5/site-packages/torch/nn/functional.py", line 1332, in nll_loss
return torch._C._nn.nll_loss(input, target, weight, size_average, ignore_index, reduce)
RuntimeError: Expected object of type torch.LongTensor but found type torch.FloatTensor for argument #2 'target'
这确实可以愉快地计算损失,但再次相信我在长时间转换中丢失了数据:
>>> loss = F.nll_loss(sigm, F.sigmoid(trg_).long(), ignore_index=250, weight=None, size_average=True)
>>> loss
tensor(-0.5010)
>>> F.sigmoid(trg_).long()
tensor([ 0, 0, 0, ..., 0, 0, 0])
解决方案
“根据我的理解,NLL是在两个概率值之间计算的?”
不,NLL 不是在两个概率值之间计算的。根据pytorch 文档 (参见形状部分),它通常用于实现交叉熵损失。当 N 是数据大小且 C 是类数时,它接受的输入预期是对数概率并且大小为 (N, C)。目标是一个大小为 (N,) 的长张量,它告诉样本的真实类别。
由于在您的情况下,目标肯定不是真正的类,因此您可能必须实现自己的损失版本,并且您可能无法使用 NLLLoss。如果你添加更多关于你想要编码的损失的详细信息,我可以帮助/解释更多关于如何做到这一点(如果可能的话,通过使用 torch 中的现有函数)。
推荐阅读
- python - 从 Python 中的二维数组获取非零数据和位置
- html - 为什么 Font Awesome SVG 图标的这种简单颜色变化不起作用?
- python - firebase 无法保存我尝试导入的所有数据
- if-statement - 如果不使用语句
- c# - 如何更有效地传递大小 jsonPayload?
- javascript - 在 React 中实现事件处理程序
- python - 当使用 csv.writer 将特定列写入新文件时,循环会遍历每个字符
- google-bigquery - BigQuery - 混合架构:无法将 STRING 类型的字段读取为 DATETIME
- python - Python configparser 从 S3 读取配置而不下载
- go - 如果一个切片改变,两个切片都会改变