神经网络和深度学习-加载数据集DataLoader

加载数据集DataLoader

Dataloader的概念

dataloader的主要目标是拿出Mini-Batch这一组数据来进行训练

在处理多维特征输入这一文章中,使用diabetes这一数据集,在训练时我们使用的是所有的输入x,在梯度计算采用的是随机梯度下降(SDG),每次选用一个样本来进行梯度计算,但存在缺点,优化时间过长

而在Mini-Batch中我们选择小批量中的所有样本,可以最大化的利用向量的优势,来提升计算速度

在使用Mini-Batch我们要了解三个概念

  • Epoch

  • Batch-Size

  • Iterations

首先我们来看一下Epoch,我们采用Mini-Batch之后要使用一个嵌套循环,内循环是每一次迭代都执行一个Mini-Batch,这两个循环相当于把所有的Mini-Batch都跑了一遍

神经网络和深度学习-加载数据集DataLoader_第1张图片

Epoch的定义就是:所有训练样本都进行一次前向传播和反向传播的过程

Batch-Size的定义是:进行一次前馈和反馈的训练样本数量

Iterations的定义是:所有的样本/Batch-Size

Dataloader的作用

我们要做小批量的训练时,要确定一些重要的参数

  • batch-size

  • shuffle:打乱顺序,为了提高数据样本的随机性可以选择对数据集进行shuffle

  • num_workers :并行操作的数量

  • [i]:支持索引

  • len:长度

神经网络和深度学习-加载数据集DataLoader_第2张图片

定义Dataset和DataLoader

我们来看一下代码中是如何定义dataset的,在torch.utils.data工具包中包含了这两个类

其中dataset是一个抽象的类,不能实例化,只能被其他的子类继承,我们想要使用的时候必须定义一个自己 的类来继承使用

dataloader是用来帮助加载数据的,我们可以实例化一个dataloader

例如下面自定义一个DiabetesDataset的类

神经网络和深度学习-加载数据集DataLoader_第3张图片

getitem这个方法是一个模板方法,是为了实例化这个对象之后能够支持下标操作,通过索引来取出数据

len这个方法同样是模板方法,为了返回数据集中的数据条数

接下来就可以用自定义的DiabetesDataset类来实例化dataset对象

我们在构造数据集的时候一般有两种选择

  • 把所有数据在init中加载进来,放入内存中,再用getitem根据索引传出数据,适用于数据集本身的容量不大

  • 类似于图像、语音这种非结构的大数据集,不能一次性加载到内存中时,定义一个列表,数据集里面得每一条数据的文件名放入相应的列表中

我们在windows中使用num_workers进行训练会报错,原因是在windows下和Linux下的进程库是不一样的。所以用spawn替代了fork,所以其中处理的方式不同,会出现RuntimeError

解决方法:将要训练的代码train_loader进行封装起来(if语句或者是函数中)

神经网络和深度学习-加载数据集DataLoader_第4张图片

我们在代码中进行改动

神经网络和深度学习-加载数据集DataLoader_第5张图片

数据集的实现

在构造函数中我们需要一个filepath:描述文件来自什么地方,其次需要通过self.len来获取数据集的长度

神经网络和深度学习-加载数据集DataLoader_第6张图片

DataLoader的使用

使用enumerate可以获得当前迭代的次数,train_loader中拿出来的元组(x,y)放入data中,所以在训练之前把inputs(x_data)和labels(y_data)从data中取出,此时这两个数据都是Tensor。

也可以一开始就在for循环中使用i,(x,y),就可以省去下面那句

神经网络和深度学习-加载数据集DataLoader_第7张图片

完整代码

import numpy as np
import torch
from torch.utils.data import Dataset, DataLoader


# prepare dataset
class DiabetesDataset(Dataset):
    def __init__(self, filepath):
        xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32)
        self.len = xy.shape[0]  # shape(多少行,多少列)
        self.x_data = torch.from_numpy(xy[:, :-1])
        self.y_data = torch.from_numpy(xy[:, [-1]])

    def __getitem__(self, index):
        return self.x_data[index], self.y_data[index]

    def __len__(self):
        return self.len


dataset = DiabetesDataset('diabetes.csv.gz')
train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=2)  # num_workers 多线程


# design model using class
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)
        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()


# construct loss and optimizer
criterion = torch.nn.BCELoss(size_average=True)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)


# training cycle forward, backward, update
if __name__ == '__main__':
    for epoch in range(100):
        for i, data in enumerate(train_loader, 0):  # train_loader 是先shuffle后mini_batch
            # 1. prepare data
            x_data, y_data = data
            # 2. Forward
            y_pred = model(x_data)
            loss = criterion(y_pred, y_data)
            print(epoch, i, loss.item())
            # 3. Backward
            optimizer.zero_grad()
            loss.backward()
            # 4. Update
            optimizer.step()

你可能感兴趣的:(神经网络,Python深度学习,深度学习,神经网络,计算机视觉)