IndexError: index is out of bounds for dimension 0

Hi,

I have problem with IndexError on evaluation model. I use transfer learning on VGG16 and I replaced last layer for nn.Linear(4096, 264), because I have 264 classes.

I got IndexError: index 43352 is out of bounds for dimension 0 with size 32218

My length of test_dataset is 32218.

Here is my code of splitting into train and test set:

train_size = int(0.8 * len(mvc_dataset))
test_size = len(mvc_dataset) - train_size
train_dataset, test_dataset = torch.utils.data.random_split(mvc_dataset, [train_size, test_size])


num_train = len(train_dataset)
indices = list(range(num_train))
split = int(np.floor(0.20 * num_train))
np.random.shuffle(indices)

train_idx, test_idx = indices[split:], indices[:split]
train_sampler = SubsetRandomSampler(train_idx)
test_sampler = SubsetRandomSampler(test_idx)


train_loader = nc.SafeDataLoader(train_dataset,
                          sampler=train_sampler, batch_size=1)
test_loader = nc.SafeDataLoader(test_dataset,
                         sampler=test_sampler, batch_size=1)

And when I got error:

    for images, annotations in test_loader:
        images = Variable(images.cuda() if torch.cuda.is_available() else images, requires_grad=True)
        annotations = Variable(annotations.cuda() if torch.cuda.is_available() else annotations)

        outputs = model(images)
        _, predicted = torch.max(outputs)
        total += annotations.size[0]
        correct += (predicted == annotations).sum().item()

Any know, what should I do in this situation?

I think the problem comes from you using both the torch.utils.data.random_split and SubsetRandomSampler solutions.

The first one gives you two datasets, of (roughly) 80% and 20% of the size of the original dataset. Then you shuffle all the indices and split them (with quite possibly a different split than the first random_split), which you feed into the SubsetRandomSampler.

This doesn’t work, because you could have any index (from 0 to len(mvc_dataset) - 1) attributed to the test_sampler. However, since the test_sampler is only (roughly) 20% of the mvc_dataset, you get the error. This error probably gives you different indices each time (unless there’s a seed setup somewhere).

The solution would be using either of the two solutions. If you simply want to randomly split your dataset in train and test sets and shuffle them separately, use torch.utils.data.random_split and something like DataLoader(shuffle=True).

1 Like

Thanks, It’s works, but now I got error:

TypeError: iteration over a 0-d tensor

in line:

_, predicted = torch.max(outputs)
    for images, annotations in val_loader:
        images = Variable(images.cuda() if torch.cuda.is_available() else images, requires_grad=True)
        annotations = Variable(annotations.cuda() if torch.cuda.is_available() else annotations)

        outputs = model(images)
        _, predicted = torch.max(outputs)
        total += annotations.size[0]
        correct += (predicted == annotations).sum().item()

Do I have add 1 after outputs for example: _, predicted = torch.max(outputs, 1)?

Indeed, if you want the predictions (argmax) as well, you need the dim parameter set. The actual value depends on the shape of your outputs tensor.

Ok, It’s all correct, but after this error I got last:

RuntimeError: The size of tensor a (64) must match the size of tensor b (264) at non-singleton dimension 1

I use pretrained VGG16 network as follow and my batch size is equal 64:

# Load pre-trained model, then cut off its last layer and freeze its weights
model = models.vgg16(pretrained=True)
for param in model.parameters():
    param.requires_grad = False

# Add custom fully-connected layer with 4096 neurons for the hidden layer
model.fc = nn.Linear(4096, 264).to(device)

What line throws the error? Could you paste a more complete stacktrace?

This line throw this error.

correct += (predicted == annotations).sum().item()

I also try without .item() and it does not work.

I’m guessing that the variables predicted and annotations don’t have the same shape. Could you print their respective shape, just before that line is called?

Also, I think comparing tensors this way does not work. Apparently, predicted.eq(annotations).sum().item() might be what you’re looking for.

1 Like

predicted = torch.Size([1])
annotations = torch.Size([1, 264])

I’m guessing you are working on multi-class single-label classification, with 264 classes but only one target per input, right?

In that case, you need to check if the prediction is the correct one, so check if your prediction is the same as the index in your one-hot target vector!

Something like that should work:

_, predicted = torch.max(outputs, 1)
_, target = torch.max(annotations, 1)
correct += predicted.eq(target).sum().item()
1 Like

Yeah! It’s working!!! Thanks!!! So what is now the best way to calculate the accuracy in this task?

1 Like

Good to know it works now :slight_smile:

I usually use something similar to this, which enables you to compute accuracy at different ranks (the topk argument, e.g. topk=(1, 3, 5) for ranks 1, 3 and 5):

def accuracy(output, target, topk=(1,)):
    """Computes the precision@k for the specified values of k"""
    maxk = max(topk)
    batch_size = target.size(0)

    _, pred = output.topk(maxk, 1, True, True)
    pred = pred.t()
    correct = pred.eq(target.view(1, -1).expand_as(pred))

    res = []
    for k in topk:
        correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
        res.append(correct_k.mul_(100.0 / batch_size))
return res

This version was found here, I don’t know if this is the real original though.

Now, my predicted values on first line, and target values on second, and so on…

If i printed correct value, I get 0. Why?

Seems like the model has not converged yet, keep training it and, if everything is setup correctly, it should slowly increase accuracy :blush:

I think so! :slight_smile:

Here is my labels: