Error: Target 4 is out of bounds. Using cross entropy loss

I am newbie in pytorch, I am trying to create a convolutional neural network with my own data but I have a problem running the cross entropy loss function. I am not sure but maybe it is due to the structure of my data. Data train contains 16X16 arrays that simulate 9 channel images, hence the train_x has structure of (4608,9,16,16), the labels of this data of (4608). The validation data has dimension of (521,9,16,16) and labels of (512).

importing the libraries

import pandas as pd
import numpy as np

for reading and displying images

from skimage.io import imread
import matplotlib.pyplot as plt
%matplotlib inline

for creating validation set

from sklearn.model_selection import train_test_split

for evaluating the model

from sklearn.metrics import accuracy_score
from tqdm import tqdm

PyTorch libraries and modules

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

check if CUDA is available

train_on_gpu = torch.cuda.is_available()
if not train_on_gpu:
print(‘CUDA is not available. Training on CPU …’)
else:
print(‘CUDA is available! Training on GPU …’)
train_data=images_training

test_data=images_testing
train_x = np.array(train_data)
test_x = np.array(test_data)

#agregando las etiquetas, es decir, identificando a qué clase pertenece cada imagen
train_y = np.array(label_train)
test_y = np.array(label_test)
#creando un set de validación, estos datos los tomamos de los datos de entrenamiento

train_x, val_x, train_y, val_y = train_test_split(train_x, train_y, test_size = 0.1)

convirtiendo las imagenes de ENTRENAMIENTO al formato torch para su manejo dentro de la red

#train_x tiene la forma (4608,9,16,16)
train_x = torch.from_numpy(train_x)

convirtiendo las etiquetas de cada imagen en formato torch

train_y = train_y.astype(int);
train_y = torch.from_numpy(train_y)

estructura de los datos de entrenamiento

train_x.shape, train_y.shape

convirtiendo las imagenes de VALIDACIÓN al formato torch para su manejo dentro de la red

#train_x tiene la forma (521,9,16,16)
val_x = torch.from_numpy(val_x)

converting the target into torch format

val_y = val_y.astype(int);
val_y = torch.from_numpy(val_y)

class Net(nn.Module):
def init(self):
super(Net, self).init()
# Defining a 2D convolution layer

    #convirtiendo la imagen de profundidad 9 a 16 con un kernel de 3x3
    self.conv1=nn.Conv2d(9, 16, kernel_size=3, stride=1, padding=1)

    #convirtiendo la imagen de profundidad 16 a 32 con un kernel de 3x3
    self.conv2=nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1)

    #convirtiendo la imagen de profundidad 32 a 64 con un kernel de 3x3
    #self.conv3=nn.Conv2d(36, 72, kernel_size=3, stride=1, padding=1)

    #Capa macpooling
    self.pool=nn.MaxPool2d(2,2)

    #la dimensión de la imagen era de 16*16 después de la primera pool tengo 8*8 después de la segunda 4*4 despuès de la tercera 2*2

    self.fc1=nn.Linear(72*4*4, 256)
    self.fc2=nn.Linear(256,4)
    self.dropout=nn.Dropout(0.25)
    

# Defining the forward pass    

def forward(self, x):
    #agregando la secuencia de las capas de convolución y maxpooling
    x = self.pool(F.relu(self.conv1(x)))
    x = self.pool(F.relu(self.conv2(x)))
    #x = self.pool(F.relu(self.conv3(x)))
    #flatten, convitiéndolo a forma de vector
    x=x.view(-1,72*4*4)

    #agregando la capa de dropout para prevenir sobreajuste
    x=self.dropout(x)
    #pasando la primera capa oculta con la activación relu
    x=F.relu(self.fc1(x))
    #agregando la capa de dropout para prevenir sobreajuste
    x=self.dropout(x)
   #agregando la segunda capa oculta del fully connectec para obtener la clasificación  
    x=self.fc2(x)
    return x

#Creando la CNN
model= Net()
print (model)
#moviéndolo a una GPU en caso de que tenga CUDA disponible
if train_on_gpu:
model.cuda()
criterion = criterion.cuda()
#Definiendo que usaremos la función de perdida

criterion=nn.CrossEntropyLoss()
#especificando un optimizador con un gradiente descendiente estocástico y una
#tasa de aprendizaje de 0.01

optimizer=optim.SGD(model.parameters(),lr=0.01)
def train(epoch):

###################

# train the model #

###################

model.train()
tr_loss = 0
# getting the training set
x_train, y_train = Variable(train_x), Variable(train_y)
# getting the validation set
x_val, y_val = Variable(val_x), Variable(val_y)
# converting the data into GPU format
if torch.cuda.is_available():
    x_train = x_train.cuda()
    y_train = y_train.cuda()
    x_val = x_val.cuda()
    y_val = y_val.cuda()


# clear the gradients of all optimized variables
optimizer.zero_grad()
# forward pass: compute predicted outputs by passing inputs to the model
output_train = model(x_train.float().squeeze(1))
output_val = model(x_val.float().squeeze(1))
print('train ',x_train.shape, 'label ', y_train.shape, 'prediccion ', output_train )
print(output_train)

# computing the training and validation loss
loss_train = criterion(output_train, y_train)
print(loss_train)
loss_val = criterion(output_val, y_val)
print(loss_val)
train_losses.append(loss_train)
val_losses.append(loss_val)
#En esta sección se actualizan los pesos praa todos los modelos
# backward pass: compute gradient of the loss with respect to model parameters

loss_train.backward()
# perform a single optimization step (parameter update)
optimizer.step()
# update training loss
tr_loss = loss_train.item()
print('Epoch: {} \tTraining Loss: {:.5f} \tValidation Loss: {:.5f}'.format(
    epoch, loss_train, loss_val))

defining the number of epochs

n_epochs = 10

empty list to store training losses

train_losses = []

empty list to store validation losses

val_losses = []

training the model

for epoch in range(n_epochs):
train(epoch)

This is the mistake
/usr/local/lib/python3.7/dist-packages/torch/nn/functional.py in cross_entropy(input, target, weight, size_average, ignore_index, reduce, reduction)
2822 if size_average is not None or reduce is not None:
2823 reduction = _Reduction.legacy_get_string(size_average, reduce)
→ 2824 return torch._C._nn.cross_entropy_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
2825
2826

IndexError: Target 4 is out of bounds.

Your model yields an output in the shape [batch_size, 4] (defined by the last linear layer) which contains logits for 4 classes. The target should thus contain class indices in the range [0, 3] and an index of 4 will be out of bounds. I’m not familiar with your use case, but in case your target contains 5 unique class indices, the model output should also have the shape [batch_size, nb_classes=5].

PS: you can post code snippets by wrapping them into three backticks ```, which makes debugging easier. :wink:

1 Like

That was the problem, thank you very much for your help, I appreciate it.