【问题标题】:Get single random example from PyTorch DataLoader从 PyTorch DataLoader 获取单个随机示例
【发布时间】:2019-05-03 09:19:01
【问题描述】:

如何从 PyTorch DataLoader 中获取单个随机示例?

如果我的DataLoader 提供了多个图像和标签的 minbatch,我如何获得单个随机图像和标签?

请注意,我不希望每个 minibatch 一个图像和标签,我想要一个示例。

【问题讨论】:

    标签: python pytorch


    【解决方案1】:

    来自DataLoader的随机样本

    假设DataLoader(shuffle=True)在其构造中使用,可以从DataLoader中抽取一个随机示例:

    example = next(iter(dataloader))[0]
    

    来自Dataset的随机样本

    如果不是这样,您可以从数据集中抽取一个随机示例:

    idx = torch.randint(len(dataset), (1,))
    example = dataset[idx]
    

    【讨论】:

      【解决方案2】:

      (此答案是对@parthagar 答案的Alternative 3的补充)

      遍历dataset 确实返回“随机”示例,您应该改用:

      # Recovers the original `dataset` from the `dataloader`
      dataset = dataloader.dataset
      n_samples = len(dataset)
      
      # Get a random sample
      random_index = int(numpy.random.random()*n_samples)
      single_example = dataset[random_index]
      

      【讨论】:

        【解决方案3】:

        如果您的DataLoader 是这样的:

        test_loader = DataLoader(image_datasets['val'], batch_size=batch_size, shuffle=True)
        

        它给你一个大小为batch_size的batch,你可以通过直接索引batch来挑选一个随机的例子:

        for test_images, test_labels in test_loader:  
            sample_image = test_images[0]    # Reshape them according to your needs.
            sample_label = test_labels[0]
        

        替代解决方案

        1. 您可以使用RandomSampler获取随机样本。

        2. 在 DataLoader 中使用 1 的 batch_size

        3. 像这样直接从您的数据集中抽取样本:

           mnist_test = datasets.MNIST('../MNIST/', train=False, transform=transform)
          

          现在使用这个数据集来采样:

           for image, label in mnist_test:
                # do something with image and other attributes
          
        4. (可能是最好的)here

           inputs, classes = next(iter(dataloader))   
          

        【讨论】:

        • 干杯!对于备选方案 1,需要有一个循环...是否可以执行以下操作:testloader.next()[0]
        • 看看 (pytorch.org/docs/stable/_modules/torch/utils/data/…)。我认为DataLoader.__iter__ 应该可以工作,或者_DataLoaderIter 必须的东西。另外,如果这回答了您的问题,请考虑接受答案
        • 你还没有真正回答我的问题:1)每个小批量会给出一张图像,而不仅仅是一张图像。 2)违反了问题中的复数形式(我将进行编辑以使这一举动变得明显)3)这看起来会处理每个示例,而不仅仅是给出一个示例。
        • 创建一个循环只是为了在一次迭代后打破它似乎很臭/丑陋。有什么想法吗?
        • 我还提到了next 选项。
        【解决方案4】:

        如果您想从您的 Trainloader/Testloader 中选择特定图像,您应该查看 master 的 Subset 函数:

        这是一个如何使用它的示例:

        testset = ImageFolderWithPaths(root="path/to/your/Image_Data/Test/", transform=transform)
        subset_indices = [0] # select your indices here as a list
        subset = torch.utils.data.Subset(testset, subset_indices)
        testloader_subset = torch.utils.data.DataLoader(subset, batch_size=1, num_workers=0, shuffle=False)
        

        这样您就可以只使用一个图像和标签。但是,您当然可以在您的 subset_indices 中使用多个索引。

        如果要使用 DataFolder 中的特定图像,可以使用 dataset.sample 并构建字典来获取要使用的图像的索引。

        【讨论】:

        • 这会为您提供数据集中的第一个元素,不是随机元素。
        【解决方案5】:

        获取随机样本的关键是将DataLoader设置为shuffle=True,获取单张图像的关键是将batch size设置为1。

        这是loading the mnist dataset之后的例子。

        from torch.utils.data import DataLoader, Dataset, TensorDataset
        bs = 1
        train_ds = TensorDataset(x_train, y_train)
        train_dl = DataLoader(train_ds, batch_size=bs, shuffle=True)
        
        for xb, yb in train_dl:
            print(xb.shape)
            x = xb.view(28,28) 
            print(x.shape)
            print(yb)
            break #just once
        
        from matplotlib import pyplot as plt
        plt.imshow(x, cmap="gray")
        

        【讨论】:

          【解决方案6】:

          TL;DR:

          DataLoader 获取单个示例的一般形式是:

          list = [ x[0] for x in iter(trainloader).next() ]
          

          特别是对于所提出的问题,图像和标签的最小批次返回:

          image, label = [ x[0] for x in iter(trainloader).next() ]
          

          可能有趣的信息:

          要从DataLoader 获取单个小批量,请使用:

          iter(trainloader).next()
          

          当运行for images, labels in dataloader: 之类的东西时,幕后发生的事情是通过iter(dataloader) 创建一个迭代器,然后在每次循环执行时调用迭代器的.next()


          要从 DataLoader 获取单个图像,它会返回图像和标签,请使用:

          image = iter(trainloader).next()[0][0]
          

          这和做的一样:

          images, labels = iter(trainloader).next()
          image = images[0]
          

          【讨论】:

          • 注意:要生成随机样本,您必须在 DataLoader 构造中确保 shuffle=True
          猜你喜欢
          • 1970-01-01
          • 2018-10-11
          • 2021-11-26
          • 1970-01-01
          • 2021-07-15
          • 2020-07-14
          • 2019-05-02
          • 2018-12-05
          • 1970-01-01
          相关资源
          最近更新 更多