Я пытаюсь перенести обучение с помощью 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'
Это, очевидно, так, потому что мой класс набора данных делаетне содержит ни одного такого атрибута.
А если серьезно, как мне сопоставить мои классы с моим индексом?Это очень важно, так как мне нужно проверить контрольную точку моей модели и снова загрузить ее, чтобы выдать прогнозы. Это может звучать очень глупо, но я действительно не знаю, что здесь делать, пожалуйста, помогите?