【PyTorch深度学习实践】07_Dataset和Dataloader

1. Epoch,Iteration,Batch-Size

参考博客

在这里插入图片描述

2. Dataset 和 Dataloader

参考博客

功能概览

在这里插入图片描述

2.1 Dataset

torch.utils.data.Dataset是一个抽象类,不可以实例化,但是可以通过构建这个抽象类的子类来创建数据集。

重要方法(且必须改写):

getitem__():传入指定的索引index后,该方法能够根据索引返回对应的单个样本及其对应的标签(以元组形式)
__len__():返回整个数据集的大小
此外,因为 Dataset 类中提供了 __add__() 方法,所以继承之后我们的数据集也会拥有此方法,从而合并数据集只需使用 + 运算即可。

代码接口

class MyDataset(Dataset):
    def __init__(self):   
        # 初始化数据集的存储路径
        # 载入数据集(转化为tensor格式)
        # ...
    
    def __getitem__(self, index):
        # 返回单个样本及其标签,后续batch由什么组成也是取决于这个是怎么设置的
        pass
    
    def __len__(self):
        # 返回整个数据集的大小
        pass

读取数据时有两个选择,一是把所有数据都加载进来(数据量较小时),另一个是定义一个列表,存放文件名,再用文件名去读文件内容,第二种留待以后实现(数据量较大时)

举例可以看参考博客。

2.2 Dataloader

绝大多数时候需要以 batch 的形式访问数据集。Dataloader 这个接口提供了这样的功能,它能够基于我们自定义的数据集将其转换成一个可迭代对象以便我们批量访问。

重要参数

在这里插入图片描述
代码示例:

train_loader = DataLoader(dataset= dataset, batch_size=32, shuffle=True, num_workers=2,drop_last=False)

这段代码可以创建一个可迭代对象

2.2.1 例子

例:数据集内容如下:

1 -14 -15
1 -1 -15
1 -11 -14
1 0 -2
0 -4 2
1 7 -2
1 -7 -17
0 9 12
0 5 -14
1 -13 13

dataloader设置:

dataloader = DataLoader(data, batch_size=3, shuffle=False, drop_last=False)

将创建的可迭代对象列表化:

list(dataloader)
# [[tensor([[-14., -15.],
#           [ -1., -15.],
#           [-11., -14.]], dtype=torch.float64),
#   tensor([1., 1., 1.], dtype=torch.float64)],
#  [tensor([[ 0., -2.],
#           [-4.,  2.],
#           [ 7., -2.]], dtype=torch.float64),
#   tensor([1., 0., 1.], dtype=torch.float64)],
#  [tensor([[ -7., -17.],
#           [  9.,  12.],
#           [  5., -14.]], dtype=torch.float64),
#   tensor([1., 0., 0.], dtype=torch.float64)],
#  [tensor([[-13.,  13.]], dtype=torch.float64),
#   tensor([1.], dtype=torch.float64)]]

可以看出,列表化后,每一个 batch 均以列表的形式存储。这说明我们可以通过 for 循环来遍历所有的 batch,具体做法如下:

for inputs, labels in dataloader:
    print(inputs, labels)
# tensor([[-14., -15.],
#         [ -1., -15.],
#         [-11., -14.]], dtype=torch.float64) tensor([1., 1., 1.], dtype=torch.float64)
# tensor([[ 0., -2.],
#         [-4.,  2.],
#         [ 7., -2.]], dtype=torch.float64) tensor([1., 0., 1.], dtype=torch.float64)
# tensor([[ -7., -17.],
#         [  9.,  12.],
#         [  5., -14.]], dtype=torch.float64) tensor([1., 0., 0.], dtype=torch.float64)
# tensor([[-13.,  13.]], dtype=torch.float64) tensor([1.], dtype=torch.float64)
2.2.2 enumerate函数

参考博客1
参考博客2

用于记录每个batch的索引(即 iteration)
在这里插入图片描述实例:(这里为了方便展示将 batch_size 设为了1):

dataloader = DataLoader(data, batch_size=1, shuffle=True, drop_last=True)
for batch_idx, (inputs, labels) in enumerate(dataloader):
    print(batch_idx, end=' ')
    print(inputs, labels)
# 0 tensor([[-4.,  2.]], dtype=torch.float64) tensor([0.], dtype=torch.float64)
# 1 tensor([[ -1., -15.]], dtype=torch.float64) tensor([1.], dtype=torch.float64)
# 2 tensor([[ 0., -2.]], dtype=torch.float64) tensor([1.], dtype=torch.float64)
# 3 tensor([[ 7., -2.]], dtype=torch.float64) tensor([1.], dtype=torch.float64)
# 4 tensor([[ 9., 12.]], dtype=torch.float64) tensor([0.], dtype=torch.float64)
# 5 tensor([[  5., -14.]], dtype=torch.float64) tensor([0.], dtype=torch.float64)
# 6 tensor([[-11., -14.]], dtype=torch.float64) tensor([1.], dtype=torch.float64)
# 7 tensor([[-14., -15.]], dtype=torch.float64) tensor([1.], dtype=torch.float64)
# 8 tensor([[ -7., -17.]], dtype=torch.float64) tensor([1.], dtype=torch.float64)
# 9 tensor([[-13.,  13.]], dtype=torch.float64) tensor([1.], dtype=torch.float64)

3. 完整代码

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

# 1. Dataset和Dataloader 准备数据集
class DiabetesDataset(Dataset):
    def __init__(self, filepath):   # 也可以删去filepath,把真正路径放到下面第一行代码的第一个参数
        xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32)
        self.len = xy.shape[0]      # 例如数据集是N行(N个样本),8+1列(8个特征,1个输出),shape就是一个元组,为(N,9),shape[0]就是N
        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(x_data)
        return self.len


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

# 2.设计模型
class Model(torch.nn.Module):
    def __init__(self):
        super().__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()   # 可以构造Sigmoid,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.损失函数和优化器
# 还是二分类,直接用BCE损失即可
criterion = torch.nn.BCELoss(size_average=True)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)

# 4.训练过程
if __name__ == '__main__':
    for epoch in range(10):
         for i, data in enumerate(train_loader,0):
        #  1.准备数据
            inputs, labels = data
        #  2. 前馈
            y_pred = model(inputs)
            loss = criterion(y_pred, labels)
            print(epoch, i, loss.item())
        #  3. 反馈
            optimizer.zero_grad()
            loss.backward()
        # 4. 更新
            optimizer.step()
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值