#pytorch #batch-processing #data-stream #dataloader
#pytorch #пакетная обработка #поток данных #загрузчик данных
Вопрос:
Я пытался интегрировать to (устройство) в мой загрузчик данных, используя to (устройство), как показано вhttps://github.com/pytorch/pytorch/issues/11372
Я определил это в FashionMNIST следующим образом:
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
batch_size = 32
trainset = datasets.FashionMNIST('~/.pytorch/F_MNIST_data/',
download=True,
train=True,
transform=transforms.ToTensor())
rain_loader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=False, collate_fn=lambda x: default_collate(x).to(device))
Но я получаю следующую ошибку:
Ошибка атрибута: объект ‘list’ не имеет атрибута ‘to’
Кажется, что вывод по умолчанию collate представляет собой список длиной 2, где первый элемент является тензором изображения, а второй — тензором меток (поскольку это вывод next(iter(train_loader)) с collate_fn=None), поэтому я попробовал использовать следующую определенную функцию:
def to_device_list(l, device):
return [l[0].to(device), l[1].to(device)]
train_loader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=False, collate_fn=lambda x: to_device_list(x, device))
И я получил следующую ошибку:
Ошибка атрибута: объект ‘tuple’ не имеет атрибута ‘to’
Любая помощь, пожалуйста, о том, как это сделать?
Комментарии:
1. Я знаю, что слишком поздно, но добавил решение
Ответ №1:
Набор данных fashion mnist возвращает кортеж из img
и target
, где img
является тензором, а target — int
значением для класса.
Теперь вы dataloader
берете образцы размера пакета из dataset
класса, чтобы получить список образцов. Обратите внимание, что этот список примеров теперь, List[Tuple[Tensor, int]]
(используя аннотацию ввода здесь). Затем он вызывает функцию collate для преобразования List[Tuple[Tensor, int]]
в List[Tensor]
, где этот список имеет 2 тензора. Первый тензор представляет собой сложенный массив изображений размером [32, 1, 28, 28], где 32 — размер пакета, а второй тензор — тензорный массив значений int (метки классов).
default_collate
Функция просто преобразует массив структур в структуры массива.
Теперь, когда вы используете collate_fn=lambda x: default_collate(x).to(device)
, обратите внимание, что default_collate возвращает вам список тензоров. Таким образом, вызов .to
в списке не будет работать и должен вызываться для всех элементов списка.
Использование решения
collate_fn=lambda x: list(map(lambda x: x.to(device), default_collate(x))))
Функция map передает каждый элемент списка (из default_collate
) в cuda и, наконец, вызывает список, поскольку map
вычисляется лениво в python3.
Комментарии:
1. Для тех, кто сталкивается с этой проблемой, я бы рекомендовал использовать инструмент отладки в pycharm или другой ide, или просто pudb. Таким образом очень легко определить проблему.