如何一起使用两个单独的数据加载器?

How to use two seperate dataloaders together?

我有两个形状为 (16384,3,224,224) 的张量。我需要将这两个相乘。显然,这两个张量太大,无法放入 GPU 内存中。所以我想知道,我应该怎么做,使用切片将它们分成更小的批次,还是应该使用两个单独的数据加载器?(我很困惑,如何一起使用两个不同的数据加载器) 执行此操作的最佳方法是什么?

我仍然不确定我是否完全理解这个问题,但假设你有两个大张量 t1t2 形状 [16384, 3, 224, 224] 已经加载到 RAM 中并且想要执行逐元素乘法,那么最简单的方法是

result = t1 * t2

或者,您可以将它们分解成更小的张量,然后将它们相乘。有很多方法可以做到这一点。

一种非常类似于 PyTorch 的方法是使用 TensorDataset 并对两个张量的相应小批量进行操作。如果您只想按元素乘法,那么将张量传入和传出 GPU 的开销可能比计算期间实际节省的时间更昂贵。如果你想尝试一下,你可以使用这样的东西

import torch
from torch.utils import data

batch_size = 100
device = 'cuda:0'

dataset = data.TensorDataset(t1, t2)
dataloader = data.DataLoader(dataset, num_workers=1, batch_size=batch_size)

result = []
for d1, d2 in dataloader:
    d1, d2 = d1.to(device=device), d2.to(device=device)
    d12 = d1 * d2

    result.append(d12.cpu())

result = torch.cat(result, dim=0)

或者你可以做一些切片,这可能会更快,内存效率更高,因为它避免了在 CPU 端复制数据。

import torch

batch_size = 100
device = 'cuda:0'

index = 0
result = []
while index < t1.shape[0]:
    d1 = t1[index:index + batch_size].to(device=device)
    d2 = t2[index:index + batch_size].to(device=device)
    d12 = d1 * d2

    result.append(d12.cpu())
    index += batch_size

result = torch.cat(result, dim=0)

请注意,对于这两个示例,大部分时间都花在了将数据复制回 CPU 和连接最终结果上。理想情况下,您只需在循环中对 d12 批处理做任何您需要做的事情,并避免将最终相乘结果发送回 CPU.