Criterion Target is out of bounds

doublesobig: <p>I found a model that looked appealing to me at:<br>
<a href="https://towardsdatascience.com/how-to-train-an-image-classifier-in-pytorch-and-use-it-to-perform-basic-inference-on-single-images-99465a1e9bf5" rel="noopener nofollow ugc">https://towardsdatascience.com/how-to-train-an-image-classifier-in-pytorch-and-use-it-to-perform-basic-inference-on-single-images-99465a1e9bf5</a></p>
<p>As a start I copied nearly everything from this website.<br>
Firstly I want to explain my train and test datasets.</p>
<p>My Train Dataset contains some chinese signs as bitmaps with unknown “meaning” ( I am looking for unicode escapes)<br>
My Test Dataset contains the range of simplified chinese characters as bitmaps (escape sequences are known).</p>
<p>I thought it would be better to do it this way as there are more than 22000 signs in simplified chinese. For training I would have needed more than one image per sign resulting in like 130000 pictures for training.<br>
I only have 225 unknown bitmaps. By doing so I only have 225*6 pictures for training which I thought would be way better for performance.</p>
<p>Here is where I changed the code from the website:</p>
<pre><code>def load_train_test():

    normalize = transforms.Normalize(mean=[0.5,],
                                     std=[0.5,])

    img_transforms = transforms.Compose([transforms.Resize(224),
                                         transforms.CenterCrop(224),
                                         transforms.ToTensor(),
                                         normalize])

    train_data = datasets.ImageFolder(TRAIN_DS,
                                      transform = img_transforms)

    test_data = datasets.ImageFolder(TEST_DS,
                                     transform = img_transforms)

    train_loader = torch.utils.data.DataLoader(train_data, batch_size=64)
    test_loader = torch.utils.data.DataLoader(test_data, batch_size=64)

    return train_loader, test_loader
</code></pre>
<p>In the example he created labels from SubsetRandomSampler().</p>
<p>Now I receive following error message:</p>
<blockquote>
<p>Exception has occurred: IndexError<br>
Target 10 is out of bounds.</p>
</blockquote>
<p>The error occurs when I try to calculate loss at</p>
<blockquote>
<p>loss = criterion(logps, labels)</p>
</blockquote>
<p>Here is the code snippet (line 7)</p>
<pre><code>for epoch in range(epochs):
    for inputs, labels in train_loader:
        steps += 1
        inputs, labels = inputs.to(device), labels.to(device)
        optimizer.zero_grad()
        logps = model.forward(inputs)
        loss = criterion(logps, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()

        if steps % print_every == 0:
            test_loss = 0
            accuracy = 0
            model.eval()
            with torch.no_grad():
                for inputs, labels in test_loader:
                    inputs, labels = inputs.to(device), labels.to(device)
                    logps = model.forward(inputs)
                    batch_loss = criterion(logps, labels)
                    test_loss += batch_loss.item()

                    ps = torch.exp(logps)
                    top_p, top_class = ps.topk(1, dim=1)
                    equals = top_class == lavels.view(*top_class.shape)
                    accuracy = torch.mean(equals.type(torch.FloatTensor)).item()
        
            train_losses.append(running_loss/len(train_loader))
            test_losses.append(test_loss/len(test_loader))
            print(f"Epoch {epoch+1}/{epochs}.."
                  f"Train loss: {running_loss/print_every:.3f}.."
                  f"Test loss: {test_loss/len(test_loader):.3f}.."
                  f"Test accuracy: {accuracy/len(test_loader):.3f}")
            running_loss = 0
            model.train()
torch.save(model, 'chinese.pth')
</code></pre>
<p>In debug mode I can see that there are some labels generated. I really don’t know why this error occurs.<br>
Maybe someone of you knows what I am doing wrong.<br>
Thanks for your time!</p>

ptrblck: <p>I assume you are using <code>nn.CrossEntropyLoss</code> as the <code>criterion</code>.<br>
In that case, the model output should contain logits and have the shape <code>[batch_size, nb_classes]</code>, while the target would have the shape <code>[batch_size]</code> and contain the class indices in the range <code>[0, nb_classes-1]</code>.<br>
The error is raised, if your target uses out-of-bounds class indices.<br>
E.g. for 10 classes, the valid target values would be <code>[0, 9]</code>, while you are trying to pass a <code>10</code> to the criterion.</p>
<p>Also, don’t call the <code>forward</code> method, as it will not call potentially registered hooks. Call the model directly instead: <code>output = model(inputs)</code>.</p>

doublesobig: <p>As criterion I use nn.NLLLoss.<br>
How can I fix the worng number of classes?<br>
I should have 225 classes so I’m not sure why its already failing at 10 classes.</p>
<p>Thank you for that hint, I changed the forward line</p>

ptrblck: <p>I guess the output of your model is not containing logits for all 225 classes, which would be defined by the last layer (<code>nn.Linear</code> in case you are working on a multi-class classification).<br>
Change the <code>out_features</code> to 225 and it should work.</p>

doublesobig: <p>This is my model description. Should I change</p>
<pre><code>model.fc = nn.Sequential(nn.Linear(2048, 512),
                         nn.ReLU(),
                         nn.Dropout(0.2),
                         nn.Linear(512, 10),
                         nn.LogSoftmax(dim=1))
</code></pre>
<p>to</p>
<pre><code>model.fc = nn.Sequential(nn.Linear(2048, 512),
                         nn.ReLU(),
                         nn.Dropout(0.2),
                         nn.Linear(512, 225),
                         nn.LogSoftmax(dim=1))
</code></pre>
<p>Edit:<br>
This creates the same error. Now Target 225 is out of bounds.<br>
Could this happen because I do not specify targets while I’m loading the images?</p>

doublesobig: <p>Okay I guess the part of</p>
<pre><code>if steps % print_every == 0:
</code></pre>
<p>is the problem.<br>
As my test dataset contains 22222 “classses”(22222 signs) I would need 22222  as <code>out_feature</code>. Since this has nothing to do with my problem I will delete it and figure out some evaluation process and then share my solution here again.<br>
As I simply copied this from the website I didn’t think of its purpose. I guess the best solution to this problem would be if I generate some more images of those 225 unknown images and test the accuracy of this neural net with them so the labels are fitting.</p>

ptrblck: <p>Your target index of 225 implies 226 classes (class indices would be in the range <code>[0, 225]</code>, which are 226 values), so your model should also return 226 output logits.</p>