Pytorch - RuntimeError: ожидаемый объект скалярного типа Long, но получил скалярный тип Float для аргумента № 2 «цель» при вызове _thnn_nll_loss_forward

Я пробовал и экспериментировал с PyTorch, где я создавал свои собственные входы и цели. Я передал эти входные данные модели (которая представляет собой базовую ИНС с двумя скрытыми слоями, в этом нет ничего плохого). Но по какой-то причине я не могу вычислить CrossEntropyLoss(). Я не могу понять, почему. Я знаю, что некоторые другие вопросы на StakcOverflow имеют такое же название, как у меня, или имеют аналогичную проблему. Я прошел через это, но у меня ничего не получилось. У многих людей были проблемы с набором данных, что не похоже на мою проблему.

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

class Net(nn.Module):
    def __init__(self) -> None:
        super(Net, self).__init__()
        self.layer1 = nn.Linear(2, 10)
        self.layer2 = nn.Linear(10, 1)

    def forward(self, x):
        x = F.relu(self.layer1(x))
        x = self.layer2(x)
        return x
    
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = Net().to(device=device)
loss_fn = nn.CrossEntropyLoss()
learning_rate = 1e-3
epochs = 20
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
inputs = torch.Tensor([
    [0,0],
    [0,1],
    [1,0],
    [1,1]
], ).to(device=device)

targets = torch.Tensor([
    0,
    1,
    1,
    0
]).to(device=device)

model.train()
for epoch in range(epochs):

    pred_output = model(inputs)
    print(pred_output.dtype)
    print(targets.dtype)
    loss = loss_fn(pred_output, targets)
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    print()
    break

Ошибка, которую я вижу,

torch.float32
torch.float32
Traceback (most recent call last):
  File ".\main.py", line 57, in <module>
    loss = loss_fn(pred_output, targets)
  File "C:\Users\user\anaconda3\lib\site-packages\torch\nn\modules\module.py", line 889, in _call_impl
    result = self.forward(*input, **kwargs)
  File "C:\Users\user\anaconda3\lib\site-packages\torch\nn\modules\loss.py", line 1047, in forward
    return F.cross_entropy(input, target, weight=self.weight,
  File "C:\Users\user\anaconda3\lib\site-packages\torch\nn\functional.py", line 2693, in cross_entropy
    return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
  File "C:\Users\user\anaconda3\lib\site-packages\torch\nn\functional.py", line 2388, in nll_loss
    ret = torch._C._nn.nll_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
RuntimeError: Expected object of scalar type Long but got scalar type Float for argument #2 'target' in call to _thnn_nll_loss_forward

person imharjyotbagga    schedule 05.07.2021    source источник


Ответы (1)


Я мог бы воспроизвести вашу ошибку, используя этот код.

import torch.nn as nn
loss = nn.CrossEntropyLoss()
input = torch.randn(3, 5, requires_grad=True)
target = torch.tensor([1., 2., 3.])
loss(input, target)

Ошибка:

RuntimeError: ожидался скалярный тип Long, но найдено значение Float

изменил тип данных цели на target = torch.tensor([1., 2., 3.], dtype=torch.long) и все заработало нормально. Я считаю, что целевая переменная требует длинного типа данных, потому что изменение ввода на float также будет работать.

#this will also work
input = torch.randn(3, 5, requires_grad=True, dtype=torch.float)
target = torch.tensor([1., 2., 3.], dtype=torch.long)
loss(input, target)  

Обратите внимание, что в документации также есть этот torch.long dtype в примере кода. https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html

#Редактировать 1 Причина, по которой это не работает, заключается в том, как вы определили входные/целевые тензоры в своем коде. Используйте torch.tensor с маленькой буквой «т» вместо torch.Tensor. Подробное обсуждение см. в В чем разница между torch. тензор и факел.Тензор?.

#this will work. Also notice the decimal. otherwise it will be interpreted differently by pytorch
inputs = torch.tensor([[0.,0.],[0.,1.],[1.,0.],[1.,1.]]).to(device=device)
targets = torch.tensor([0.,1.,1.,0.], dtype=torch.long).to(device=device)
person dufrmbgr    schedule 05.07.2021
comment
Я пробовал это, py targets = torch.Tensor([ 0, 1, 1, 0 ], dtype=torch.long).to(device=device) - person imharjyotbagga; 05.07.2021
comment
Но все же столкнулся с другой проблемой, cmd Traceback (most recent call last): File ".\main.py", line 44, in <module> targets = torch.Tensor([ TypeError: new() received an invalid combination of arguments - got (list, dtype=torch.dtype), but expected one of: * (*, torch.device device) didn't match because some of the keywords were incorrect: dtype * (torch.Storage storage) * (Tensor other) * (tuple of ints size, *, torch.device device) * (object data, *, torch.device device) - person imharjyotbagga; 05.07.2021
comment
Извините за плохое форматирование. - person imharjyotbagga; 05.07.2021
comment
У меня нет проблем с добавлением to(device=device). что вы используете - «процессор» или «куда»? - person dufrmbgr; 05.07.2021
comment
cuda, сейчас я использую графический процессор - person imharjyotbagga; 05.07.2021
comment
хм. Я использовал процессор, и он работал. Это также проснулось с графическим процессором, если я не назначу цель устройству. - person dufrmbgr; 05.07.2021
comment
Всю программу обновлю в квесте, попробуй запустить - person imharjyotbagga; 05.07.2021
comment
Я отредактировал ответ, чтобы устранить новую ошибку. - person dufrmbgr; 05.07.2021