title: How to get class_to_idx map for Custom Dataset in Pytorch
body: <p>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 </p>
  
  <p><a href="https://pytorch.org/tutorials/beginner/data_loading_tutorial.html" rel="nofollow noreferrer">https://pytorch.org/tutorials/beginner/data_loading_tutorial.html</a></p>
  
  <p>A subset of the code I wrote up for my project</p>
  
  <pre><code>    data_dir_path = 'data/images/'
      labels_path = 'data/imagelabels.mat'
      class_label_path = 'data/class_label_map'
  
      # standard normalization for Imagenet models mean: [0.485, 0.456,0.406],
      # std :[0.229, 0.224, 0.225]
  
      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])
  ]),
     }
  
  
      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])
  
          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]
  
      # label index for pytorch should start form zero
      # so subtract -1 from each class
      label_list[:] = [i - 1 for i in label_list]
      label = label_list[idx]  
  
      if self.transform:
          image = self.transform(image)
  
      return image, label
  
      image_datasets = {x: MyDataset(image_labels=labels_path, data_dir=data_dir_path, transform=data_transforms[x]) for x in
                ['train', 'valid', 'test']}
  </code></pre>
  
  <p>my model class instance inherited from nn.Module is</p>
  
  <pre><code>    classifier = Neural(25088, [4096], 102)
  </code></pre>
  
  <p>I have 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 &lt;= n_classes failed" error if I don't subtract one. </p>
  
  <p>class_label_map is a dict which maps class labels to flowers names</p>
  
  <pre><code>    {
  "1": "pink primrose",
  "2": "hard-leaved pocket orchid",
  "3": "canterbury bells",
  "4": "sweet pea",
  "5": "english marigold",
  "6": "tiger lily",
  "7": "moon orchid",
  "8": "bird of paradise",
  "9": "monkshood",
  "10": "globe thistle",
  "11": "snapdragon",
      }
  </code></pre>
  
  <p>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. </p>
  
  <p>I first created a mapping by having a dict with key my original label before I subtracted 1, and value the one after. Example</p>
  
  <pre><code>    class_to_idx = {77:76, 73:72, 1:0, 65:64......102:101...65:54}
  </code></pre>
  
  <p>This is beyond doubt wrong as I was getting totally wrong label for my images.</p>
  
  <p>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...</p>
  
  <pre><code>    class_to_idx = {76:0, 72:1, 0:2, 65:3....and so on}
  </code></pre>
  
  <p>The ImageFolder seems to have a class_to_idx attribute which if used on my Dataset throws an error,</p>
  
  <pre><code>    image_datasets['train'].class_to_idx
  
     AttributeError: 'MyDataset' object has no attribute 'class_to_idx'
  </code></pre>
  
  <p>This is obviously the case because my Dataset class does not contain any such attribute.</p>
  
  <p>But seriously though, How do I map my classes to my index? 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 help?</p>