↓阿里云服务器3年不到300元↓

Tomcat 架构解析 阿里云服务器3年不到300元 Redis设计与实现

在PyTorch的DataLoader中,getitem的idx是如何工作的?

  • 问题:
  • 我目前正在尝试使用PyTorch的DataLoader来处理数据,并将其输入到我的深度学习模型中,但是遇到了一些困难

    我需要的数据是shape(minibatch_size=32,rows=100,columns=41)。在我编写的自定义数据集类中,我拥有的getitem\uucoad如下所示:

    def __getitem__(self, idx):
    x = np.array(self.train.iloc[idx:100, :])
    return x

    我这样写是因为我希望DataLoader一次处理shape(100,41)的输入实例,我们有32个这样的单个实例

    但是,我注意到,与我最初的想法相反,DataLoader传递给函数的idx参数不是连续的(这一点很重要,因为我的数据是时间序列数据)。例如,打印值给了我这样的结果:

    idx = 206000
    idx = 113814
    idx = 80597
    idx = 3836
    idx = 156187
    idx = 54990
    idx = 8694
    idx = 190555
    idx = 84418
    idx = 161773
    idx = 177725
    idx = 178351
    idx = 89217
    idx = 11048
    idx = 135994
    idx = 15067

    这是正常行为吗?我发布这个问题是因为返回的数据批不是我最初想要的

    在使用DataLoader之前,我用于预处理数据的原始逻辑是:

    我不确定我应该如何处理DataLoader钩子方法。如有任何提示或建议,我们将不胜感激。提前谢谢

  • 答案:
  • 定义idx的是samplerbatch\u sampler,如您所见here(开源项目是你的朋友)。在此代码(和注释/docstring)您可以看到采样器batch\u sampler之间的区别。如果你看https://github.com/pytorch/pytorch/blob/e870a9a87042805cd52973e36534357f428a0748/torch/utils/data/dataloader.py\L344-L349“rel=”nofollow noreferrer“>在这里您将看到如何选择索引:

    def __next__(self):
    index = self._next_index()

    # and _next_index is implemented on the base class (_BaseDataLoaderIter)
    def _next_index(self):
    return next(self._sampler_iter)

    # self._sampler_iter is defined in the __init__ like this:
    self._sampler_iter = iter(self._index_sampler)

    # and self._index_sampler is a property implemented like this (modified to one-liner for simplicity):
    self._index_sampler = self.batch_sampler if self._auto_collation else self.sampler

    请注意,这是一个实现,您可以找到multiprocessingdataloaderhere(ofc,使用哪个取决于num_workers值,如您所见此处)。回到采样器,假设你的数据集不是_DatasetKind.Iterable并且您没有提供自定义采样器,这表示您正在使用(数据加载器.py#L212-L215):

    if shuffle:
    sampler = RandomSampler(dataset)
    else:
    sampler = SequentialSampler(dataset)

    if batch_size is not None and batch_sampler is None:
    # auto_collation without custom batch_sampler
    batch_sampler = BatchSampler(sampler, batch_size, drop_last)

    我们来看看how the default BatchSampler builds a batch公司名称:

    def __iter__(self):
    batch = []
    for idx in self.sampler:
    batch.append(idx)
    if len(batch) == self.batch_size:
    yield batch
    batch = []
    if len(batch) > 0 and not self.drop_last:
    yield batch

    非常简单:它从取样器获取索引,直到达到所需的批次大小

    现在的问题是“在PyTorch的DataLoader中,getitem的idx是如何工作的?”可以通过查看每个默认采样器的工作方式来回答

    class SequentialSampler(Sampler):
    def __init__(self, data_source):
    self.data_source = data_source

    def __iter__(self):
    return iter(range(len(self.data_source)))

    def __len__(self):
    return len(self.data_source)
    def __iter__(self):
    n = len(self.data_source)
    if self.replacement:
    return iter(torch.randint(high=n, size=(self.num_samples,), dtype=torch.int64).tolist())
    return iter(torch.randperm(n).tolist())

    因此,由于您没有提供任何代码,我们只能假设:

C++ Primer Plus 第六版 阿里云服务器3年不到300元 流畅的 Python