'RuntimeError: Expected object of scalar type Long but got scalar type Float for argument #2 'target'

I'm running into an issue while calculating the loss for my Neural Net. I'm not sure why the program expects a long object because all my Tensors are in float form. I looked at threads with similar errors and the solution was to cast Tensors as floats instead of longs, but that wouldn't work in my case because all my data is already in float form when passed to the network.

Here's my code:

# Dataloader
from torch.utils.data import Dataset, DataLoader

class LoadInfo(Dataset):    
    def __init__(self, prediction, indicator):  
        self.prediction = prediction
        self.indicator = indicator
    def __len__(self):
        return len(self.prediction)
    def __getitem__(self, idx):
        data = torch.tensor(self.indicator.iloc[idx, :],dtype=torch.float)
        data = torch.unsqueeze(data, 0)
        label = torch.tensor(self.prediction.iloc[idx, :],dtype=torch.float)
        sample = {'data': data, 'label': label} 
        return sample

# Trainloader
test_train = LoadInfo(train_label, train_indicators)
trainloader = DataLoader(test_train, batch_size=64,shuffle=True, num_workers=1,pin_memory=True) 

# The Network
class NetDense2(nn.Module):

    def __init__(self):
        super(NetDense2, self).__init__()
        self.rnn1 = nn.RNN(11, 100, 3)  
        self.rnn2 = nn.RNN(100, 500, 3)  
        self.fc1 = nn.Linear(500, 100)  
        self.fc2 = nn.Linear(100, 20)
        self.fc3 = nn.Linear(20, 3)

    def forward(self, x):
        x1, h1 = self.rnn1(x)
        x2, h2 = self.rnn2(x1)
        x = F.relu(self.fc1(x2))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# Allocate / Transfer to GPU      
dense2 = NetDense2()
dense2.cuda()

# Optimizer
import torch.optim as optim
criterion = nn.CrossEntropyLoss()                                 # specify the loss function
optimizer = optim.SGD(dense2.parameters(), lr=0.001, momentum=0.9,weight_decay=0.001)

# Training
dense2.train()
loss_memory = []
for epoch in range(50):  # loop over the dataset multiple times
    running_loss = 0.0
    for i, samp in enumerate(trainloader):
        # get the inputs
        ins = samp['data']
        targets = samp['label']
        tmp = []
        tmp = torch.squeeze(targets.float())
        ins, targets = ins.cuda(),  tmp.cuda()
        # zero the parameter gradients
        optimizer.zero_grad()
        # forward + backward + optimize
        outputs = dense2(ins)
        loss = criterion(outputs, targets)     # The loss
        loss.backward()
        optimizer.step()
        # keep track of loss
        running_loss += loss.data.item()

I get the error from above in the line " loss = criterion(outputs, targets) "



Solution 1:[1]

As per the documentation and official example at pytorch webpage, The targets passed to nn.CrossEntropyLoss() should be in torch.long format

# official example
import torch
import torch.nn as nn
loss = nn.CrossEntropyLoss()
input = torch.randn(3, 5, requires_grad=True)
target = torch.empty(3, dtype=torch.long).random_(5) 

# if you will replace the dtype=torch.float, you will get error

output = loss(input, target)
output.backward()

update this line in your code as

label = torch.tensor(self.prediction.iloc[idx, :],dtype=torch.long) #updated torch.float to torch.long

Solution 2:[2]

Small workaround to your code would be something like this:

for epoch in range(50):  # loop over the dataset multiple times
running_loss = 0.0
for i, samp in enumerate(trainloader):
    # get the inputs
    ins = samp['data']
    targets = samp['label'].long() # HERE IS THE CHANGE <<---------------
    tmp = []
    tmp = torch.squeeze(targets.float())
    ins, targets = ins.cuda(),  tmp.cuda()
    # zero the parameter gradients
    optimizer.zero_grad()
    # forward + backward + optimize
    outputs = dense2(ins)
    loss = criterion(outputs, targets)     # The loss
    loss.backward()
    optimizer.step()
    # keep track of loss
    running_loss += loss.data.item()

Solution 3:[3]

A simple fix which worked for me by replacing

loss = criterion(outputs, targets)

with

loss = criterion(outputs, targets.long())

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mughees
Solution 2 Prajot Kuvalekar
Solution 3 homelessmathaddict