Pytorch:八、加載數(shù)據(jù)集


Dataloader主要是拿出一些Mini-Batch來供訓(xùn)練時(shí)能夠快速使用。使用batch可以提升計(jì)算速度,但是其求值的性能會(huì)有些問題。因此選用了Mini-Batch來進(jìn)行綜合;

使用了Mini-Batch后都得用下面這樣的嵌套循環(huán)

#train cycle
for epoch in range(training_epochs):
    #每次迭代執(zhí)行一個(gè)Mini-Batch
    for i in range(total_batch):
  • 需要了解的概念:
  1. epoch所有的樣本都進(jìn)行了一次正,反向傳播。即所有樣本都進(jìn)行了一次訓(xùn)練;
  2. Batch-Size:每次訓(xùn)練時(shí),所用的樣本數(shù)量;
  3. Iteration:分了多少個(gè)batch,也就是內(nèi)層的那個(gè)迭代執(zhí)行了多少次;
    如:現(xiàn)有1w個(gè)樣本,batch是1k個(gè),即每次拿1k個(gè)樣本。那么Iteration就是10000/1000=10

Dataloader:需要知道目標(biāo)數(shù)據(jù)的索引[i]以及長(zhǎng)度len。這樣一來,dataloader就可以自動(dòng)對(duì)dataset進(jìn)行小批量的數(shù)據(jù)集的生成:

dataloader工作流程

第一步,shuffle:就是打亂順序;第二步,將打亂后的數(shù)據(jù)進(jìn)行分組,這里將兩個(gè)樣本作為一個(gè)batch

  • 常見的讀取數(shù)據(jù)集的方法:
  1. 直接讀取所有數(shù)據(jù),這種方法適用于數(shù)據(jù)集本身就不算大的數(shù)據(jù);
  2. 對(duì)于數(shù)據(jù)量很大的一堆文件/圖片之類的,可以通過一個(gè)list來保存其地址一類的,然后在用到的時(shí)候再進(jìn)行讀?。?/li>

如何去定義一個(gè)數(shù)據(jù)集

import torch
#Dataset是個(gè)抽象類
from torch.utils.data import Dataset
#torch中幫助加載數(shù)據(jù)的類
from torch.utils.data import DataLoader
import numpy as np

class DiabetesDataset(Dataset):
    def __init__(self):
        pass
    
    #通過這個(gè)方法來支持下標(biāo)操作
    def __getitem__(self, index):
        pass
    
    def __len__(self):
        pass
    
dataset = DiabetesDataset()
#torch直接提供的,一般都是設(shè)置這四個(gè)參數(shù)
#num_workers表示讀數(shù)據(jù)的時(shí)候可以兼容的線程數(shù)
train_loader = DataLoader(dataset = dataset
                         ,batch_size = 32
                         ,shuffle = True
                         ,num_workers = 2
                         )

但是在windows下運(yùn)行上面的loader代碼好像以后會(huì)報(bào)錯(cuò):

解決方法:將loader封裝到if中,而不是直接頂格寫出來

if __name__ == '__main__':
    for epoch in range(100):
        #將train_loader所拿出的x, y 放入到data中去
        for i, data in enumerate(train_loader, 0):

至此,加載數(shù)據(jù)集的功能就寫好了,然后再加上前面寫的model的代碼就變成了:

class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.linear1 = torch.nn.Linear(8, 6)
        self.linear2 = torch.nn.Linear(6, 4)
        self.linear3 = torch.nn.Linear(4, 1)
        #注意這里用的是nn下的sigmoid,
        self.sigmoid = torch.nn.Sigmoid()

    def forward(self, x):
        x = self.sigmoid(self.linear1(x))
        x = self.sigmoid(self.linear2(x))
        x = self.sigmoid(self.linear3(x))
        return x

model = Model()

#3. 構(gòu)造損失函數(shù)和優(yōu)化器
#和之前一樣
criterion = torch.nn.BCELoss(size_average=True)

optimizer = torch.optim.SGD(model.parameters(), lr=0.1)

注意,上面這段代碼在jupyter中無法運(yùn)行,因?yàn)檫@玩意兒不能多線程。然后在pycharm中可以運(yùn)行,但是速度很慢。這應(yīng)該是因?yàn)閿?shù)據(jù)量太少,所以多線程的調(diào)用反而影響了讀取速度照成的;

程序以及對(duì)應(yīng)的模塊

主要就是在1和4進(jìn)行了改造:1中不再是加載所有數(shù)據(jù)了,而是構(gòu)造并使用了dataset和dataloader;4中則是改成了嵌套循環(huán),適配mini-batch;

這樣一來,就完成了對(duì)于糖尿病數(shù)據(jù)集進(jìn)行分類的神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)流程。

torchvision中提供的數(shù)據(jù)集們:

這些數(shù)據(jù)集都派生自dataset,所以都可以用dataloader進(jìn)行加載,也有getitem, len等方法,還可以用多進(jìn)程進(jìn)行加速

對(duì)其他的數(shù)據(jù)集進(jìn)行同樣的操作

transform是指要將數(shù)據(jù)轉(zhuǎn)為想要的數(shù)據(jù)類型,這里是張量;
在test_loader那里是不用shuffle的,以保證每次輸出的順序都是一樣的

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容