I am attempting transfer learning with a CNN (vgg19) on the Oxford102 category dataset consisting of 8189 samples of flowers labeled from 1 through 102. Instead of loading the data with ImageFolder, which requires a tedious process of structuring my data into train, valid and test folders with each class being a sub-folder holding my images, I decided to load it in using the Custom Dataset class following  This tutorial 59
My directory paths set up for the image, the labels (from 1 through 102), and class label map which
maps the label to flower name
    data_dir_path = 'data/images/'
    labels_path = 'data/imagelabels.mat'
    class_label_path = 'data/class_label_map'y 

my data is not in the ImageFolder, and as far as I know If writing a  custom dataset, you don’t need your data to be in that format.
data/images/image_00001.jpg
data/images/image_00002.jpg
data/images/image_00003.jpg
data/images/image_00004.jpg
.
.
.
data/images/image_08189.jpg
my labels list which is in data/imagelabels.mat is as follows,
[77 77 77 … 62 62 62]
The transforms I am using for train, test and valid are
    data_transforms = {
'train': transforms.Compose([
    transforms.RandomRotation(45),
    transforms.RandomResizedCrop(224),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406],
                         [0.229, 0.224, 0.225])
]),
'valid': transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406],
                         [0.229, 0.224, 0.225])
]),
'test': transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406],
                         [0.229, 0.224, 0.225])
]),

}
Here is my code to load in data, it works as I can, index into my images and labels.
    class MyDataset(Dataset):

def __init__(self, image_labels, data_dir, transform=None):

    """

    :param image_labels_path: path to our labels
    :param root_dir: the directory which houses our images
    :param transform: apply any transform on our sample
    """

    self.image_labels = image_labels
    self.root_dir = data_dir
    self.transform = transform

def __len__(self):

    label_dict = scipy.io.loadmat(self.image_labels)
    return len(label_dict['labels'][0]) # [0] cause its a list of lists

def __getitem__(self, idx):

    image_path_list = [os.path.join(self.root_dir, filename) for filename in os.listdir(self.root_dir)]

    image = Image.open(image_path_list[idx])

    label_dict = scipy.io.loadmat(self.image_labels)
    label_list = label_dict['labels'][0]

    # labels for pytorch should start from zero
    label_list[:] = [i - 1 for i in label_list]
    label = label_list[idx]  

    if self.transform:
        image = self.transform(image)

    return image, label

Here I am creating my trainset, validset and testset
    image_datasets = {x: MyDataset(image_labels=labels_path, data_dir=data_dir_path, transform=data_transforms[x]) for x in
              ['train', 'valid', 'test']}

I subtracted 1 from my label list since Pytorch expects labels to start from 0. Thus 0 through 101 for 102 labels.
Correct me if I am wrong cause I get a “current target >=0 and current target <= n_classes failed” error if I don’t subtract one. Since this fails at 102, I thus surmised that class representation starts from 0.
I have a class_label_map is a dict which maps class labels to flowers names
{ 1": “pink primrose”,
“2”: “hard-leaved pocket orchid”,
“3”: “canterbury bells”,
“4”: “sweet pea”,
“5”: “english marigold”,
“6”: "tiger lily }
My big problem is to get a class_to_idx mapping, how do I do this, my flower names do not match the images if I visualize them, I get totally different flower names for my flowers.
I first created a mapping by having a dict with key my original label before I subtracted 1, and value the one after. Example:
        class_to_idx = {77:76, 73:72, 1:0, 65:64......102:101...65:54}

This is beyond doubt wrong as I was getting totally wrong label for my images.
The first label of my image in my data_dir_path = ‘data/images’ is 77, upon subtracting one I get 76. Would this mean the index for all labels 76 is 0, and if the next class is 72 , would that mean the index for all classes 72 is 1? So…
        class_to_idx = {76:0, 72:1, 0:2, 65:3....and so on}

But this again works if the class number does not repeat after a certain classes, i.e. if 72 were to repeat
after class 65, then 72 is no more the 2nd class. The code for how ImageFolder find class_to_index is…
     classes = [d for d in os.listdir(dir) if os.path.isdir(os.path.join(dir, d))]
     classes.sort()
     class_to_idx = {classes[i]: i for i in range(len(classes))}

I don’t properly understand this. Performing it on my label_list give me the largest index of the a certain
class  {1: 39, 2: 99, 3: 139, 4: 195, 5: 260, 6: 305, 7: 345, 8: 430, 9: 476}.
The ImageFolder seems to have a class_to_idx attribute which if used on my Dataset throws an error,
    image_datasets['train'].class_to_idx

AttributeError: ‘MyDataset’ object has no attribute ‘class_to_idx’
This is obviously the case because my Dataset class does not contain any such attribute. If I am reasoing is correct, Pytorch gives out a tuple of probabilities and corresponding index when we do probs.max(dim=1). This index is the value in our class_to_index map. The key is the also the key in our
label_map with, the value of which helps us trace the flower name of the our prediction.
So How do I map my classes to my index in this scenario? It isn’t structured like ImageFolder.
This is super important as I need to checkpoint my model and load it back again to fire out predictions.It may sound really silly, but I really don’t know what to do here, please please please help?