摘要:我們在打撲克,一摞的撲克牌就相當於dataset,拿牌的手相當於神經網路。而dataloader相當於抽牌的過程,它可以控制我們抽幾張牌,用幾隻手抽牌。
官網地址:
class torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=None, sampler=None, batch_sampler=None, num_workers=0, collate_fn=None, pin_memory=False, drop_last=False, timeout=0, worker_init_fn=None, multiprocessing_context=None, generator=None, *, prefetch_factor=None, persistent_workers=False, pin_memory_device='')
由此可見,DataLoder必須需要輸入的引數只有\(dataset\)。
dataset(Dataset): 資料集的儲存的路徑位置等資訊
batch_size(int): 每次取資料的數量,比如batchi_size=2,那麼每次取2條資料
shuffle(bool): True: 打亂資料(可以理解為打牌中洗牌的過程); False: 不打亂。預設為False
num_workers(int): 載入資料的程序,多程序會更快。預設為0,即用主程序進行載入。但在windows系統下,num_workers如果非0,可能會出現 BrokenPipeError[Error 32] 錯誤
drop_last(bool): 比如我們從100條資料中每次取3條,到最後會餘下1條,如果drop_last=True,那麼這條資料會被捨棄(即只要前面99條資料);如果為False,則保留這條資料
首先import dataset,dataset會返回一個資料的img和target
然後import dataloder,並設定\(batch\_size\),比如\(batch\_size=4\),那麼dataloder會獲取這些資料:dataset[0]=img0, target0; dataset[1]=img1, target1; dataset[2]=img2, target2; dataset[3]=img3, target3. 並分別將其中的4個img和4個target進行打包,並返回打包好的imgs和targets
比如下面這串程式碼:
import torchvision
from torch.utils.data import DataLoader
#測試集,並將PIL資料轉化為tensor型別
test_data=torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor())
#batch_size=4:每次從test_data中取4個資料集並打包
test_loader=DataLoader(dataset=test_data, batch_size=4, shuffle=True, num_workers=0, drop_last=False)
這裡的test_loader會取出test_data[0]、test_data[1]、test_data[2]、test_data[3]的img和target,並分別打包。返回兩個引數:打包好的imgs,打包好的taregts
程式碼範例如下:
import torchvision
from torch.utils.data import DataLoader
#測試集,並將PIL資料轉化為tensor型別
test_data=torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor())
#batch_size=4:每次從test_data中取4個資料集並打包
test_loader=DataLoader(dataset=test_data, batch_size=4, shuffle=True, num_workers=0, drop_last=False)
#測試資料集中第一章圖片及target
img, target=test_data[0]
print(img.shape)
print(target)
#取出test_loader中的圖片
for data in test_loader:
imgs,targets = data
print(imgs.shape) #[Run] torch.Size([4, 3, 32, 32]) 4張圖片打包,3通道,32×32
print(targets) #[Run] tensor([3, 5, 2, 7]) 4張圖,每張圖片對應的標籤分別是3,5,2,7(某一次print的舉例,每次print結果不太一樣)
在11行處debug一下可以發現,test_loader中有個叫sampler的取樣器,採取的是隨機取樣的方式,也就是說這batch_size=4時,每次抓取的4張圖片都是隨機抓取的。
用tensorboard就可以視覺化了,具體操作改一下上面程式碼最後的for迴圈就好了
from torch.utils.tensorboard import SummaryWriter
writer=SummaryWriter("dataloder")
step=0 #tensorboard步長引數
for data in test_loader:
imgs,targets = data
# print(imgs.shape) #[Run] torch.Size([4, 3, 32, 32]) 4張圖片打包,3通道,32×32
# print(targets) #[Run] tensor([3, 5, 2, 7]) 4張圖,每張圖片對應的標籤分別是3,5,2,7(某一次print的舉例,每次print結果不太一樣)
writer.add_images("test_data",imgs,step) #注意這裡是add_images,不是add_image。因為這裡是加入了64張圖
step=step+1
writer.close()
首先將shuffle設定為False:
test_loader=DataLoader(dataset=test_data, batch_size=64, shuffle=True, num_workers=0, drop_last=False)
然後對(2)的程式碼進行修改,執行程式碼:
for epoch in range(2): #假設打兩次牌,我們來觀察兩次牌中間的洗牌情況
step = 0 # tensorboard步長引數
for data in test_loader:
imgs,targets = data
# print(imgs.shape) #[Run] torch.Size([4, 3, 32, 32]) 4張圖片打包,3通道,32×32
# print(targets) #[Run] tensor([3, 5, 2, 7]) 4張圖,每張圖片對應的標籤分別是3,5,2,7(某一次print的舉例,每次print結果不太一樣)
writer.add_images("Epoch: {}".format(epoch),imgs,step) #注意這裡是add_images,不是add_image。因為這裡是加入了64張圖
step=step+1
writer.close()
結果顯示,未洗牌時執行的結果是一樣的: