Invalid index in scatter

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

class Generator(nn.Module):
‘’’
Generator
‘’’
def init(self, z=100, channels=3, d=128):
super().init()
self.z = z
self.channels = channels
self.deconv1_1 = nn.ConvTranspose2d(self.z, d2, 4, 1, 0)
self.deconv1_1_bn = nn.BatchNorm2d(d
2)
self.deconv1_2 = nn.ConvTranspose2d(20, d2, 4, 1, 0)
self.deconv1_2_bn = nn.BatchNorm2d(d
2)
self.deconv2 = nn.ConvTranspose2d(d4, d2, 4, 2, 1)
self.deconv2_bn = nn.BatchNorm2d(d2)
self.deconv3 = nn.ConvTranspose2d(d
2, d, 4, 2, 1)
self.deconv3_bn = nn.BatchNorm2d(d)
self.deconv4 = nn.ConvTranspose2d(d, self.channels, 4, 2, 1)

def forward(self, input, label):
    label_oh = Variable(label.data.new(label.size(0), 20).float().zero_())
    label = label.unsqueeze(1)
    label_oh.scatter_(1, label, 1)
    label = label_oh.view(label_oh.size(0), label_oh.size(1), 1, 1)
    input = input.view(input.size(0), -1, 1, 1)
    x = F.relu(self.deconv1_1_bn(self.deconv1_1(input)))
    y = F.relu(self.deconv1_2_bn(self.deconv1_2(label)))
    x = torch.cat([x, y], 1)
    x = F.relu(self.deconv2_bn(self.deconv2(x)))
    x = F.relu(self.deconv3_bn(self.deconv3(x)))
    features = x
    x = torch.tanh(self.deconv4(x))
    return x, features

this is a piece of the generator where for the cifar100 in this line because I entered 20 as a number of classes because I am considering training taking only the coarse_label which are 20 instead of the labels, in which case in this piece of code the number of classes is 100.
self.deconv1_2 = nn.ConvTranspose2d(100, d2, 4, 1, 0)
self.deconv1_2_bn = nn.BatchNorm2d(d
2)
self.deconv2 = nn.ConvTranspose2d(d4, d2, 4, 2, 1)
self.deconv2_bn = nn.BatchNorm2d(d2)
self.deconv3 = nn.ConvTranspose2d(d
2, d, 4, 2, 1)
self.deconv3_bn = nn.BatchNorm2d(d)
self.deconv4 = nn.ConvTranspose2d(d, self.channels, 4, 2, 1)

def forward(self, input, label):
    label_oh = Variable(label.data.new(label.size(0), 100).float().zero_())
    label = label.unsqueeze(1)
    label_oh.scatter_(1, label, 1)

In output it gives me the following error and I can’t understand what I have to change.
label_oh.scatter_ (1, label, 1)
RuntimeError: Invalid index in scatter at C: \ w \ 1 \ s \ windows \ pytorch \ aten \ src \ TH / generic / THTensorEvenMoreMath.cpp: 151Mi by error

Could you post the content of label before passing it to scatter_?
Based on the code I assume that label_oh has the shape [20, 100] and contains zeros?

I created the dataset in this way and then passed it to the loader
import os
import sys
import pickle

from skimage import io
import matplotlib.pyplot as plt
import numpy
import torch
from torch.utils.data import Dataset

class CIFAR100Train(Dataset):
“”“cifar100 test dataset, derived from
torch.utils.data.DataSet
“””

def __init__(self, path, transform=None):
    #if transform is given, we transoform data using
    with open(os.path.join(path, 'train'), 'rb') as cifar100:
        self.data = pickle.load(cifar100, encoding='bytes')
    self.transform = transform
    
def __len__(self):
    return len(self.data['coarse_labels'.encode()])

def __getitem__(self, index):
    label = self.data['coarse_labels'.encode()][index]
    print(label)
    r = self.data['data'.encode()][index, :1024].reshape(32, 32)
    g = self.data['data'.encode()][index, 1024:2048].reshape(32, 32)
    b = self.data['data'.encode()][index, 2048:].reshape(32, 32)
    image = numpy.dstack((r, g, b))

    if self.transform:
        image = self.transform(image)
    return label, image

this is the piece of the train

for i ,(inputs,coarse_labels) in enumerate(tqdm(data_loader, desc=f’EPOCH: {epoch+1}/{args.epochs}’)):
inputs=inputs.to(device)
#coarse_label_names=coarse_label_names.to(device)
#print(coarse_labecl_name)
coarse_labels = coarse_labels.to(device)

                # train GAN
                if split == 'train':
                    loss_gan_dict = gan_trainer.forward_batch(inputs, coarse_labels)
                    fake_images = loss_gan_dict['generated_img'] # 64 x 3 x 32 x 32

                #if split == 'test':
                   
                        



                step = (epoch * len(data_loader)) + i

                # log train
                if split == 'train':
                    saver.log_loss("Discriminator/Loss", loss_gan_dict['discriminator'], step)
                    saver.log_loss("Discriminator/Real_Right_Loss", loss_gan_dict['discriminator_real_right'], step)
                    saver.log_loss("Discriminator/Real_Wrong_Loss", loss_gan_dict['discriminator_real_wrong'], step)
                    saver.log_loss("Discriminator/Fake_Loss", loss_gan_dict['discriminator_fake'], step)
                    saver.log_loss("Generator/Loss", loss_gan_dict['generator'], step)
                    saver.log_loss("Generator/Loss Fake", loss_gan_dict['generator_loss_fake'], step)

                    
            #evaluate generation of images putting generator in eval mode
            g_net.eval()
            z_in = torch.randn(len(coarse_labels), 100).to(device)
            for i in range(0, 20):
                label_vector = torch.ones(80, dtype=torch.int64).to(device)
                label_vector = label_vector*i
                z_in = torch.randn(len(label_vector), 100).to(device)
                results, _ = g_net(z_in, label_vector)
                saver.log_images("Fake Images 80/"+classes[i], epoch, results)

            # Generate 8 samples for each class with fixed noise
            labels_20 = torch.arange(0,20).to(device)
            labels_20 = labels_100.repeat(8)
            z_fixed = torch.randn(len(labels_20), 100).to(device)
            samples_20, _ = g_net(z_in, labels_20)
            saver.log_images("Fake Images/eval_20_fixed_noise", epoch, samples_20)

            # reset net to train mode
            g_net.train()

I tried to isolate the code snippet, which might cause the issue, but this works fine:


for i in range(0, 20):
    label_vector = torch.ones(80, dtype=torch.int64).to(device)
    label_vector = label_vector*i
    z_in = torch.randn(len(label_vector), 100).to(device)                
    label = label_vector
    
    label_oh = label.new(label.size(0), 100).float().zero_()
    label = label.unsqueeze(1)
    label_oh.scatter_(1, label, 1)

Note that your Dataset returns label, image while you are using inputs, coards_labels in your DataLoader loop.
I don’t know, if this mismatch might be related to your issue, but feel free to post a code snippet to reproduce this issue in case you get stuck.

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