当前位置: 首页 > news >正文

再探pytorch的Dataset和DataLoader

本文从分类检测分割三大任务的角度来剖析pytorch得datasetdataloader源码,可以让初学者深刻理解每个参数的由来和使用,并轻松自定义dataset。

思考:在探究Dataset和DataLoader之前,需要明白一个事情,就是当我们不管做是分类、检测还是分割任务时,我们的数据集一定由很多张图片组成的,形状大小各异;那麽我们在使用pytorch时,图片是怎么以一个batch的形式进行打包的呢,形状不同怎么处理,数据格式有什么要求,Dataset类中的初始化参数transform如何自定义,并是怎么调用的,在哪里调用?训练时如何取出DataLoader中的数据的?带着种种疑问,开始Dataset和DataLoader的探索之旅吧!

Dataset探究

Dataset的定义

  • 问题1:Dataset到底是什么,如何去调用?

  • 我们通常见到的Dataset的定义如下图,VOCSegmentation()在这里其实是一个

voc_train = VOCSegmentation('F:\pytorch_yolov3\yolo3-pytorch',year='2007',image_set='train',transform=transform,target_transform=target_transform)

自定义得Dataset类中,必有三个函数:__init__(),__getitem__(),__len__()函数,

  1. __init__(self,...):是几乎类中都会有的一个初始化函数,会在类进行实例化时初始化一些变量,供类中其他函数使用

  1. __getitem__(self, index):是python得magic method,一般如果想通过使用索引访问元素时,就可以在类中定义这个方法。

  1. __len__():返回数据集的长度

凡是在类中定义了这个__getitem__ 方法,那么它的实例对象(假定为p),可以像这样p[key] 取值,当实例对象做p[key] 运算时,会调用类中的方法__getitem__。

返回值为处理过后的img和seg

class VOCSegmentation(Dataset):def __init__('F:\pytorch_yolov3\yolo3-pytorch',year='2007',image_set='train',transform=transform,target_transform=target_transform):passdef __getitem__(self, index):passdef __len__(self):pass

分类任务的Dataset

  • 自定义分类Dataset

class MyDataset(Dataset): # 继承Dataset类def __init__(self, txt_path, transform=None, target_transform=None): # 定义txt_path参数fh = open(txt_path, 'r') # 读取txt文件imgs = []  # 定义imgs的列表for line in fh:line = line.rstrip() # 默认删除的是空白符('\n', '\r', '\t', ' ')words = line.split() # 默认以空格、换行(\n)、制表符(\t)进行分割,大多是"\"imgs.append((words[0], int(words[1]))) # 存放进imgs列表中self.imgs = imgs        # 最主要就是要生成这个list, 然后DataLoader中给index,通过getitem读取图片数据self.transform = transformself.target_transform = target_transformdef __getitem__(self, index):fn, label = self.imgs[index] # fn代表图片的路径,label代表标签img = Image.open(fn).convert('RGB')     # 像素值 0~255,在transfrom.totensor会除以255,使像素值变成 0~1   参考:https://blog.csdn.net/icamera0/article/details/50843172if self.transform is not None:img = self.transform(img)   # 在这里做transform,转为tensor等等return img, labeldef __len__(self):return len(self.imgs)   # 返回图片的数量
  • 官方的MNIST类

def __init__(self, root, train=True, transform=None, download=False)

参数解析:

  • root:为数据集的路径,如果没找到本地路径,配合download使用,可以将download设置为True,会从网上为你下载数据

  • train:是一个boolean类型参数,用来定义数据使用的时train数据集还是test数据集,如果train为True,就会将train数据集路径加载进来,供后面读取数据使用。

  • download:boolean类型参数,如果为True,就会直接跳过本地数据集,去网上下载,下载后存放在当前工程目录下。

  • transform:可以是一个实例化对象,也可以使用torchvison.transforms.Compose来包裹一个含有多个实例化转换类对象的列表

注意:非常重要的是掌握transform参数需要的参数类型是什么,后面方便自己自定义transform,在自定义tranform前,先来看看pytorch官方自己定义的一些变换方法吧(变换都在torchvison.transforms.transforms.py中)。
  • transform解析

class CenterCrop(object):"""Crops the given PIL Image at the center.Args:size (sequence or int): Desired output size of the crop. If size is anint instead of sequence like (h, w), a square crop (size, size) ismade."""def __init__(self, size):if isinstance(size, numbers.Number):self.size = (int(size), int(size))else:self.size = sizedef __call__(self, img):"""Args:img (PIL Image): Image to be cropped.Returns:PIL Image: Cropped image."""return F.center_crop(img, self.size)def __repr__(self):return self.__class__.__name__ + '(size={0})'.format(self.size)

以CenterCrop为例,可以看出是类的实现。类中包含三个方法

  • __init__(self, size):用于初始化必要的变量

  • __call__(self, img):为python的magic方法,在类中实现这一方法可以使该类的实例(对象)像函数一样被调用。默认情况下该方法在类中是没有被实现的。使用callable()方法可以判断某对象是否可以被调用。

  • __repr__(self):支持打印功能,可以使用print(实例化对象),返回变换类名包括初始化的一些参数信息。

class People(object):def __init__(self,name):self.name=namedef __call__(self):print("hello "+self.name)a = People('无忌!')
a.__call__()       # 调用方法一
a()                # 调用方法二
#两种调用方法等价
#__call__()方法的作用其实是把一个类的实例化对象变成了可调用对象,
#也就是说把一个类的实例化对象变成了可调用对象,只要类里实现了__call__()方法就行。
#如当类里没有实现__call__()时,此时的对象p 只是个类的实例,不是一个可调用的对象,
#当调用它时会报错:‘Person’ object is not callable.
注意:__call__(self, img)方法中的参数是img,即图像,格式为PIL Image,所以一般是对图像做完各种图像变换之后再进行ToTensor()和Normalize()操作,顺序很重要,否则会报数据类型错误。__call__(self,img)的具体实现F.center_crop(img, self.size)在torchvision.transforms.functional.py中。

  • 问题:transforms中的compose为何可以以列表的形式接受各种变换

代码解析
class Compose(object):"""Composes several transforms together.Args:transforms (list of ``Transform`` objects): list of transforms to compose.Example:>>> transforms.Compose([>>>     transforms.CenterCrop(10),>>>     transforms.ToTensor(),>>> ])"""def __init__(self, transforms):#先批量初始化变换方法self.transforms = transformsdef __call__(self, img):#__call__方法是python的魔法方法,会#遍历list,得到第一个transforms.CenterCrop(10),每一个变换都是一个类,CenterCrop(10)#对中心裁剪类进行了实例化,真正调用__call__()方法是在,__getitem__(self, index)方法中#self.transform(img),返回变换后的img(循环顺序调用,像是一个管道,img从一边输入,从另一边#另一边输出,输出的图像已经变成了我们想要的模样)for t in self.transforms:img = t(img)return img

DataLoader

DataLoader的定义

问题:DataLoader到底是什么?
DataLoader也是以类的方式实现的,DataLoader是一个可迭代对象,其类中实现了__iter__方法,因此在实例化DataLoader后,可以通过for循环的方式来迭代获取打包后的batch数据,在使用for循环遍历DataLoader时,会调用DataLoader里的__iter__方法,返回一个_SingleProcessDataLoaderIter(self)迭代器,后面每次迭代时会调用__next__方法获得下一批数据.

def __init__(self, dataset, batch_size=1, shuffle=False, 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):
参数解析:
dataset:自定义的数据集
batch_size:每次喂入网络几张图
shuffle:数据是否乱序
sampler:一个采样器
batch_sampler:以sampler为参数,在遍历dataloader时,会对采样器进行迭代产生一个batch的index
num_workers:使用几个进程来加载数据,默认是0,由主进程来加载数据
collate_fn:主要用来打包通过一个batch的index取到的数据,将img,target分开打包成tensor

collate_fn的参数可以自定义实现,因为pytorch官方提供的collate_fn函数只是将数据简单stack在一起,如果需要实现一些其他功能,可以自行定义,然后作为参数传给collate_fn.

DataLoader案例

Dataset和DataLoader的关系

参考文献:

https://blog.51cto.com/u_15274944/2921682

https://zhuanlan.zhihu.com/p/35698470

https://zhuanlan.zhihu.com/p/27661382

https://zhuanlan.zhihu.com/p/359998425

https://blog.csdn.net/qq_28057379/article/details/115427052

https://zhuanlan.zhihu.com/p/30385675

https://cloud.tencent.com/developer/article/1728103

https://ai.deepshare.net/p/t_pc/course_pc_detail/video/v_5e1694ec1470e_SJ7JwMgA?product_id=p_5d552aea89dd9_CWCmRNUu&type=5

相关文章:

再探pytorch的Dataset和DataLoader

本文从分类、检测、分割三大任务的角度来剖析pytorch得dataset和dataloader源码,可以让初学者深刻理解每个参数的由来和使用,并轻松自定义dataset。思考:在探究Dataset和DataLoader之前,需要明白一个事情,就是当我们不…...

【2023.3.18 美团校招】

文章目录1. 小美剪彩带2. 最多修改两个字符,生成字典序最小的回文串1. 小美剪彩带 题意:找出区间内不超过k种数字子数组的最大长度 使用双指针的方式,用哈希表来统计每个数出现次数。在双指针移动的过程中,动态的维护区间内不同数…...

程序员必须知道的HTML常用代码有哪些?

HTML 即超文本标记语言,是目前应用最为广泛的语言之一,是组成一个网页的主要语言。在现今这个 HTML5 华丽丽地占领了整个互联网的时候,如果想要通过网页抓住浏览者的眼球光靠因循守旧是不行的,程序猿们需要掌握一些必须知道的 HTM…...

多目标家庭行为检测--人脸识别模块构建

文章目录前言原理项目结构编码配置主控函数人脸采集模块特征提取识别测试前言 2023-3-18 天小雨,午觉舒适程度5颗星。任务完成指数2颗星。续接上文:《MidiaPipe stgcn(时空图卷积网络)实现人体姿态判断(单目标&#x…...

RocketMQ重复消费问题的原因

文章目录 概览消息发送异常时重复发送消费消息抛出异常消费者提交offset失败服务端持久化offset失败主从同步offset失败重平衡清理长时间消费的消息总结概览 消息发送异常时重复发送 首先,我们来瞅瞅RocketMQ发送消息和消费消息的基本原理。 如图,简单说一下上图中的概念: …...

proxy详细介绍与使用

proxy详细介绍与使用 proxy 对象用于创建一个对象的代理,是在目标对象之前架设一个拦截,外界对该对象的访问,都必须先通过这个拦截。通过这种机制,就可以对外界的访问进行过滤和改写。 ES6 原生提供 Proxy 构造函数,…...

基于YOLOv5的舰船检测与识别系统(Python+清新界面+数据集)

摘要:基于YOLOv5的舰船检测与识别系统用于识别包括渔船、游轮等多种海上船只类型,检测船舰目标并进行识别计数,以提供海洋船只的自动化监测和管理。本文详细介绍船舰类型识别系统,在介绍算法原理的同时,给出Python的实…...

【C#】List数据去重

系列文章 【C#】单号生成器(定义编号规则、流水号、产生业务单号) 本文链接:https://blog.csdn.net/youcheng_ge/article/details/129129787 【C#】日期范围生成(构建本周开始、结束日期) 本文链接:https…...

避免踩坑,教给你VSCode中最常用到的6项功能

这里为程序员介绍VSCode中包含的许多令人兴奋的Tips。 1. 插件市场中免费下载使用CodeGeeX插件 AI辅助编程工具CodeGeeX,是完全免费,开源开放给所有开发者使用。程序员普遍反应使用这个插件后,代码编写效率提升2倍以上。 CodeGeeX插件拥有…...

ThingsBoard开源物联网平台智慧农业实例快速部署教程(Ubuntu、CentOS适用)

ThingsBoard部署教程文档 文章目录ThingsBoard部署教程文档1. JDK环境安装2. 安装thingsBoard2.1 ThingsBoard软件包安装2.2 PostgreSQL安装2.3 PostgreSQL初始化配置3. 修改ThingsBord的配置4. 运行安装脚本测试5. 访问测试6. 导入一个仪表盘库6.1 导出仪表盘并导入自己的项目…...

【Java Spring基本问题】记录面试题宝典中自己不熟悉的Spring问题

文章目录Spring Bean定义装配Spring Bean生命周期Spring Bean容器Spring 循环依赖Spring 事务Autowired和ResourceSpring Bean定义装配 参考文章 1. 定义Spring Bean的三种方式 XML文件定义Spring Bean JavaConfig定义Spring Bean Component注解定义SpringBean 2. 装配Spri…...

I2C协议简介 Verilog实现

I2C协议 IIC 协议是三种最常用的串行通信协议(I2C,SPI,UART)之一,接口包含 SDA(串行数据线)和 SCL(串行时钟线),均为双向端口。I2C 仅使用两根信号线&#xf…...

服务器被DDoS攻击,怎么破?

文章目录前言网站受到DDoS的症状判断是否被攻击查看网络带宽占用查看网络连接TCP连接攻击SYN洪水攻击防御措施TCP/IP内核参数优化iptables 防火墙预防防止同步包洪水(Sync Flood)Ping洪水攻击(Ping of Death)控制单个IP的最大并发…...

实现完全二叉树

文章目录1、树概念及结构2、孩子兄弟表示法3、二叉树3.1、二叉树的概念3.2、特殊的二叉树3.3、二叉树的存储4、堆的性质5、数组结构实现完全二叉树1、结构体的定义2、初始化堆3、销毁堆4、交换函数5、向上调整函数6、插入数据7、向下调整函数8、删除堆顶数据函数9、判断是否空堆…...

【独家】华为OD机试 - 矩阵最值(C 语言解题)

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本期题目:矩阵最值 题目 给定一个仅包…...

C++模板(进阶)

文章目录非类型模板参数类模板的特化类模板的概念函数模板特化类模板的特化全特化偏特化参数的进一步限制模板的分离编译模板的优缺点非类型模板参数 模板参数分类型形参与非类型形参. 类型形参: 出现在模板参数列表中,跟在class,typename之类的参数类型名称. 非类型形参: 就是…...

【数据分析之道(二)】列表

文章目录专栏导读1、列表介绍2、访问列表中的值3、列表增加和修改4、删除元素5、列表函数6、列表方法专栏导读 ✍ 作者简介:i阿极,CSDN Python领域新星创作者,专注于分享python领域知识。 ✍ 本文录入于《数据分析之道》,本专栏针…...

架构师必须要掌握的大小端问题

一、什么是大端和小端 所谓的大端模式,就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。 所谓的小端模式,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。 简单来说:大端——高尾端,小端——低尾端 举个例子,比如数字 0x12 34 56 78…...

2023年ACM竞赛班 2023.3.20题解

目录 瞎编乱造第一题 瞎编乱造第二题 瞎编乱造第三题 瞎编乱造第四题 瞎编乱造第五题 不是很想编了但还是得编的第六题 不是很想编了但还是得编的第七题 还差三道题就编完了的第八题 还差两道题就编完了的第九题 太好啦终于编完了 为啥一周六天早八阿 瞎编乱造第一题…...

什么是语法糖?Java中有哪些语法糖?

本文从 Java 编译原理角度,深入字节码及 class 文件,抽丝剥茧,了解 Java 中的语法糖原理及用法,帮助大家在学会如何使用 Java 语法糖的同时,了解这些语法糖背后的原理1 语法糖语法糖(Syntactic Sugar&#…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​,覆盖应用全生命周期测试需求,主要提供五大核心能力: ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

爬虫基础学习day2

# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...

论文阅读:Matting by Generation

今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...