How can I shuffle the labels of a dataset?

Viewed 1727

I have downloaded the MNIST dataset, using the following command:

train_dataset = dsets.MNIST(root='./data', 
                            train=True, 
                            transform=transforms.ToTensor(),
                            download=True)

I now need to run some experiments on this dataset (MNIST), but shuffling the labels of the training set. How can I shuffle/reassign them randomly? I have tried the following:

train_dataset = dsets.MNIST(root='./data', 
                            train=True, 
                            transform=transforms.ToTensor(),
                            target_transform=lambda y: torch.randint(0, 10, (1,)).item(),
                            download=True)

But I have noticed that what comes after the lambda function makes the labels shuffle during the training process, e.g. they change at every epoch. This way, I won't reach 100% training accuracy, which is what I am aiming for. How can I shuffle these labels in a way that is completely random, making sure that these labels won't change during the training process?

Thank you!!

1 Answers

In case your goal is to create a random mapping of labels you would need to define the mapping before defining the target transform to keep the transform constant. Something like the following should do the trick

import random
label_mapping = list(range(10))
random.shuffle(label_mapping)
train_dataset = dsets.MNIST(root='./data', 
                            train=True, 
                            transform=transforms.ToTensor(),
                            target_transform=lambda y: label_mapping[y],
                            download=True)

In order to get a new shuffle each epoch you would want to redefine the label mapping, training dataset, and dataloader each epoch.

Update To instead generate a random label which is independent of the true label but consistent for a given index then you probably need to either do some very careful seeding or reimplement some functionality of the dataset class.

For example, the latter case might look something like this

import random
class RandomMNIST(dsets.MNIST):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.targets = [random.randint(0, 9) for _ in range(len(self.data))]

train_dataset = RandomMNIST(root='./data', 
                            train=True, 
                            transform=transforms.ToTensor(),
                            download=True)

or equivalently

import random
train_dataset = dsets.MNIST(root='./data', 
                            train=True, 
                            transform=transforms.ToTensor(),
                            download=True)
train_dataset.targets = [random.randint(0, 9) for _ in range(len(train_dataset))]
Related