Pytorch / torchvision - изменить изображения и метки объекта набора данных - PullRequest
1 голос
/ 18 октября 2019

Итак, у меня есть эта строка кода для загрузки набора данных изображений из двух классов с именами «0» и «1» для простоты:

train_data = torchvision.datasets.ImageFolder(os.path.join(TRAIN_DATA_DIR), train_transform)

, а затем я подготавливаю загрузчик для использования с моиммодель следующим образом:

train_loader = torch.utils.data.DataLoader(train_data, TRAIN_BATCH_SIZE, shuffle=True)

Итак, на данный момент каждое изображение связано с классом, и я хочу взять каждое изображение и применить к нему преобразование между этими двумя строками кода, скажем,поворот на одну из четырех градусов: 0, 90, 180, 270 и добавьте эту информацию в качестве дополнительной метки четырех классов: 0, 1, 2, 3. В конце я хочу, чтобы набор данных содержал повернутые изображения и как ихпомечает список из двух значений: класс изображения и примененное вращение.

Я пробовал это, и ошибки нет, но набор данных остается неизменным, если я пытаюсь напечатать ярлыки:

for idx,label in enumerate(train_data.targets):
    train_data.targets[idx] = [label, 1]

Есть ли хороший способ сделать это, напрямую изменив train_data, не требуя пользовательского набора данных?

1 Ответ

0 голосов
/ 23 октября 2019

Есть ли хороший способ сделать это, напрямую изменив train_data, не требуя специального набора данных?

Нет, нет. Если вы хотите использовать <a href="https://pytorch.org/docs/stable/torchvision/datasets.html#imagefolder" rel="nofollow noreferrer">datasets.ImageFolder</a>, вы должны принять его ограниченную гибкость. Фактически, ImageFolder - это просто подкласс DatasetFolder, который в значительной степени представляет собой собственный набор данных. Вы можете увидеть в исходном коде следующий раздел __getItem__:

if self.transform is not None:
    sample = self.transform(sample)
if self.target_transform is not None:
    target = self.target_transform(target)

Это делает невозможным то, что вы хотите, так как ожидаемое преобразование должно изменить как изображение, так и цель нав то же время, что здесь и делается независимо.

Итак, начните с того, что ваш подкласс Dataset будет похож на DatasetFolder, и просто реализуйте свое собственное преобразование, которое принимает изображение и цель одновременнои возвращает их преобразованные значения. Это всего лишь пример класса преобразования, который вы могли бы иметь, который затем нужно было бы объединить в один вызов функции:

class RotateTransform(object):
    def __call__(self, image, target):
        # Rotate the image randomly and adjust the target accordingly
        #...

        return image, target

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

...