[英]Why is my DataLoader so much slower than a for loop?
我正在為MNIST數據集編寫一個基於神經網絡的分類器。 我首先嘗試使用時期和批次的循環和索引手動加載數據。 在教程中,我看到有人使用torch.utils.data.DataLoader執行此確切任務,因此我將代碼更改為使用DataLoader。 這導致學習過程的持續時間存在重大差異。
我試圖通過使用基准測試來縮小范圍來解決這個問題。 我總是在CPU(i7 8700k)和GPU(1080ti)上進行基准測試,數據存儲在我的ssd(970 evo)上。
我首先嘗試比較使用和不使用DataLoader的Batch Gradient Descent,然后使用和不使用DataLoader來比較Mini-Batch Gradient Descent。 結果對我來說相當混亂。
| | 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是錯誤的,還是這只是錯誤的用例,循環更適合我正在做的事情?
編輯:這里有兩個小提琴,包含循環的完整代碼和dataloader變體
編輯:我相信我可能已經想出如何解決我的主要問題,dataloader和循環之間的性能差異。 通過將加載器的num_workers
參數設置為8,我設法將GPU上的DL小批量的時間減少到大約1分鍾。 雖然這肯定好於5分鍾,但它仍然很糟糕,考慮到在GPU上使用DL的miniatch與具有CPU循環的minibatch的性能相當。
transforms.ToTensor()
需要PIL Image
或np.ndarray
在范圍[0, 255]
作為輸入,並把它轉換成一個torch.FloatTensor
范圍[0.0, 1.0]
如果np.ndarray
具有dtype=np.uint8
或PIL Image
屬於其中一種模式(L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1)
docs
重新縮放和更改數據類型會影響模型的准確性。 此外, DataLoader
比批量循環更多的操作,因此時間上的差異。
PS在進行小型訓練培訓時,您應該隨機播放訓練數據
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.