【发布时间】:2019-05-03 09:19:01
【问题描述】:
如何从 PyTorch DataLoader 中获取单个随机示例?
如果我的DataLoader 提供了多个图像和标签的 minbatch,我如何获得单个随机图像和标签?
请注意,我不希望每个 minibatch 一个图像和标签,我想要一个示例。
【问题讨论】:
如何从 PyTorch DataLoader 中获取单个随机示例?
如果我的DataLoader 提供了多个图像和标签的 minbatch,我如何获得单个随机图像和标签?
请注意,我不希望每个 minibatch 一个图像和标签,我想要一个示例。
【问题讨论】:
DataLoader的随机样本
假设DataLoader(shuffle=True)在其构造中使用,可以从DataLoader中抽取一个随机示例:
example = next(iter(dataloader))[0]
Dataset的随机样本
如果不是这样,您可以从数据集中抽取一个随机示例:
idx = torch.randint(len(dataset), (1,))
example = dataset[idx]
【讨论】:
(此答案是对@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]
【讨论】:
如果您的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]
您可以使用RandomSampler获取随机样本。
在 DataLoader 中使用 1 的 batch_size。
像这样直接从您的数据集中抽取样本:
mnist_test = datasets.MNIST('../MNIST/', train=False, transform=transform)
现在使用这个数据集来采样:
for image, label in mnist_test:
# do something with image and other attributes
(可能是最好的)见here:
inputs, classes = next(iter(dataloader))
【讨论】:
testloader.next()[0]?
DataLoader.__iter__ 应该可以工作,或者_DataLoaderIter 必须的东西。另外,如果这回答了您的问题,请考虑接受答案
next 选项。
如果您想从您的 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 并构建字典来获取要使用的图像的索引。
【讨论】:
获取随机样本的关键是将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")
【讨论】:
从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]
【讨论】:
shuffle=True。