PyTorch 入门与实践(三)加载数据集(Dataset、DataLoader)

从零开始Pytorch深度学习-数据封装 数据封装 深度学习整个的过程由几个模块组成:数据封装->模型定义->损失函数,优化器定义->训练函数定义 这部分主要讲数据封装: 我们以图片分类为例,图1为文件的结构(5种花) 图1 我们的绝对路径是:F:\pythonProject\blog\flower_photos 我们先设计一个函数,用来提取该路径下的所有图片,对应的标签(0-4对应5种花的类别)。 def read_split_data(root: str, val_rate: float = 0.2): 阅读详情

来自 B 站刘二大人的《PyTorch深度学习实践》P8 的学习笔记

上一篇 处理多维特征的输入 的时候我们提到了 Mini-Batch,也就是训练时,一个 epoch 只遍历 N N N 个 samples(行), N ≤ 总 行 数 N \le 总行数 N≤总行数,要实现这个,就要用到 PyTorch 强大的数据加载工具类:Dataset、DataLoader。

  • 一次性输入全部的 Batch 的优势在于计算性能,而且更容易用于并行计算;

  • 一次性输入一个样本的优势在于数据的随机性使得网络优化更容易走出鞍点,更易于训练收敛;

  • 我们折中使用 Mini-Batch,集成计算性能和优化性能。

Mini-Batch

使用 Mini-Batch 之后,训练的代码需要两层 for 循环:

  • 一个 Epoch:外层 for 循环一次,遍历完所有的样本(所有的样本都前馈和反向传播了一次)
  • 一个 Mini-Batch:内层 for 循环一次,前馈和反向传播一个 Batch-Size 的样本(一次性输入 batch-size 数量的样本到 model() 里)
  • 一个 Iteration:一次迭代一个 Mini-Batch

1

Dataset、DataLoader

DataLoader:batch_size=2,shuffle=True

shuffle 的意义在于打乱数据,提供随机性。
2
Dataset 是一个抽象类,不能直接实例化,我们要自定义自己的数据类并继承 Dataset。

由于我们的数据类的实例要作为参数放到 DataLoader 类里面返回一个数据生成器,所以继承了 Dataset 的数据类要至少实现下面三个方法:
3
这些双下划线方法都是 Python 自带的魔法方法,在自定义的类里面实现它们之后,类的实例就会具备相应的取数功能:

  • 例如定义了 def __getitem__(self, index),类的实例 dataset 就可以通过数组下标 dataset[index] 的方式调用 __getitem__(self, index)。
  • 例如定义了 def __len__(self),类的实例 dataset 就可以通过 Python 内置方法 len(dataset) 来调用 __len__(self),并希望这个函数返回数据长度。
    4
    把我们自定义的数据类实例化之后,传参到 DataLoader() 中,得到
    5
    在 windows 下,训练的循环需要在 if __name__ == "__main__": 里面,否则不能设置 num_worker 参数来使用多线程加载数据。
    6
Using DataLoader

每一次迭代 train_loader 得到的是 batch_size 大小的样本矩阵:
7
train_loader 的返回值是调用 __getitem__() 的结果
8
神经网络的建模步骤从构建 Mini-Batch 数据加载器开始
9

torchvision.datasets

torchvision.datasets 这个包里面有很多常用的数据集,这些 dataset 都继承自 PyTorch 的 Dataset 类,并实现了 __getitem__ 和 __len__ 方法,因此可以直接实例化之后传入 DataLoader 来获取 data_loader。
10
例如:指定的数据集位置如果没有相应的数据集,它会下载,如果有,则不会再下载。
11

完整代码
  • diabetes 数据集
import copy

import numpy as np
import torch
from torch import nn, optim
from torch.nn import functional as F
from torch.utils.data import DataLoader, Dataset


class DiabetesDataset(Dataset):
    def __init__(self):
        xy = np.loadtxt("../datasets/diabetes/diabetes.csv.gz", delimiter=',', dtype=np.float32)
        self.len = xy.shape[0]
        self.x_data = torch.from_numpy(xy[:, :-1])
        self.y_data = torch.from_numpy(xy[:, [-1]])

    def __getitem__(self, index):
        """很明显 Index 是行坐标"""
        return self.x_data[index], self.y_data[index]

    def __len__(self):
        return self.len


dataset = DiabetesDataset()
data_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True)
print(len(dataset))


class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.linear1 = nn.Linear(8, 6)
        self.linear2 = nn.Linear(6, 4)
        self.linear3 = nn.Linear(4, 1)
        self.activate = nn.Sigmoid()

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


model = Model()

criterion = nn.BCELoss()
optimizer = optim.AdamW(model.parameters(), lr=0.003)  # SGD 效果不好,那效果看起来像没有优化一样

if __name__ == '__main__':
    for epoch in range(50):
        TP = 0  # 预测正确的总个数
        loss_lst = []
        for i, (x, y) in enumerate(data_loader):
            y_pred = model(x)
            loss = criterion(y_pred, y)

            loss_lst.append(loss.item())
            # 以下是计算一个 Mini-Batch 的精确度
            y_hat = copy.copy(y_pred.data.numpy())
            y_hat[y_hat >= 0.5] = 1.0
            y_hat[y_hat < 0.5] = 0.0
            TP += np.sum(y.data.numpy().flatten() == y_hat.flatten())
            # 也可以下面这样计算,后面TP要转成numpy()才能计算acc
            # y_hat = torch.round(y_pred.data)  # 取每个元素的最接近的整数,注:0.5接近0
            # TP += (y.data.flatten() == y_hat.flatten()).sum()  # 这里不能用 numpy.sum(), torch.sum()可以

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        acc = TP / len(dataset)
        print("epoch:", epoch, "loss:", np.mean(loss_lst), "acc:", acc, "TP:", TP)
  • MNIST 数据集
import os
import copy

import numpy as np
import torch
from torch import nn, optim
from torch.nn import functional as F
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

import matplotlib.pyplot as plt


trans = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

train_set = datasets.MNIST(root="../datasets/mnist",
                           train=True,
                           transform=trans,  # 原始是 PIL Image 格式
                           download=True)
test_set = datasets.MNIST(root="../datasets/mnist",
                          train=False,
                          transform=trans,
                          download=True)

train_loader = DataLoader(train_set, batch_size=128, shuffle=True)
test_loader = DataLoader(test_set, batch_size=32, shuffle=True)

# examples = enumerate(train_loader)
# _, (x, y) = next(examples)
# print(x.shape, y.shape)


class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.linear1 = nn.Linear(28*28, 60)  # MNIST 每个图像大小为 28*28
        self.linear2 = nn.Linear(60, 10)
        self.activate = nn.ReLU()

    def forward(self, x):
        x = self.activate(self.linear1(x))
        x = F.softmax(self.linear2(x))
        return x


model = Model()


def train(model, train_loader, save_dst="./models/acc_0.96.pth"):
    global acc

    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters())

    for epoch in range(5):

        TP = 0
        loss_lst = []
        for i, (imgs, labels) in enumerate(train_loader):
            x = imgs.reshape(-1, 28*28)  # 若不reshape,imgs矩阵默认为[32*28, 28]
            y_pred = model(x)
            # print("x:", x.shape, "y:", labels.shape, "y_pred:", y_pred.shape)

            loss = criterion(y_pred, labels)

            y_hat = copy.copy(y_pred)
            TP += torch.sum(labels.flatten() == torch.argmax(y_hat, dim=1))

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        acc = TP.data.numpy() / len(train_set)
        print("epoch:", epoch, "loss:", np.mean(loss_lst), "acc:", round(acc, 3), "TP:", TP)

    # 保存模型
    torch.save(model.state_dict(), os.path.join(save_dst, f"acc_{round(acc, 2)}.pth"))


def test(model, test_loader, load_dst="./models/acc_0.96.pth"):
    TP = 0
    model.load_state_dict(torch.load(load_dst))

    for i, (imgs, labels) in enumerate(test_loader):
        x = imgs.reshape(-1, 28*28)
        with torch.no_grad():
            y_pred = model(x)
        # print("x:", x.shape, "y:", labels.shape, "y_pred:", y_pred.shape)

        y_hat = copy.copy(y_pred)
        TP += torch.sum(labels.flatten() == torch.argmax(y_hat, dim=1))
    acc = TP.data.numpy() / len(test_set)
    print("acc:", round(acc, 4), "TP:", TP)


def draw(model, test_loader, load_dst="./models/acc_0.96.pth"):
    model.load_state_dict(torch.load(load_dst))

    examples = enumerate(test_loader)
    _, (imgs, labels) = next(examples)
    x = imgs.reshape(-1, 28 * 28)

    with torch.no_grad():
        y_pred = model(x)

    for i in range(6):
    """选取mini-batch中32个图像的前6个"""
        plt.subplot(2, 3, i + 1)
        plt.tight_layout()
        plt.imshow(imgs[i][0], cmap='gray', interpolation='none')
        plt.title("Prediction: {}".format(
            y_pred.data.max(1, keepdim=True)[1][i].item()))
        plt.xticks([])
        plt.yticks([])
    plt.show()


if __name__ == '__main__':
    train(model, train_loader)
    # test(model, test_loader, load_dst="./models/acc_0.96.pth")
    draw(model, test_loader, load_dst="./models/acc_0.96.pth")

预测结果如下:
请添加图片描述

绘图代码参考:Pytorch+torchvisio MNIST手写数字识别

课后练习
  • 在 Kaggle 获取 Titanic dataset:https://www.kaggle.com/c/titanic/data
  • 构建一个分类神经网络,使用 DataLoader 作为数据加载器,训练并得出结果,按照比赛的说明将结果格式化后提交。
Pytorch深度学习加载数据集的方式 图像分类数据集的加载方式及类别json文件的生成 阅读详情

相关推荐

pytorch的自定义数据集/DataLoader和Dataset重写

目录背景介绍DataLoader介绍Dataset 介绍工作原理继承__init__方法__getitem__方法__len__方法使用总结 背景介绍   做Modulation Recognition的时候需要加载自定义的数据集,这就涉及到DataLoader和Dataset类中的方法重写了。 DataLoader介绍   源码中的介绍是: *Data loader. Combines a dataset and a sampler, and provides an iterable over the g

CCjoffrey的博客 9607

深度学习(PyTorch)——Dataset&DataLoader 加载数据集

深度学习(PyTorch)——Dataset&DataLoader 加载数据集

qq_42233059的博客 1882

PyTorch数据准备:从基础Dataset到高效DataLoader

import osimport cv2""":param root_dir: 图片根目录,子目录名为类别名:param transform: 图像变换组合"""# 使用OpenCV读取图像(BGR格式)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转换为RGB# 定义图像变换])# 使用示例当默认的batch组装方式不满足需求时,可以自定义collate_fn# batch是包含多个__getitem__返回值的列表。

wyy202206174248的博客 1756

pytroch学习笔记三:数据的读取机制

机器学习的五大模块: 数据模块又可分为以下几部分: ● 数据的收集:Image、label ● 数据的划分:train、test、valid ● 数据的读取:DataLoader,有两个子模块,Sampler和Dataset,Sampler是对数据集生成索引index,DataSet是根据索引读取数据 ● 数据预处理:torchvision.transforms模块 所以这一节主要介绍pytorch中数据的读取模块 一、DataLoader torch.utils.data.DataLoader():构建

Dear_learner的博客 5161

【Pytorch】从0开始的数据集制作,从numpy数组到Dataset,再到Dataloader

从0创建一个Datalader类的数据集 完整代码 行行注释

Ejemplarr的博客 6254

pytorch数据读取:DataLoader与Dataset

目录: 0 My Plan /****第一部分概述*****/ 1.1 机器学习介绍 1.2 机器学习学习线路 /****第二部分回归*******/ 2.1 回归 2.2 误差分析 2.3 梯度下降法 2.4 Hw1:pm2.5 Prediction ...

liupc的学习笔记 2891

Pytorch加载自己的数据集(使用DataLoader读取Dataset)

1. 我们经常可以看到Pytorch加载数据集会用到官方整理好的数据集。很多时候我们需要加载自己的数据集,这时候我们需要使用Dataset和DataLoader Dataset:是被封装进DataLoader里,实现该方法封装自己的数据和标签。 DataLoader:被封装入DataLoaderIter里,实现该方法达到数据的划分。 2.Dataset 阅读源码后,我们可以指导,继承该方法必须.........

l8947943的博客 5万+

PyTorch基础-自定义数据集和数据加载器(2)

ETL是用来描述将数据从来源端经过抽取、转换、加载至目的端的过程。在机器学习中处理数据集的流程为: 提取:从数据源提取数据。 转换:将我们的数据转换为张量形式。 加载:将我们的数据放入对象以使其易于访问。 一、加载数据集 PyTorch 提供了两个数据原语: 分别是 torch.utils.data.Dataset和torch.utils.data.DataLoader 可以在预加载的数据集或者自己的数据集上使用。其中Dataset表示存储样本及其对应的标签,用...

3321

Pytorch数据加载——Dataset和DataLoader详解

一、可迭代对象与迭代器简介 可迭代对象(iterable):实现了 __iter__ 方法,该方法返回一个迭代器对象; 迭代器(iterator):迭代器含有 __iter__ 和 next 方法,当调用 __iter__ 返回迭代器自身,当调用 next() 方法返回容器下一个值; 二者关系:使用 iter(可迭代对象) 转换为 (迭代器). 二、pytorch输入数据pipline“三步走”策略 一般pytorch的数据加载到模型的操作顺序如下: 1、创建一个 Dataset 对象,必须实

loveliuzz的博客 3万+

PyTorch 入门实战(三)——Dataset和DataLoader

1.Dataset是一个抽象类,需要派生一个子类构造数据集,需要改写的方法有__init__等。2.DataLoader是一个迭代器,方便我们访问Dataset里的对象,值得注意的的参数设置:如果放在cpu上跑,可以不管,但是放在GPU上则需要设置为0;或者在DataLoader操作之后将Tensor放在GPU上。3.数据和标签是tuple元组的形式,使用Dataloader然后使用enumerate函数访问它们。

黄笳倞的博客 3万+

PyTorch学习笔记(三)——Dataset和DataLoader

目录一、一级目录1.1 二级目录1.1.1 三级目录 一、一级目录 1.1 二级目录 1.1.1 三级目录

⚡ 4218

pytorch划分数据集的两种方法(dataset, dataloader)

Pytorch提供的对数据集进行操作的函数详见:https://pytorch.org/docs/master/data.html#torch.utils.data.SubsetRandomSampler torch的这个文件包含了一些关于数据集处理的类: class torch.utils.data.Dataset: 一个抽象类, 所有其他类的数据集类都应该是它的子类。而且其子类必须重载两个重要的函数:len(提供数据集的大小)、getitem(支持整数索引)。 class torch.utils.dat

程序员养成日记 3万+

给MATLAB安装runtime插件

输入你刚刚下载压缩包的位置(小白提示:在 此电脑 中找到压缩包位置,右键属性复制位置)(!设置好以后然后填写下面输出exe文件的信息,包括文件的名字、作者、Email、公司、概述、描述,下面还可以选择额外的安装选项,exe文件运行需要的其他文件(图像、子程序等)、提供给用户的文件(readme.txt等)(很多方法是官网下载,但在官网下载还是会版本不对应,所以直接在你所用的MATLAB里搜索安装链接最靠谱)(!5.可以打包程序了(你发送文件的人电脑里没有MATLAB也可以查看运行你的程序了)

Pei_hua100的专栏 1万+

PyTorch|Dataset与DataLoader使用、构建自定义数据集

构建自定义的Dataset类,需要继承TensorFlow的官方dataset类自定义Dataset类必须实现三个函数:__init__,__len__和__getitem__pytorch中的dataset类是在pytorch的torch下的utils之下的data文件夹里有一个dataset.py。

weixin_47748259的博客 1万+

libcurl库使用详情、libcurl库的制作

​ libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证。libcurl的官网 、库下载。这种库使用的时候就像使用wiringPi库一样,编写完代码需要链接这个库,所以要先下载这个库。libcurl的使用(其实和socket编程时一样,都需要一定的步骤):

qq_45698138的博客 5337

告别水印!Vue3项目集成Stimulsoft.Reports.js完整配置与激活指南

本文详细介绍了如何在Vue3项目中集成Stimulsoft.Reports.js,提供从授权策略到性能优化的完整解决方案。通过模块化架构设计和现代化引入方式,帮助开发者高效实现专业级报表功能,同时避免版权风险和水印问题,特别适合中小型项目需求。

weixin_33701294的博客 431

【PyTorch】加载数据集Dataset与DataLoader

关于PyTorch构建数据集的Dataset与DataLoader的一些记录笔记

weixin_45069367的博客 3424

OB4.X集群状态running但是oceanbase-ce is not running

自 V3.2.0 起,若 obd 设置了加密密钥,执行 display 命令输出的集群信息中,密码相关内容为加密状态。若需输出明文密码,可在命令中添加 --epk/–encryption-passkey 指定密钥用于验证。obd 运维的数据库,启停需要使用obd进行操作,停机时候没有使用obd会导致集群状态running但是oceanbase-ce is not running。查看集群中的租户时无租户反馈,警告oceanbase-ce is not running,但是查询集群状态明明是running。

qq961573863的博客 1213

PyTorch使用Dataset和DataLoader加载数据集

在PyTorch里优化器都是小批量小批量地优化训练的,即每次都会从原数据集中取出一小批量进行训练,完成一次权重更新后,再从原数据集中取下一个小批量数据,然后再训练再更新。。。 比如最常用的小批量随机梯度下降(Mini-Batch Gradient Descent,MBGD)。 毕竟原数据集往往很大,不可能一次性的全部载入内存,只能一小批一小批地载入内存。训练完了就扔了,再加载下一小批。 如何实现批量地加载数据集? 在PyTorch的torch.utils.data包中定义了两个类Dataset和DataL

Jnchin的博客 1万+

LabVIEW+数据库应用系列保姆级教程,第一篇数据库连接

目录LabVIEW连接数据库的方法连接MySQL连接Oracle,SQL Server,Access等 LabVIEW连接数据库的方法 1、创建udl(Universal Data Link)是通用数据连接文件。界面操作,简单快捷。 2、编写连接字符串。需要熟悉连接字符串的结构,容易出错。 3、其他… 本教程教你使用第1种方法,也是最简单、最常用的方法。 连接MySQL 1、在MySQL Installer内安装MySQL Connector/ODBC,建议安装32位(X86),如下图: 2、创建ODBC

wwplh5520370的博客 1万+

Flowable高级篇 -6.8.0 最全表结构说明-主要表结构字段注释

flowable 28张表 详细

billzhen的博客 1万+

Pytorch加载自己的数据集(使用DataLoader加载Dataset)

https://www.pytorchtutorial.com/pytorch-custom-dataset-examples/ https://blog.csdn.net/l8947943/article/details/103733473 1. 我们需要加载自己的数据集,使用Dataset和DataLoader Dataset:是被封装进DataLoader里,实现该方法封装自己的数据和标签。 DataLoader:被封装入DataLoader迭代器里,实现该方法达到数据的划分。 2.Datas

北国觅梦 9048

钉钉多维表格开发

从0到1完成钉钉多维表格开发SDK对接与实践案例。

沉修所长,勇逐新机;安而不怠,静而思变 3610

基于PyTorch学AI——Dataset与DataLoader

本文总结了Dataset和DataLoader两个核心类,是模型训练绕不开的基础类,希望阅读本文能带来收获。

道至简 2856

103:vue+cesium 设置球体水部分颜色为黄色

本示例在 Vue + cesium 项目中设置球体水部分颜色为黄色。这里的操作是将球体内部设置为空的,在地球内部添加一个黄色的圆球,这样水的部分就被突出出来了。直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果.

大剑师兰特的GIS世界 623

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: PyTorch 入门与实践(二)处理多维特征的输入
下一篇: PyTorch 入门与实践(四)多分类问题(Softmax)
Skr.B
博客等级 码龄8年 1103粉丝 81原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Skr.B

WUHOOO~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值