Как получить карту class_to_idx для пользовательского набора данных в Pytorch - PullRequest
0 голосов
/ 17 февраля 2019

Я пытаюсь перенести обучение с помощью CNN (vgg19) в наборе данных категории Oxford102, состоящем из 8189 образцов цветов, помеченных от 1 до 102. Вместо загрузки данных в ImageFolder, что требует утомительного процесса структурирования моих данных в поезд, действительные и тестовые папки с каждым классом, являющимся подпапкой, содержащей мои изображения, я решил загрузить его, используя класс Custom Dataset, следуя

https://pytorch.org/tutorials/beginner/data_loading_tutorial.html

Подмножество кода Iзаписал для моего проекта

    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']}

мой экземпляр класса модели унаследован от nn.Module

    classifier = Neural(25088, [4096], 102)

Я вычел -1 из моего списка меток, так как Pytorch ожидает, что метки начнутся с 0Таким образом, от 0 до 101 для 102 этикеток.Поправьте меня, если я ошибаюсь, потому что я получаю ошибку «текущая цель> = 0 и текущая цель <= n_classes fail», если я не вычитаю ее.</p>

class_label_map - это диктовка, которая отображает метки классов на имена цветов

    {
"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",
    }

Моя большая проблема состоит в том, чтобы получить отображение class_to_idx, как мне это сделать, мои имена цветов не соответствуют изображениямесли я их визуализирую, я получаю совершенно разные названия цветов для своих цветов.

Сначала я создал отображение, указав в поле ввода мой оригинальный ярлык, прежде чем вычесть 1, а затем значение после.Пример

    class_to_idx = {77:76, 73:72, 1:0, 65:64......102:101...65:54}

Вне всякого сомнения, это неправильно, поскольку я получаю совершенно неправильную метку для своих изображений.

Первая метка моего изображения в моем data_dir_path = 'data / images' - 77,после вычитания одного я получаю 76. Будет ли это означать, что индекс для всех меток 76 равен 0, а если следующий класс равен 72, будет ли это означать, что индекс для всех классов 72 равен 1?Итак ...

    class_to_idx = {76:0, 72:1, 0:2, 65:3....and so on}

Кажется, ImageFolder имеет атрибут class_to_idx, который, если он используется в моем наборе данных, выдает ошибку,

    image_datasets['train'].class_to_idx

   AttributeError: 'MyDataset' object has no attribute 'class_to_idx'

Это, очевидно, так, потому что мой класс набора данных делаетне содержит ни одного такого атрибута.

А если серьезно, как мне сопоставить мои классы с моим индексом?Это очень важно, так как мне нужно проверить контрольную точку моей модели и снова загрузить ее, чтобы выдать прогнозы. Это может звучать очень глупо, но я действительно не знаю, что здесь делать, пожалуйста, помогите?

1 Ответ

0 голосов
/ 04 марта 2019

Я закончил эту вещь давным-давно, и за то, что она стоит, я хотел бы дать свои два цента о том, где я ошибся, хотя и очень неловко.Я не сортировал свой image_path_list.Порядок их появления в папке с данными и соответствующие метки в списке меток не совпадали.Это произошло потому, что Python считывал их в произвольном порядке из папки данных в image_path_list.Простая сортировка разобрала все.

    image_path_list = sort([os.path.join(self.root_dir, filename) for filename in os.listdir(self.root_dir)])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...