【问题标题】:How to use two seperate dataloaders together?如何一起使用两个单独的数据加载器?
【发布时间】:2020-05-02 15:48:33
【问题描述】:

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

【问题讨论】:

  • @jonny-vu 有什么建议吗?
  • 您不能组合数据加载器,但可以组合数据集(技术上不正确,但尝试同时迭代两个数据加载器时会出现一些微妙的问题)。您是否有两个单独的数据集,它们具有 1-1 对应关系,每个数据集在调用 __getitem__ 时都会产生 (3, 224, 224) 张量?
  • 现在,我只有这两个张量。我应该采取什么方法?

标签: deep-learning pytorch tensor


【解决方案1】:

我仍然不确定我是否完全理解这个问题,但假设你有两个大张量 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。

【讨论】:

  • 非常感谢!我正在寻找这个答案。我是深度学习的新手,你能告诉我更多关于何时使用 gpu 以及何时单独使用 cpu 的示例
  • 没有硬性规定,但通常您必须考虑这样一个事实,即每当您向/从 GPU 传输数据时,都会产生一些(通常是非常重要的)开销。在 pytorch 中,如果你想在大张量上计算一系列复杂操作,那么传输到 GPU 通常会导致显着的加速(例如 DCNN)。另一方面,对于像元素乘法这样的东西,在 GPU 上执行计算的好处可能会被将数据从 RAM 复制到 GPU 并再次复制回来的开销所掩盖。
猜你喜欢
  • 2012-05-14
  • 2017-08-01
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 1970-01-01
  • 2016-07-26
  • 2018-12-28
  • 2011-01-28
相关资源
最近更新 更多