Как PyTorch DataLoader взаимодействует с набором данных PyTorch для преобразования пакетов?

Я создаю собственный набор данных для задач, связанных с НЛП.

В руководстве по настройке пользовательских данных PyTorch мы видим, что метод __getitem__() место для преобразования, прежде чем оно вернет образец:

def __getitem__(self, idx):
        if torch.is_tensor(idx):
            idx = idx.tolist()

        img_name = os.path.join(self.root_dir,
                                self.landmarks_frame.iloc[idx, 0])
        image = io.imread(img_name)
       
        ### SOME DATA MANIPULATION HERE ###

        sample = {'image': image, 'landmarks': landmarks}
        if self.transform:
            sample = self.transform(sample)

        return sample

Однако код здесь:

        if torch.is_tensor(idx):
            idx = idx.tolist()

подразумевает, что можно получить несколько элементов одновременно, что заставляет меня задуматься:

  1. Как это преобразование работает с несколькими элементами? Возьмем, к примеру, пользовательские преобразования из учебника. Они не выглядят так, как будто их можно применить к партии образцов за один вызов.

  2. В связи с этим, как DataLoader извлекает пакет из нескольких выборок параллельно и применяет указанное преобразование, если преобразование может быть применено только к одному образцу?


person rocksNwaves    schedule 25.02.2021    source источник


Ответы (2)


  1. Как это преобразование работает с несколькими элементами? Они работают с несколькими элементами с помощью загрузчика данных. Используя преобразования, вы указываете, что должно произойти с единичной эмиссией данных (например, batch_size=1). Загрузчик данных принимает ваш указанный batch_size и делает n вызовы метода __getitem__ в наборе данных torch, применяя преобразование к каждой выборке, отправленной для обучения / проверки. Затем он сопоставляет n выборок по размеру вашего пакета, полученного из загрузчика данных.

  2. В связи с этим, как DataLoader извлекает пакет из нескольких образцов параллельно и применяет указанное преобразование, если преобразование может быть применено только к одному образцу? Надеюсь, что вышеизложенное имеет смысл для вас. Распараллеливание выполняется классом набора данных резака и загрузчиком данных, где вы указываете num_workers. Torch обработает набор данных и распределит его между рабочими.

person John Stud    schedule 25.02.2021
comment
... делает n вызовов __getitem__ - это именно то, что я хотел знать. Тогда это означает, что передача индекса списка ничего не даст, и этого следует избегать. Я удалю эти строки кода из своей собственной реализации. Спасибо. - person rocksNwaves; 25.02.2021
comment
Да, вам не нужно передавать ему список индекса, за исключением, вероятно, очень редких заданий. В разделе __init__, где вы создаете экземпляр своего набора данных, он определит длину набора данных, частично с помощью метода __len__, а затем создаст сам список индексов. - person John Stud; 25.02.2021
comment
Правильно, я подумал, что именно так DataLoader мог бы получить доступ к n элементам в batch_size=n, поскольку в официальном руководстве были эти строки кода об индексе списка. Я считаю, что список выдаст ошибку, если преобразование пакета не удастся. - person rocksNwaves; 25.02.2021

из документации по преобразованиям из torchvision:

Все преобразования принимают в качестве входных данных изображение PIL, тензорное изображение или пакет тензорных изображений. Тензорное изображение - это тензор с формой (C, H, W), где C - количество каналов, H и W - высота и ширина изображения. Пакет тензорных изображений - это тензор формы (B, C, H, W), где B - количество изображений в пакете. Детерминированные или случайные преобразования, применяемые к пакету тензорных изображений, одинаково преобразуют все изображения пакета.

Это означает, что вы можете передать пакет изображений, и преобразование будет применено ко всему пакету, если оно соответствует форме. Индексы списка действуют на iloc из фрейма данных, который выбирает либо один индекс, либо их список, возвращая запрошенное подмножество.

person Maura Pintor    schedule 25.02.2021
comment
Привет, Маура, пользовательские наборы данных используются за пределами мира CV, поэтому меня интересует взаимодействие наборов данных с загрузчиками данных в более общем смысле. В частности, я работаю с текстовыми данными, а не с изображениями. - person rocksNwaves; 25.02.2021
comment
Я отредактировал свой вопрос для ясности, если вы хотите попытаться ответить на него еще раз. - person rocksNwaves; 25.02.2021
comment
Это определенно один из подходов, но он не делает вашу сеть, расширяющую класс nn.Module, очень расширяемой. Но в любом случае мой вопрос несколько меньше о том, как мне достичь X? и скорее это Как достигается X в примере Y? Например, если преобразования предназначены только для одного образца, зачем разрешать передачу индекса списка? Здесь что-то воняет или что-то необычное творится под капотом. Я хочу знать, что это такое. - person rocksNwaves; 25.02.2021
comment
Хорошо, извините, я этого не понял :) В любом случае, я думаю, что это все еще связано с тем, как определены преобразования в torchvision (да, домен изображений везде, я понимаю вашу точку зрения, однако долгое время это было основным тема). Некоторые из них на самом деле nn.Module сами по себе. - person Maura Pintor; 25.02.2021