【问题标题】:Pytorch RuntimeError: "host_softmax" not implemented for 'torch.cuda.LongTensor'Pytorch RuntimeError:“host_softmax”未为“torch.cuda.LongTensor”实现
【发布时间】:2019-01-19 22:35:55
【问题描述】:

我正在使用 pytorch 来训练模型。但是在计算交叉熵损失时出现运行时错误。

Traceback (most recent call last):
  File "deparser.py", line 402, in <module>
    d.train()
  File "deparser.py", line 331, in train
    total, correct, avgloss = self.train_util()
  File "deparser.py", line 362, in train_util
    loss = self.step(X_train, Y_train, correct, total)
  File "deparser.py", line 214, in step
    loss = nn.CrossEntropyLoss()(out.long(), y)
  File "/home/summer2018/TF/lib/python3.5/site-packages/torch/nn/modules/module.py", line 477, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/summer2018/TF/lib/python3.5/site-packages/torch/nn/modules/loss.py", line 862, in forward
    ignore_index=self.ignore_index, reduction=self.reduction)
  File "/home/summer2018/TF/lib/python3.5/site-packages/torch/nn/functional.py", line 1550, in cross_entropy
    return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
  File "/home/summer2018/TF/lib/python3.5/site-packages/torch/nn/functional.py", line 975, in log_softmax
    return input.log_softmax(dim)
RuntimeError: "host_softmax" not implemented for 'torch.cuda.LongTensor'

我认为这是因为.cuda() 函数或torch.Floattorch.Long 之间的转换。但是我尝试了很多方法来通过.cpu()/.cuda().long()/.float()来改变变量,但还是不行。在谷歌上搜索时找不到此错误消息。任何人都可以帮助我吗?谢谢!!!

这是导致错误的代码:

def step(self, x, y, correct, total):
    self.optimizer.zero_grad()
    out = self.forward(*x)
    loss = nn.CrossEntropyLoss()(out.long(), y)
    loss.backward()
    self.optimizer.step()
    _, predicted = torch.max(out.data, 1)
    total += y.size(0)
    correct += int((predicted == y).sum().data)
    return loss.data

这个函数step()被调用:

def train_util(self):
    total = 0
    correct = 0
    avgloss = 0
    for i in range(self.step_num_per_epoch):
        X_train, Y_train = self.trainloader()
        self.optimizer.zero_grad()
        if torch.cuda.is_available():
            self.cuda()
            for i in range(len(X_train)):
                X_train[i] = Variable(torch.from_numpy(X_train[i]))
                X_train[i].requires_grad = False
                X_train[i] = X_train[i].cuda()
            Y_train = torch.from_numpy(Y_train)
            Y_train.requires_grad = False
            Y_train = Y_train.cuda()
        loss = self.step(X_train, Y_train, correct, total)
        avgloss+=float(loss)*Y_train.size(0)
        self.optimizer.step()
        if i%100==99:
            print('STEP %d, Loss: %.4f, Acc: %.4f'%(i+1,loss,correct/total))

    return total, correct, avgloss/self.data_len

输入数据X_train, Y_train = self.trainloader()一开始是numpy数组。

这是一个数据样本:

>>> X_train, Y_train = d.trainloader()
>>> X_train[0].dtype
dtype('int64')
>>> X_train[1].dtype
dtype('int64')
>>> X_train[2].dtype
dtype('int64')
>>> Y_train.dtype
dtype('float32')
>>> X_train[0]
array([[   0,    6,    0, ...,    0,    0,    0],
       [   0, 1944, 8168, ...,    0,    0,    0],
       [   0,  815,  317, ...,    0,    0,    0],
       ...,
       [   0,    0,    0, ...,    0,    0,    0],
       [   0,   23,    6, ...,    0,    0,    0],
       [   0,    0,  297, ...,    0,    0,    0]])
>>> X_train[1]
array([ 6,  7,  8, 21,  2, 34,  3,  4, 19, 14, 15,  2, 13,  3, 11, 22,  4,
   13, 34, 10, 13,  3, 48, 18, 16, 19, 16, 17, 48,  3,  3, 13])
>>> X_train[2]
array([ 4,  5,  8, 36,  2, 33,  5,  3, 17, 16, 11,  0,  9,  3, 10, 20,  1,
   14, 33, 25, 19,  1, 46, 17, 14, 24, 15, 15, 51,  2,  1, 14])
>>> Y_train
array([[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., 1.],
       [0., 0., 0., 1., 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.],
       [1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       ...,
       [0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]],
      dtype=float32)

尝试所有可能的组合:

案例1:
loss = nn.CrossEntropyLoss()(out, y)
我得到:
RuntimeError: Expected object of type torch.cuda.LongTensor but found type torch.cuda.FloatTensor for argument #2 'target'

案例2:
loss = nn.CrossEntropyLoss()(out.long(), y)
如上所述

案例3:
loss = nn.CrossEntropyLoss()(out.float(), y)
我得到:
RuntimeError: Expected object of type torch.cuda.LongTensor but found type torch.cuda.FloatTensor for argument #2 'target'

案例4:
loss = nn.CrossEntropyLoss()(out, y.long())
我得到:
RuntimeError: multi-target not supported at /pytorch/aten/src/THCUNN/generic/ClassNLLCriterion.cu:15

案例5:
loss = nn.CrossEntropyLoss()(out.long(), y.long())
我得到:
RuntimeError: "host_softmax" not implemented for 'torch.cuda.LongTensor'

案例6:
loss = nn.CrossEntropyLoss()(out.float(), y.long())
我得到:
RuntimeError: multi-target not supported at /pytorch/aten/src/THCUNN/generic/ClassNLLCriterion.cu:15

案例7:
loss = nn.CrossEntropyLoss()(out, y.float())
我得到:
RuntimeError: Expected object of type torch.cuda.LongTensor but found type torch.cuda.FloatTensor for argument #2 'target'

案例8:
loss = nn.CrossEntropyLoss()(out.long(), y.float())
我得到:
RuntimeError: "host_softmax" not implemented for 'torch.cuda.LongTensor'

案例9:
loss = nn.CrossEntropyLoss()(out.float(), y.float())
我得到:
RuntimeError: Expected object of type torch.cuda.LongTensor but found type torch.cuda.FloatTensor for argument #2 'target'

【问题讨论】:

  • 所以,您正在使用长张量计算 CrossEntropyLoss。你能分享一个导致这种情况的特定数据样本吗?您如何尝试将其转换为浮点数? y是什么格式?
  • 嗨!谢谢你的意见!我在上面的描述中添加了数据格式。下面的 cmets 是我尝试将其转换为 float 的方式:
  • 案例1:loss = nn.CrossEntropyLoss()(out, y)我得到:RuntimeError: Expected object of type torch.cuda.LongTensor but found type torch.cuda.FloatTensor for argument #2 'target'
  • 案例 2:loss = nn.CrossEntropyLoss()(out.long(), y) 如上所述
  • 哦!我知道问题出在哪里。 y 应该在 torch.int64 dtype 中,没有 one-hot 编码。并且 CrossEntropyLoss() 将使用 one-hot 对其进行自动编码(而out 是预测的概率分布,如 one-hot 格式)。现在可以运行了!谢谢你的帮助!

标签: deep-learning pytorch


【解决方案1】:

好的,每当我在类似的线路上出现错误时,这对我有用(我会保留在这里以供参考):

  1. 在输入上调用模型时,确保 x 为浮点数。
  2. 不过,要让你的目标越久越好。
  3. 模型输出和 y 的调用丢失,没有任何类型转换。
from torch import nn
net = nn.Linear(input, out_classes)
loss_criterion = nn.CrossEntropyLoss()

net = net.to(device)
X = X.to(device).float()
y = y.to(device).long()

y_hat = net(X)
l = loss_criterion(y_hat, y)

【讨论】:

    【解决方案2】:

    在我的情况下,这是因为我已经翻转了 targetslogits 并且由于 logits 显然不是 torch.int64 它引发了错误。

    【讨论】:

      【解决方案3】:

      我知道问题出在哪里。

      y 应该在 torch.int64 dtype 中,没有 one-hot 编码。 而CrossEntropyLoss() 将使用 one-hot 自动对其进行编码(而 out 是预测的概率分布,如 one-hot 格式)。

      现在可以运行了!

      【讨论】:

      猜你喜欢
      • 2019-03-26
      • 2019-01-11
      • 2019-12-26
      • 2020-06-13
      • 2023-01-17
      • 2021-07-18
      • 2021-06-09
      • 2021-04-13
      • 2020-11-10
      相关资源
      最近更新 更多