我正在为MNIST数据集编写一个基于神经网络的分类器。我首先尝试使用周期和批处理的循环和索引手动加载数据。在一篇教程中,我看到有人使用torch.utils.data.DataLoader来完成这项任务,所以我更改了代码,改为使用DataLoader。这导致了学习过程中持续时间的重大差异。
我试图通过使用基准来缩小范围来解决这个问题。我总是在中央处理器(I7 8700k)和图形处理器(1080ti)上进行基准测试,数据存储在我的固态硬盘(970evo)上。
我首先尝试比较使用和不使用DataLoader的批量梯度下降,然后比较使用和不使用DataLoader的小批量梯度下降。结果让我很困惑。
| | BGD | BGD with DL | MB-GD | MB-GD with DL |
|-----------------|-------------|-------------|-------------|---------------|
| Time on CPU | 00:00:56.70 | 00:05:59.31 | 00:01:31.29 | 00:07:46.56 |
| Accuracy on CPU | 82.47 | 33.44 | 94.84 | 87.67 |
| Time on GPU | 00:00:15.89 | 00:05:41.79 | 00:00:17.48 | 00:05:37.33 |
| Accuracy on GPU | 82.3 | 30.66 | 94.88 | 87.74 |
| Batch Size | M | M | 500 | 500 |
| Epoch | 100 | 100 | 100 | 100 |
这是使用DataLoader的代码,精简为要点。
num_epoch = 100
train_loader = DataLoader(batch_size=500, shuffle=False, dataset=dataset_train)
for epoch in range(num_epoch):
for i, (images, labels) in enumerate(train_loader):
images = images.view(-1, 28 * 28)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
vs使用循环的代码
num_epoch = 100
batch_size = 500
num_batch = int(len(dataset_train) / batch_size)
for epoch in range(num_epoch):
for batch_idx in range(num_batch):
images = dataset_train.data[batch_idx*batch_size:(batch_idx+1)*batch_size].view(-1, 28 * 28)
labels = dataset_train.targets[batch_idx*batch_size:(batch_idx+1)*batch_size]
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
我希望DataLoader在时间和性能方面至少在接近循环的地方执行,但不会慢10倍。我也不明白为什么DataLoader会影响模型的准确性。
我是不是用错了DataLoader,或者这只是一个错误的用例,循环更适合我正在做的事情?
编辑:这里有两个小提琴,包含loop和dataloader变体的完整代码
编辑:我相信我可能已经解决了我的主要问题,dataloader和循环之间的性能差异。通过将加载器的num_workers
参数设置为8,我设法将在图形处理器上使用DL的小批量处理时间降低到1分钟左右。虽然这肯定比5分钟要好,但考虑到在GPU上使用DL的minibatch与在CPU上使用循环的minibatch的性能相当,这仍然很糟糕。
发布于 2019-05-16 17:22:57
transforms.ToTensor()
将[0, 255]
范围内的 PIL Image
或 np.ndarray
作为输入,并将其转换为 [0.0, 1.0]
范围内的 torch.FloatTensor
如果 np.ndarray
具有 dtype=np.uint8
或PIL Image
属于模式之一(L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1)
docs
重新缩放和更改数据类型会影响模型精度。此外,DataLoader
在批处理上执行的操作比您的循环更多,因此计时上的差异。
附注:在进行小批量训练时,您应该对训练数据进行混洗
https://stackoverflow.com/questions/56101111
复制相似问题