Pytorch 从“ConcatDataset”创建的“DataLoader”是从不同的文件创建批处理,还是从单个文件创建批处理?

Pytorch 从“ConcatDataset”创建的“DataLoader”是从不同的文件创建批处理,还是从单个文件创建批处理?,pytorch,Pytorch,我正在处理多个文件,每个文件中都有多个培训样本。我将使用ConcatDataset,如下所述: 除了真实样本,我还需要负样本,我需要从所有训练数据文件中随机选择负样本。所以,我想知道,返回的批处理样本是来自单个文件的随机连续chuck,还是跨所有数据文件的多个随机索引的批处理范围 如果我想做的事情需要更多的细节,那是因为我试图用PyTrac XLA来训练TPU。 正常情况下,对于负样本,我只会使用一个第二代码>数据集< /COD>和 DataLoader ,但是,我正试图用PyTrac XLA

我正在处理多个文件,每个文件中都有多个培训样本。我将使用
ConcatDataset
,如下所述:

除了真实样本,我还需要负样本,我需要从所有训练数据文件中随机选择负样本。所以,我想知道,返回的批处理样本是来自单个文件的随机连续chuck,还是跨所有数据文件的多个随机索引的批处理范围

如果我想做的事情需要更多的细节,那是因为我试图用PyTrac XLA来训练TPU。

正常情况下,对于负样本,我只会使用一个第二代码>数据集< /COD>和<代码> DataLoader <代码>,但是,我正试图用PyTrac XLA(几天前才发布)来在TPU上进行训练,并且要做到这一点,我需要把我的<代码> DataLoader < /代码>发送到<代码> TrChxxLa.DataSalPix.DataParallel < /Cord>对象,类似于

model\u parallel(train\u loop\u fn,train\u loader)
,可以在这些示例笔记本中看到


因此,我现在仅限于一个
数据加载器
,它需要处理真实样本和需要从我的所有文件中随机选择的负样本。

ConcatDataset
是一个自定义类,它是从
torch.utils.data.Dataset
中派生的。让我们来看一个例子。

class ConcatDataset(torch.utils.data.Dataset):
    def __init__(self, *datasets):
        self.datasets = datasets

    def __getitem__(self, i):
        return tuple(d[i] for d in self.datasets)

    def __len__(self):
        return min(len(d) for d in self.datasets)

train_loader = torch.utils.data.DataLoader(
             ConcatDataset(
                 dataset1, 
                 dataset2
             ),
             batch_size=args.batch_size, 
             shuffle=True,
             num_workers=args.workers, 
             pin_memory=True)

for i, (input, target) in enumerate(train_loader):
    ...
这里,将两个数据集,即
dataset1
(示例列表)和
dataset2
组合成一个训练数据集。
\uuu getitem\uuu
函数从数据集中返回一个示例,并将由
批次采样器使用以形成训练小批次

返回的批处理样本是来自单个文件的随机连续样本,还是跨越所有数据文件的多个随机索引的批处理范围

由于您已将所有数据文件合并为一个数据集,现在它取决于您用于采样小批量的
BatchSampler
。PyTorch中实现了多个采样器,例如,
随机采样器
顺序采样器
海底采样器
加权随机采样器
。请在中查看它们的用法

您也可以使用自定义的
BatchSampler
,如下所示

class MyBatchSampler(Sampler):
    def __init__(self, *params):
        # write your code here

    def __iter__(self):
        # write your code here
        # return an iterable

    def __len__(self):
        # return the size of the dataset
\uuuu iter\uuuu
函数应返回一个小批量的iterable。您可以在此函数中实现形成小批量的逻辑


要随机抽取负面示例进行培训,一种替代方法是在
ConcatDataset
类的
\uuu init\uuuu
函数中为每个正面示例挑选负面示例。

从文档中,似乎是针对批次,您使用
BatchSampler
,并在实例化时将特定的采样器传入
BatchSampler
。在我的例子中,我想使用
RandomSampler
,因为它生成了一个整数列表,它跨越了我所有数据点()的全部索引数。因此,我认为对于第一个代码块,我们需要指定
batch\u sampler=BatchSampler(RandomSampler,batch\u size,drop\u last)
。但是我现在想知道,如果每个数据集都是延迟加载的,那么随机采样器如何知道数据集的整个长度,
n
(),以避免一次加载所有文件(为了避免内存错误)。我将实现这个
数据集
加载器。这将需要一个全新的问题,所以我只做了一个新的stackoverflow帖子。