[solved] Assertion `cur_target >= 0 && cur_target < n_classes' failed

Hi guys, I am trying to learn Pytorch by using it for the Titanic kaggle competition. I completed the intro CIFAR-10 tutorial and decided to try to build a simple fully connected neural net. The problem is that I keep running into this error: ‘Assertion `cur_target >= 0 && cur_target < n_classes’ failed.’. I think I am loading the data correctly (I tried to apply the Data Loading and Processing tutorial) and I believe I have correctly set up the neural net. Of course, there’s always the chance that I’m missing something completely obvious and it’s a quick fix. I have attached my jupyter notebook.

btw I am running this on macOS High Sierra with Python 3.6 and Anaconda without CUDA.

Thanks!

Brian

import torch
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
train_file = open("./data/train.csv", "r")
train = pd.read_csv(train_file)
def process(df):
    df_X = df.join(pd.get_dummies(train['Pclass'], prefix="class"))
    df_X = df_X.join(pd.get_dummies(train['Sex']))
    df_X = df_X.join(pd.get_dummies(train['Embarked'], prefix="port"))
    df_X = df_X.join(pd.get_dummies(train['SibSp'], prefix="sibsp"))
    df_X = df_X.join(pd.get_dummies(train['Parch'], prefix="parch"))
    
    df_Y = train['Survived']
    
    df_X.drop(['Survived', 'Name', 'PassengerId', 'Sex', 'Embarked',
                  'SibSp', 'Parch', 'Cabin', 'Ticket'], axis=1, inplace=True)
    
    return df_X, df_Y
train_X, train_y = process(train)
print(train_X.shape)
print(train_Y.shape)
(891, 25)
(891,)
train_X.head()
.dataframe thead tr:only-child th { text-align: right; }
.dataframe thead th {
    text-align: left;
}

.dataframe tbody tr th {
    vertical-align: top;
}
Pclass Age Fare class_1 class_2 class_3 female male port_C port_Q ... sibsp_4 sibsp_5 sibsp_8 parch_0 parch_1 parch_2 parch_3 parch_4 parch_5 parch_6
0 3 22.0 7.2500 0 0 1 0 1 0 0 ... 0 0 0 1 0 0 0 0 0 0
1 1 38.0 71.2833 1 0 0 1 0 1 0 ... 0 0 0 1 0 0 0 0 0 0
2 3 26.0 7.9250 0 0 1 1 0 0 0 ... 0 0 0 1 0 0 0 0 0 0
3 1 35.0 53.1000 1 0 0 1 0 0 0 ... 0 0 0 1 0 0 0 0 0 0
4 3 35.0 8.0500 0 0 1 0 1 0 0 ... 0 0 0 1 0 0 0 0 0 0

5 rows × 25 columns

train_Y.head()
0    0
1    1
2    1
3    1
4    0
Name: Survived, dtype: int64
import os
from torch.utils.data import Dataset, DataLoader
class TitanicDataset(Dataset):

    def __init__(self, X, Y):
        self.X = X
        self.Y = Y

    def __len__(self):
        return len(self.X)

    def __getitem__(self, idx):
        X = self.X.iloc[idx].as_matrix().astype('double')
        X = X.reshape(-1, 25)
        Y = self.Y.iloc[idx].astype('double')

        return torch.from_numpy(X).double(), int(Y)
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(25, 100)
        self.fc2 = nn.Linear(100, 100)
        self.fc3 = nn.Linear(100, 50)
        self.fc4 = nn.Linear(50, 20)
        self.fc5 = nn.Linear(20, 10)
        self.fc6 = nn.Linear(10, 1)

    def forward(self, x):
        x = self.fc1(x).clamp(min=0)
        x = F.relu(self.fc2(x))
        x = F.relu(self.fc3(x))
        x = F.relu(self.fc4(x))
        x = F.relu(self.fc5(x))
        x = self.fc6(x)
        return x


net = Net()
import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
dataset = TitanicDataset(train_X, train_Y)
dataloader = DataLoader(dataset, batch_size=4,
                        shuffle=True, num_workers=4)
print(dataloader.dataset[0][0].shape)
print(dataloader.dataset[0][0].size())
print(type(dataloader.dataset[0][0]))
print(type(dataloader.dataset[0][1]))
torch.Size([1, 25])
torch.Size([1, 25])
<class 'torch.DoubleTensor'>
<class 'int'>
for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(dataloader, 0):
        # get the inputs
        inputs, labels = data

        # wrap them in Variable
        inputs, labels = Variable(inputs.float()), Variable(labels.float())

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        labels = labels.long()
        loss = criterion(outputs[:,0], labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.data[0]
        if i % 100 == 99:    # print every 100 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 100))
            running_loss = 0.0
''
print('Finished Training')
---------------------------------------------------------------------------

RuntimeError                              Traceback (most recent call last)

<ipython-input-375-f4e44e3f5cbb> in <module>()
     15         outputs = net(inputs)
     16         labels = labels.long()
---> 17         loss = criterion(outputs[:,0], labels)
     18         loss.backward()
     19         optimizer.step()


/Users/brian/anaconda/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    222         for hook in self._forward_pre_hooks.values():
    223             hook(self, input)
--> 224         result = self.forward(*input, **kwargs)
    225         for hook in self._forward_hooks.values():
    226             hook_result = hook(self, input, result)


/Users/brian/anaconda/lib/python3.6/site-packages/torch/nn/modules/loss.py in forward(self, input, target)
    480         _assert_no_grad(target)
    481         return F.cross_entropy(input, target, self.weight, self.size_average,
--> 482                                self.ignore_index)
    483 
    484 


/Users/brian/anaconda/lib/python3.6/site-packages/torch/nn/functional.py in cross_entropy(input, target, weight, size_average, ignore_index)
    744                 True, the loss is averaged over non-ignored targets.
    745     """
--> 746     return nll_loss(log_softmax(input), target, weight, size_average, ignore_index)
    747 
    748 


/Users/brian/anaconda/lib/python3.6/site-packages/torch/nn/functional.py in nll_loss(input, target, weight, size_average, ignore_index)
    670     dim = input.dim()
    671     if dim == 2:
--> 672         return _functions.thnn.NLLLoss.apply(input, target, weight, size_average, ignore_index)
    673     elif dim == 4:
    674         return _functions.thnn.NLLLoss2d.apply(input, target, weight, size_average, ignore_index)


/Users/brian/anaconda/lib/python3.6/site-packages/torch/nn/_functions/thnn/auto.py in forward(ctx, input, target, *args)
     45         output = input.new(1)
     46         getattr(ctx._backend, update_output.name)(ctx._backend.library_state, input, target,
---> 47                                                   output, *ctx.additional_args)
     48         return output
     49 


RuntimeError: Assertion `cur_target >= 0 && cur_target < n_classes' failed.  at /Users/soumith/miniconda2/conda-bld/pytorch_1503975723910/work/torch/lib/THNN/generic/ClassNLLCriterion.c:62

1 Like

It’s may be your linear layer’s demension problem.Try squeeze or unsqueee it.

1 Like

I fixed it! Although it didn’t have anything to do with squeeze() or unsqueeze(), I still thank you @quoniammm because I was unaware of squeeze() and unsqueeze() and they seem very useful! Turns out it was a quick fix. I had to change self.fc6 = nn.Linear(10, 1) to self.fc6 = nn.Linear(10, 2) in my Net class.

9 Likes

My pleasure.It’s nice that I can help you.

2 Likes

did you discover what the error even means and why your fix worked?

I had the same error. The error is saying that the labels must be 0 indexed.

So, for example, if you have 20 classes, and the labels are 1th indexed, the 20th label would be 20, so cur_target < n_classes assert would fail. If it’s 0th indexed, the 20th label is 19, so cur_target < n_classes assert passes.

9 Likes

Thank you for this tip ! I was having the exact same problem and I had [0…8] clases in my dataset and In my network I forgot to pay attention on the lengh of the unique classes (9 classes) :sweat_smile:

2 Likes

I had the same error and realized the output number was wrong as well. In the final layer, ensure your output matches the number of classifications your model will be making.

4 Likes

I also run into this error when computing a loss on GPU, but the error is "Unable to get repr for <class ‘torch.Tensor’>. After I move the prediction and truth to cpu and call the F.cross_entropy again. I see the informative error, “cur_target…”.

Im classifying music files in 10 classes and I labelled them from 1,2,3…,9,0.
Now i used this dataser for softmax regression where it worked perfectly when i just wanted to classify for any number of classes but when i used neural networks to classify it into first 3 classes it didnt work and gave same error. Any comments onwhy it didnt give error in case of softmax regression for 3 classes and gave error in neural networks for 3 class classification?
Thank you in advance!

Yep! Same happened with me too. Thanks!! :grinning:

Thank you, this was the needed answer. Build a wrapper class for loading CIFAR-10 and CIFAR-100. With a look on the output layer I saw I was on CIFAR-10 but loaded CIFAR-100.

Hi, I have same problem look this is my model

VGG(
  (features): Sequential(
    (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): ReLU(inplace=True)
    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (3): ReLU(inplace=True)
    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (6): ReLU(inplace=True)
    (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (8): ReLU(inplace=True)
    (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU(inplace=True)
    (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (13): ReLU(inplace=True)
    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (15): ReLU(inplace=True)
    (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (18): ReLU(inplace=True)
    (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (20): ReLU(inplace=True)
    (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (22): ReLU(inplace=True)
    (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (25): ReLU(inplace=True)
    (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (27): ReLU(inplace=True)
    (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (29): ReLU(inplace=True)
    (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(7, 7))
  (classifier): Sequential(
    (0): Linear(in_features=25088, out_features=64, bias=True)
    (1): ReLU()
    (2): Dropout(p=0.25, inplace=False)
    (3): Linear(in_features=64, out_features=32, bias=True)
    (4): ReLU()
    (5): Dropout(p=0.25, inplace=False)
    (6): Linear(in_features=32, out_features=6, bias=True)
  )
)

when I print(dataset…class_to_idx) i get

{'0-9': 0, '10-19': 1, '20-29': 2, '30-39': 3, '40-49': 4, '50-inf': 5}

What kind of dataset are you using and what data does your target contain?
The printed mapping looks a bit weird and I am not sure, how you’ve created it.

I had this problem as I had classes 0,1,2,…,9 and 10, and my network had only 10 outputs instead of 11.

Here is a recreation of the problem
The below code works fine

>>> loss = nn.CrossEntropyLoss()
>>> input = torch.randn(3, 5, requires_grad=True)
>>> target = torch.empty(3, dtype=torch.long).random_(5)
>>> output = loss(input, target)

But this wont work

>>> loss = nn.CrossEntropyLoss()
>>> input = torch.randn(3, 5, requires_grad=True)
>>> target = torch.empty(3, dtype=torch.long).random_(100)
>>> output = loss(input, target)

This is because target can be [0,5,99].
The target is screaming at you, that your 3rd sample is the 100th class.
But if you look at your input there is only 5 classes. Meaning target value should in range [0-4].

cheers