Execution of convolution neural network - multiclassification

learner1234: <p>Hi coders</p>
<p>I am new to pytorch as I have just started today, I saw few examples in kaggle and try to adapt my cnn from tensorflow in torch to enable better gpu allocation. However, I am stuck in a shape problem</p>
<p>I want to balance the data in train and test dataset so I have used train_test_split, have I applied it in the correct way although it is not giving an error</p>
<p>Could someone help please?</p>
<p>I have defined the customdataset in other python file and importing it in the main module</p>
<pre><code class="lang-auto">
class CustomDataset(Dataset):

        def __init__(self, root_folder_path):

            self.root_folder_path = root_folder_path
            self.image_files = []
            self.labels = []


            # Collect image paths and corresponding labels

            folders = sorted([f for f in os.listdir(root_folder_path) if os.path.isdir(os.path.join(root_folder_path, f))])
            self.label_dict = {folder: i for i, folder in enumerate(folders)}


            for folder in folders:

                folder_path = os.path.join(root_folder_path, folder)
                image_files = sorted([f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f)) and f.endswith('.jpg')])
                self.image_files.extend([os.path.join(folder_path, img) for img in image_files])
                self.labels.extend([self.label_dict[folder]] * len(image_files))


            self.transform = transforms.Compose([
                transforms.ToPILImage(),
                transforms.Resize((900, 300)),
                transforms.Grayscale(),
                transforms.ToTensor(),
                transforms.Normalize(mean=[0.5], std=[0.5])
            ])

            

        def __len__(self):

            return len(self.image_files)


        def __getitem__(self, idx):

            image_path = self.image_files[idx]
            label = self.labels[idx]
            image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
            image = self.transform(image)
           

            return image, label
</code></pre>
<p>this is my main script</p>
<pre><code class="lang-auto">
if __name__ == '__main__':
    
    
    # Instantiate your custom dataset and dataloaders
    root_folder_path = r'W:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\image_dataset_300_900_10_classes'
    dataset = CustomDataset(root_folder_path)

    print("Labels:", sorted(dataset.label_dict.keys()))
    print("Total number of labels:", len(dataset.label_dict))


    # Display some images from each folder
    n_images_to_display = 4
    n_folders = len(dataset.label_dict)
    fig, ax = plt.subplots(n_images_to_display, n_folders, figsize=(n_folders * 4, n_images_to_display * 4))

    for i, (folder, label) in enumerate(dataset.label_dict.items()):
        folder_images = [dataset[i][0] for i, lbl in enumerate(dataset.labels) if lbl == label]
        indices_to_display = random.sample(range(len(folder_images)), min(n_images_to_display, len(folder_images)))
        for j, ind in enumerate(indices_to_display):
            ax[j, i].imshow(folder_images[ind].squeeze(), cmap='gray')  # Squeeze to remove the channel dimension for grayscale images
            ax[j, i].axis('off')
        ax[0, i].set_title(folder, fontsize=30)

    plt.show()
    fig.tight_layout(pad=0, w_pad=0, h_pad=0)

  

    from torch.utils.data import DataLoader, Subset
    from sklearn.model_selection import train_test_split

    TEST_SIZE = 0.2
    BATCH_SIZE = 64
    SEED = 42

    # Get the labels from the dataset
    labels = np.array([label for _, label in dataset])
    

    # generate indices: instead of the actual data we pass in integers instead
    train_indices, test_indices, _, _ = train_test_split(
        range(len(dataset)),
        labels,
        stratify=labels,
        test_size=TEST_SIZE,
        random_state=SEED
    )

    # generate subset based on indices
    train_split = Subset(dataset, train_indices)
    test_split = Subset(dataset, test_indices)
    print('Length of train_batch:',len(train_split))
    print('Length of test_batch:',len(test_split))

   
    # create batches
    train_loader = DataLoader(train_split, batch_size=BATCH_SIZE, num_workers=6,shuffle=True,pin_memory=True)
    test_loader = DataLoader(test_split, batch_size=BATCH_SIZE,num_workers=6,pin_memory=True)

    class ImageClassificationBase(nn.Module):
        
        def training_step(self, batch):
            images, labels = batch 
            out = self(images)                  # Generate predictions
            loss = F.cross_entropy(out, labels) # Calculate loss
            return loss
        
        def accuracy(outputs, labels):
            _, preds = torch.max(outputs, dim=1)
            return torch.tensor(torch.sum(preds == labels).item() / len(preds))
        
        def validation_step(self, batch):
            images, labels = batch 
            out = self(images)                    # Generate predictions
            loss = F.cross_entropy(out, labels)   # Calculate loss
            acc = accuracy(out, labels)           # Calculate accuracy
            return {'val_loss': loss.detach(), 'val_acc': acc}
            
        def validation_epoch_end(self, outputs):
            batch_losses = [x['val_loss'] for x in outputs]
            epoch_loss = torch.stack(batch_losses).mean()   # Combine losses
            batch_accs = [x['val_acc'] for x in outputs]
            epoch_acc = torch.stack(batch_accs).mean()      # Combine accuracies
            return {'val_loss': epoch_loss.item(), 'val_acc': epoch_acc.item()}
        
        def epoch_end(self, epoch, result):
            print("Epoch [{}], train_loss: {:.4f}, val_loss: {:.4f}, val_acc: {:.4f}".format(
                epoch, result['train_loss'], result['val_loss'], result['val_acc']))
            

    import torch.nn.init as init
    class ImageClassification(ImageClassificationBase):
        def __init__(self):
            super().__init__()
            self.network = nn.Sequential(
                #image size is [1,900,300] as [channel, height,width]
                nn.Conv2d(1, 32, kernel_size = 3, padding = 1),
                nn.LeakyReLU(0.01),
                nn.BatchNorm2d(32),
                nn.AvgPool2d(kernel_size=2, stride=2),

                nn.Conv2d(32,32, kernel_size = 3,  padding = 1),
                nn.LeakyReLU(0.01),
                nn.BatchNorm2d(32),
                nn.AvgPool2d(kernel_size=2, stride=2),
            
                nn.Conv2d(32, 64, kernel_size = 3, padding = 1),
                nn.LeakyReLU(0.01),
                nn.BatchNorm2d(64),
                nn.AvgPool2d(kernel_size=2, stride=2),
            
                nn.Conv2d(64 ,64, kernel_size = 3, padding = 1),
                nn.LeakyReLU(0.01),
                nn.BatchNorm2d(64),
                nn.AvgPool2d(kernel_size=2, stride=2),
                                    
                nn.Flatten(),
                nn.Dropout(0.3),

                nn.Linear(64 * 56 * 18, 64),  # Assuming input size after convolutional layers is 64 * 56 * 18
                nn.LeakyReLU(0.01),
                nn.BatchNorm1d(64),
                nn.Dropout(0.2),
            
                nn.Linear(64, 64),
                nn.LeakyReLU(0.01),
                nn.BatchNorm1d(64),
                nn.Dropout(0.2),
            
                nn.Linear(64, 10)  # Output layer
            )
            # Initialize the weights of convolutional layers
            self._initialize_weights()

        def _initialize_weights(self):
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    init.kaiming_uniform_(m.weight, mode='fan_in', nonlinearity='leaky_relu')
        
        def forward(self, xb):
            return self.network(xb)

    def get_default_device():
        """ Set Device to GPU or CPU"""
        if torch.cuda.is_available():
            return torch.device('cuda')
        else:
            return torch.device('cpu')
        

    def to_device(data, device):
        "Move data to the device"
        if isinstance(data,(list,tuple)):
            return [to_device(x,device) for x in data]
        return data.to(device,non_blocking = True)

    class DeviceDataLoader():
        """ Wrap a dataloader to move data to a device """
        
        def __init__(self, dl, device):
            self.dl = dl
            self.device = device
        
        def __iter__(self):
            """ Yield a batch of data after moving it to device"""
            for b in self.dl:
                yield to_device(b,self.device)
                
        def __len__(self):
            """ Number of batches """
            return len(self.dl)

    device = get_default_device()
    device

    torch.cuda.empty_cache()
    model = ImageClassification()

    random_seed = 99
    torch.manual_seed(random_seed)

    train_loader = DeviceDataLoader(train_loader, device)
    test_loader = DeviceDataLoader(test_loader, device)

    to_device(model, device)

    @torch.no_grad()
    def evaluate(model, val_loader):
        model.eval()
        outputs = [model.validation_step(batch) for batch in val_loader]
        return model.validation_epoch_end(outputs)

    def accuracy(outputs, labels):
        _, preds = torch.max(outputs, dim=1)
        return torch.tensor(torch.sum(preds == labels).item() / len(preds))

    def fit(epochs, lr, model, train_loader, val_loader, opt_func=torch.optim.RMSprop):
        history = []
        optimizer = opt_func(model.parameters(), lr)
        for epoch in range(epochs):
            # Training Phase 
            model.train()
            train_losses = []
            for batch in train_loader:
                loss = model.training_step(batch)
                train_losses.append(loss)
                loss.backward()
                optimizer.step()
                optimizer.zero_grad()
            # Validation phase
            result = evaluate(model, val_loader)
            result['train_loss'] = torch.stack(train_losses).mean().item()
            model.epoch_end(epoch, result)
            history.append(result)
        return history

    model=to_device(ImageClassification(),device)

    #initial evaluation of the model
    evaluate(model,test_loader)
</code></pre>
<p>data looks like this and my size of the image in the model is [1,900,300] where 1 stands for graychannel, 900 - height of the image in pixels, 300 - width of the image in pixels</p>
<p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/b/4/b41e867f9b671aa0855a173bc03b2c200ce29305.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/b41e867f9b671aa0855a173bc03b2c200ce29305" title="img_2228.jpg"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/b/4/b41e867f9b671aa0855a173bc03b2c200ce29305_2_170x500.jpeg" alt="img_2228.jpg" data-base62-sha1="pHploeV01VGY2Vi4wA8BT8sdQeV" width="170" height="500" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/b/4/b41e867f9b671aa0855a173bc03b2c200ce29305_2_170x500.jpeg, https://discuss.pytorch.org/uploads/default/optimized/3X/b/4/b41e867f9b671aa0855a173bc03b2c200ce29305_2_255x750.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/b/4/b41e867f9b671aa0855a173bc03b2c200ce29305_2_340x1000.jpeg 2x" data-dominant-color="585858"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">img_2228.jpg</span><span class="informations">840×2464 366 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>and the error is</p>
<pre><code class="lang-auto">  File "w:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\10 class cropped 300_900 runs\10_class_torch.py", line 236, in &lt;module&gt;
    evaluate(model,test_loader)
  File "C:\Users\smjobagc\AppData\Local\miniconda3\envs\FSV\lib\site-packages\torch\autograd\grad_mode.py", line 28, in decorate_context
    return func(*args, **kwargs)
  File "w:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\10 class cropped 300_900 runs\10_class_torch.py", line 206, in evaluate
    outputs = [model.validation_step(batch) for batch in val_loader]
  File "w:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\10 class cropped 300_900 runs\10_class_torch.py", line 206, in &lt;listcomp&gt;
    outputs = [model.validation_step(batch) for batch in val_loader]
  File "w:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\10 class cropped 300_900 runs\10_class_torch.py", line 92, in validation_step
    acc = accuracy(out, labels)           # Calculate accuracy
  File "w:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\10 class cropped 300_900 runs\10_class_torch.py", line 211, in accuracy
    return torch.tensor(torch.sum(preds == labels).item() / len(preds))
RuntimeError: The size of tensor a (64) must match the size of tensor b (10) at non-singleton dimension 1

</code></pre>
<p>Here is the drive link of the dataset: <a href="https://drive.google.com/drive/folders/1PsT9_HWX4snfgnhlwC6xM4rNjcoqXdk5?usp=drive_link" rel="noopener nofollow ugc">https://drive.google.com/drive/folders/1PsT9_HWX4snfgnhlwC6xM4rNjcoqXdk5?usp=drive_link</a></p>

ptrblck: <p>Could you describe the shapes of <code>preds</code> as well as <code>labels</code> and what these tensors contain?<br>
The error message points to a shape mismatch in <code>dim1</code>, which should represent the number of classes in the prediction and potentially the same in the targets if probabilities are used.</p>

learner1234: <p>thankyou <a class="mention" href="/u/ptrblck">@ptrblck</a> for the reply. Without the successful run, I think I cannot print the shape of preds but for labels if I try to print the shape in customdataset then it is again hanged for a while.<br>
labels are the names of folders containing images</p>
<p>also, the output shape from the model is <code>[batch_size, num_classes]</code>, where <code>batch_size</code>=64 is the number of samples in the batch and <code>num_classes</code>=10 is the number of classes your model is predicting. However, the shape of the <code>labels</code> tensor seems to be <code>[batch_size]</code>, where each element represents the class index for a sample.</p>
<p>Do I need to convert labels to one hot encoded labels ? I believe the labels get convert to one hot encoded label if we take loss as cross entropy</p>

ptrblck: <p>Based on the shapes you might need to create the predictions from the logits via <code>torch.argmax</code> as seen here:</p>
<pre data-code-wrap="python"><code class="lang-python">batch_size = 64
nb_classes = 10
preds = torch.randn(batch_size, nb_classes)
labels = torch.randint(0, nb_classes, (batch_size,))

preds == labels
# RuntimeError: The size of tensor a (10) must match the size of tensor b (64) at non-singleton dimension 1

(torch.argmax(preds, 1) == labels).sum()
# tensor(6)
</code></pre>

learner1234: <aside class="quote no-group" data-username="ptrblck" data-post="4" data-topic="198366">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/48/1823_2.png" class="avatar"> ptrblck:</div>
<blockquote>
<pre><code class="lang-auto">batch_size = 64
nb_classes = 10
preds = torch.randn(batch_size, nb_classes)
labels = torch.randint(0, nb_classes, (batch_size,))

preds == labels
# RuntimeError: The size of tensor a (10) must match the size of tensor b (64) at non-singleton dimension 1

(torch.argmax(preds, 1) == labels).sum()
# tensor(6)
</code></pre>
</blockquote>
</aside>
<p>I have tried few things though I read that it is useless to convert labels into one hot encoded if we are using loss as cross entropy but I want the labels size as [batch_size,num_classes] so I one-hot encode the labels and applied the correction as you have suggested</p>
<pre><code class="lang-auto">class CustomDataset(Dataset):

        def __init__(self, root_folder_path):

            self.root_folder_path = root_folder_path
            self.image_files = []
            self.labels = []


            # Collect image paths and corresponding labels

            folders = sorted([f for f in os.listdir(root_folder_path) if os.path.isdir(os.path.join(root_folder_path, f))])
            self.label_dict = {folder: i for i, folder in enumerate(folders)}


            for folder in folders:

                folder_path = os.path.join(root_folder_path, folder)
                image_files = sorted([f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f)) and f.endswith('.jpg')])
                self.image_files.extend([os.path.join(folder_path, img) for img in image_files])
                self.labels.extend([self.label_dict[folder]] * len(image_files))


            self.transform = transforms.Compose([
                transforms.ToPILImage(),
                transforms.Resize((900, 300)),
                transforms.Grayscale(),
                transforms.ToTensor(),
                transforms.Normalize(mean=[0.5], std=[0.5])
            ])

            

        def __len__(self):

            return len(self.image_files)


        def __getitem__(self, idx):

            image_path = self.image_files[idx]
            label = self.labels[idx]
            image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
            image = self.transform(image)
            #print("Image shape:", image.shape)  # Print the shape of the image
            one_hot_label = torch.zeros(len(self.label_dict))
            one_hot_label[label] = 1

            return image, one_hot_label
</code></pre>
<p>main script</p>
<pre><code class="lang-auto">from custom_dataset import CustomDataset
if __name__ == '__main__':
    
    
     # Instantiate your custom dataset and dataloaders
    root_folder_path = r'W:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\image_dataset_300_900_10_classes'
    dataset = CustomDataset(root_folder_path)

    print("Labels:", sorted(dataset.label_dict.keys()))
    print("Total number of labels:", len(dataset.label_dict))


    # Display some images from each folder
    n_images_to_display = 4
    n_folders = len(dataset.label_dict)
    fig, ax = plt.subplots(n_images_to_display, n_folders, figsize=(n_folders * 4, n_images_to_display * 4))

    for i, (folder, label) in enumerate(dataset.label_dict.items()):
        folder_images = [dataset[i][0] for i, lbl in enumerate(dataset.labels) if lbl == label]
        indices_to_display = random.sample(range(len(folder_images)), min(n_images_to_display, len(folder_images)))
        for j, ind in enumerate(indices_to_display):
            ax[j, i].imshow(folder_images[ind].squeeze(), cmap='gray')  # Squeeze to remove the channel dimension for grayscale images
            ax[j, i].axis('off')
        ax[0, i].set_title(folder, fontsize=30)

    plt.show()
    fig.tight_layout(pad=0, w_pad=0, h_pad=0)

  

    from torch.utils.data import DataLoader, Subset
    from sklearn.model_selection import train_test_split

    TEST_SIZE = 0.2
    BATCH_SIZE = 16
    SEED = 42

    # Get the labels from the dataset
    labels = np.array([label for _, label in dataset])
    

    # generate indices: instead of the actual data we pass in integers instead
    train_indices, test_indices, _, _ = train_test_split(
        range(len(dataset)),
        labels,
        stratify=labels,
        test_size=TEST_SIZE,
        random_state=SEED
    )

    # generate subset based on indices
    train_split = Subset(dataset, train_indices)
    test_split = Subset(dataset, test_indices)
    print('Length of train_batch:',len(train_split))
    print('Length of test_batch:',len(test_split))

   
    # create batches
    train_loader = DataLoader(train_split, batch_size=BATCH_SIZE, num_workers=2,shuffle=True,pin_memory=True)
    test_loader = DataLoader(test_split, batch_size=BATCH_SIZE,num_workers=2,pin_memory=True)

    for batch in train_loader:
        images, labels = batch
        print('Train batch size:', images.size())
        print('Shape of labels array:',labels.size())

    for batch in test_loader:
        images, labels = batch
        print('Test batch size:', images.size())
        print('Shape of labels array:',labels.size())
    
    class ImageClassificationBase(nn.Module):
        
        def training_step(self, batch):
            images, labels = batch 
            out = self(images)                  # Generate predictions
            loss = F.cross_entropy(out, labels) # Calculate loss
            return loss
        
        def accuracy(self,outputs, labels):
            #_, preds = torch.max(outputs, dim=1)
            
            preds = torch.argmax(outputs, dim=1)
            return torch.sum(preds.argmax(1) == labels).float().mean()
            
            #return torch.sum((preds == labels).float()).item() / batch
            #return torch.tensor(torch.sum(preds == labels).item() / len(preds))
        
        def validation_step(self, batch):
            images, labels = batch 
            out = self(images)                    # Generate predictions
            loss = F.cross_entropy(out, labels)   # Calculate loss
            acc = self.accuracy(out, labels)           # Calculate accuracy
            return {'val_loss': loss.detach(), 'val_acc': acc}
            
        def validation_epoch_end(self, outputs):
            batch_losses = [x['val_loss'] for x in outputs]
            epoch_loss = torch.stack(batch_losses).mean()   # Combine losses
            batch_accs = [x['val_acc'] for x in outputs]
            epoch_acc = torch.stack(batch_accs).mean()      # Combine accuracies
            return {'val_loss': epoch_loss.item(), 'val_acc': epoch_acc.item()}
        
        def epoch_end(self, epoch, result):
            print("Epoch [{}], train_loss: {:.4f}, val_loss: {:.4f}, val_acc: {:.4f}".format(
                epoch, result['train_loss'], result['val_loss'], result['val_acc']))
            

    import torch.nn.init as init
    class ImageClassification(ImageClassificationBase):
        def __init__(self):
            super().__init__()
            self.network = nn.Sequential(
                #image size is [1,900,300] as [channel, height,width]
                nn.Conv2d(1, 32, kernel_size = 3, padding = 1),
                nn.LeakyReLU(0.01),
                nn.BatchNorm2d(32),
                nn.AvgPool2d(kernel_size=2, stride=2),

                nn.Conv2d(32,32, kernel_size = 3,  padding = 1),
                nn.LeakyReLU(0.01),
                nn.BatchNorm2d(32),
                nn.AvgPool2d(kernel_size=2, stride=2),
            
                nn.Conv2d(32, 64, kernel_size = 3, padding = 1),
                nn.LeakyReLU(0.01),
                nn.BatchNorm2d(64),
                nn.AvgPool2d(kernel_size=2, stride=2),
            
                nn.Conv2d(64 ,64, kernel_size = 3, padding = 1),
                nn.LeakyReLU(0.01),
                nn.BatchNorm2d(64),
                nn.AvgPool2d(kernel_size=2, stride=2),
                                    
                nn.Flatten(),                
                nn.Dropout(0.3),

                nn.Linear(64 * 56 * 18, 64),  # Assuming input size after convolutional layers is 64 * 56 * 18
                nn.LeakyReLU(0.01),
                nn.BatchNorm1d(64),
                nn.Dropout(0.2),
            
                nn.Linear(64, 64),
                nn.LeakyReLU(0.01),
                nn.BatchNorm1d(64),
                nn.Dropout(0.2),
            
                nn.Linear(64, 10)  # Output layer
            )
            # Initialize the weights of convolutional layers
            self._initialize_weights()

        def _initialize_weights(self):
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    init.kaiming_uniform_(m.weight, mode='fan_in', nonlinearity='leaky_relu')
        
        def forward(self, xb):
            return self.network(xb)

    def get_default_device():
        #Set Device to GPU or CPU
        if torch.cuda.is_available():
            return torch.device('cuda')
        else:
            return torch.device('cpu')
        

    def to_device(data, device):
        "Move data to the device"
        if isinstance(data,(list,tuple)):
            return [to_device(x,device) for x in data]
        return data.to(device,non_blocking = True)

    class DeviceDataLoader():
        #Wrap a dataloader to move data to a device
        
        def __init__(self, dl, device):
            self.dl = dl
            self.device = device
        
        def __iter__(self):
            #Yield a batch of data after moving it to device
            for b in self.dl:
                yield to_device(b,self.device)
                
        def __len__(self):
            #Number of batches
            return len(self.dl)

    device = get_default_device()
    device

    torch.cuda.empty_cache()
    model = ImageClassification()

    random_seed = 99
    torch.manual_seed(random_seed)

    train_loader = DeviceDataLoader(train_loader, device)
    test_loader = DeviceDataLoader(test_loader, device)

    to_device(model, device)

    @torch.no_grad()
    def evaluate(model, val_loader):
        model.eval()
        outputs = [model.validation_step(batch) for batch in val_loader]
        return model.validation_epoch_end(outputs)

    
    def fit(epochs, lr, model, train_loader, val_loader, opt_func=torch.optim.RMSprop):
        history = []
        optimizer = opt_func(model.parameters(), lr)
        for epoch in range(epochs):
            # Training Phase 
            model.train()
            train_losses = []
            for batch in train_loader:
                loss = model.training_step(batch)
                train_losses.append(loss)
                loss.backward()
                optimizer.step()
                optimizer.zero_grad()
            # Validation phase
            result = evaluate(model, val_loader)
            result['train_loss'] = torch.stack(train_losses).mean().item()
            model.epoch_end(epoch, result)
            history.append(result)
        return history

    model=to_device(ImageClassification(),device)

    #initial evaluation of the model
    evaluate(model,test_loader)

    #set the no. of epochs, optimizer funtion and learning rate
    #num_epochs = 1
    #opt_func = torch.optim.RMSprop
    #lr = 0.0001

    #fitting the model on training data and record the result after each epoch
    #history = fit(num_epochs, lr, model, train_loader, test_loader, opt_func)
    
</code></pre>
<p>and now the output is</p>
<pre><code class="lang-auto">PS C:\Users\smjobagc&gt; &amp; c:/Users/smjobagc/AppData/Local/miniconda3/envs/FSV/python.exe "w:/MASTER_BAGCHI_SCHALDACH/THESIS/code and dataset/10 class cropped 300_900 runs/10_class_torch.py"
Labels: ['120', '144', '168', '192', '216', '24', '240', '48', '72', '96']
Total number of labels: 10
Length of train_batch: 1835
Length of test_batch: 459
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])    
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])    
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])    
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Train batch size: torch.Size([11, 1, 900, 300])
Shape of labels array: torch.Size([11, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([16, 1, 900, 300])
Shape of labels array: torch.Size([16, 10])
Test batch size: torch.Size([11, 1, 900, 300])
Shape of labels array: torch.Size([11, 10])
Traceback (most recent call last):
  File "w:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\10 class cropped 300_900 runs\10_class_torch.py", line 248, in &lt;module&gt;
    evaluate(model,test_loader)
  File "C:\Users\smjobagc\AppData\Local\miniconda3\envs\FSV\lib\site-packages\torch\autograd\grad_mode.py", line 28, in decorate_context
    return func(*args, **kwargs)
  File "w:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\10 class cropped 300_900 runs\10_class_torch.py", line 221, in evaluate
    outputs = [model.validation_step(batch) for batch in val_loader]
  File "w:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\10 class cropped 300_900 runs\10_class_torch.py", line 221, in &lt;listcomp&gt;
    outputs = [model.validation_step(batch) for batch in val_loader]
  File "w:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\10 class cropped 300_900 runs\10_class_torch.py", line 107, in validation_step
    acc = self.accuracy(out, labels)           # Calculate accuracy
  File "w:\MASTER_BAGCHI_SCHALDACH\THESIS\code and dataset\10 class cropped 300_900 runs\10_class_torch.py", line 98, in accuracy
    return torch.sum(preds.argmax(1) == labels).float().mean()
IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)
</code></pre>

ptrblck: <p>I don’t fully understand your code since now you are applying <code>torch.argmax</code> twice on the output:</p>
<pre data-code-wrap="python"><code class="lang-python">preds = torch.argmax(outputs, dim=1)
return torch.sum(preds.argmax(1) == labels).float().mean()
</code></pre>
<p>while you also claim you are using one-hot encoded targets.<br>
My code snippet shows the expected and working shapes so you could compare the shapes of all tensors and check why your code is failing now.</p>

learner1234: <p>Thankyou <a class="mention" href="/u/ptrblck">@ptrblck</a><br>
I was able to resolve the shape issue but the model is not training for thr weights and I have put another thread for that.<br>
If you have time, could you please have a look once?</p>
<aside class="quote quote-modified" data-post="2" data-topic="198528">
  <div class="title">
    <div class="quote-controls"></div>
    <img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/learner1234/48/63325_2.png" class="avatar">
    <a href="https://discuss.pytorch.org/t/validation-loss-and-training-loss-is-not-increasing-in-pytorch/198528/2">Validation loss and training loss is not increasing in pytorch</a> <a class="badge-category__wrapper " href="/c/vision/5"><span data-category-id="5" style="--category-badge-color: #AB9364; --category-badge-text-color: #FFFFFF;" data-drop-close="true" class="badge-category " title="Topics related to either pytorch/vision or vision research related topics"><span class="badge-category__name">vision</span></span></a>
  </div>
  <blockquote>
    I have tried to print the gradients whether it is changing or not 
Indeed it is changing 
Gradient - network.4.weight: 1972.0595703125
Gradient - network.4.bias: 65.66154479980469
Gradient - network.6.weight: 39.97140121459961
Gradient - network.6.bias: 16.263952255249023
Gradient - network.8.weight: 1124.482177734375
Gradient - network.8.bias: 29.2763729095459
Gradient - network.10.weight: 26.414426803588867
Gradient - network.10.bias: 12.346122741699219
Gradient - network.12.weight: 1166.07873…
  </blockquote>
</aside>