Jim*_*ang 4 python shuffle machine-learning pytorch dataloader
我已经多次使用 pytorch 数据加载器的 shuffle 选项。但我想知道这种 shuffle 何时发生以及它是否在迭代期间动态执行。以下面的代码为例:
namesDataset = NamesDataset()
namesTrainLoader = DataLoader(namesDataset, batch_size=16, shuffle=True)
for batch_data in namesTrainLoader:
print(batch_data)
Run Code Online (Sandbox Code Playgroud)
当我们定义“namesTrainLoader”时,是否意味着shuffle结束,接下来的迭代将基于固定的数据顺序?定义了 namesTrainLoader 后,for 循环中会不会有任何随机性?
我试图用一些特殊值替换“batch_data”的一半:
for batch_data in namesTrainLoader:
batch_data[?8] = special_val
pre = model(batch_data)
Run Code Online (Sandbox Code Playgroud)
假设将有无数个 epoch,“模型”最终会看到“namesTrainLoader”中的所有数据吗?还是说“namesTrainLoader”的一半数据实际上丢给了“model”?
混洗在创建迭代器时发生。在 for 循环的情况下,这发生在 for 循环开始之前。
您可以使用以下命令手动创建迭代器:
# Iterator gets created, the data has been shuffled at this point.
data_iterator = iter(namesTrainLoader)
Run Code Online (Sandbox Code Playgroud)
默认情况下,数据加载器使用torch.utils.data.RandomSamplerif 您设置shuffle=True(不提供您自己的采样器)。它的实现非常简单,您可以通过查看该RandomSampler.__iter__方法来查看创建迭代器时数据被打乱的位置:
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())
Run Code Online (Sandbox Code Playgroud)
return 语句是重排发生的重要部分。它只是创建索引的随机排列。
这意味着每次完全使用迭代器时,您都会看到整个数据集,只是每次的顺序不同。因此没有数据丢失(不包括带有 的情况drop_last=True)并且您的模型将看到每个时期的所有数据。
torch.utils.data.DataLoader 您可以在此处查看 PyTorch 的实现。
如果您指定shuffle=True torch.utils.data.RandomSampler将被使用(SequentialSampler否则)。
当创建实例时DataLoader,不会对任何内容进行洗牌,它只是实例化对象的必要私有成员和其他设置之类的东西。
当您在迭代期间发出特殊__iter__方法时,就像您的情况一样,会返回一个特殊对象,_SingleProcessDataLoader(self)该对象名为数据生成器(可能是批处理、洗牌等,假设您不使用多处理)。
要找到所有私有和帮助程序相关的方法,需要遵循一些兔子洞,但它基本上所做的是使用底层sampler来获取索引,这些索引用于从torch.utils.data.Dataset.
采样器运行直到耗尽并且重复该过程(通常是一个时期)。
定义namesTrainLoader后for循环中会有随机性吗?
在每个周期/纪元开始时RandomSampler都会对索引进行洗牌__iter__,所以是的,它将在每个纪元之前(当调用并返回新值时)进行随机化_SingleProcessDataLoader(self),这可以无限期地完成。
[...]“模型”最终会看到“namesTrainLoader”中的所有数据吗?
是的,它最终很可能会看到所有数据点
| 归档时间: |
|
| 查看次数: |
3195 次 |
| 最近记录: |