DataLoade类与list ,iterator ,yield的用法

news2025/1/13 9:30:56

1 问题

探索DataLoader的属性,方法

Vscode中图标含意

list 与 iterator 的区别,尤其yield的用法

2 方法

知乎搜索DataLoader的属性,方法

pytorch基础的dataloader类是 from torch.utils.data.dataloader import Dataloader 其主要的参数如下:

datasets、batch size、shuffle、sampler、batch_sampler、num_workers、collate_fn、pin_memory、drop_last ...

(1)datasets

这可以算是dataloader最重要的参数,从本质上讲这是一个数据集映射器(DatasetMapper,这里借用了d2的概念),所谓数据集映射器,就是将数据集dataset以及其标注文件annotations,从原始的数据文件中进行提取,并转换为,网络所需要的输入数据的格式。这一步重要且繁琐,但是定义数据集dataset整体的结构还是固定的。

定义数据集dataset类的基本结构如下:

class mydataset(Dataset):# 这里可以继承torch的数据集类进行覆写,也可以不继承,直接自己去定义

   def __init__():

   #定义映射数据集所需要的一些基本的属性(例如数据样本的文件目录,数据的格式等等),

   #如果是映射coco格式的数据集,则会使用pycocotools的COCO类进行数据提取的预定义

   ...

   def __len__():#这里一般返回的是数据集的长度(就是数据集样本的数量)

   ...

   def __getitem__():

   #这里就是数据集映射功能的核心函数,dataloader就是通过它来对数据集的样本进行提取映射为所需要的格式

   #当然,在进行数据映射的时候,也可以在这个方法中添加一些数据增强的功能,这都是无限制的。

   ...

# 在功能上 __getitem__ == __iter__ + __next__ 所以定义的dataset数据集,通常其实例对象本身也是一个迭代器

#这里注意区分 迭代器、可迭代对象、生成器3者之间的联系与区别:

#可迭代对象:任何一个实现了__iter__方法的对象,都是可迭代对象

#迭代器:任何一个同时实现了__iter__ 与 __next__ 方法的对象,都是一个迭代器

#生成器:任何一个同时实现了__iter__ 与 __next__ 方法的对象,并且在迭代过程中本身能够自动改变迭代值,则这种对象都是一个生成器

(生成器是一种特殊的迭代器)生成器的例子建议参看torch.utils.data.samplers 中的BatchSampler

-- 任何具有yield关键字的函数,都可以视为一种生成器,调用函数返回的是一个生成器对象,对该对象采用next()方法,才会调用该生成器函数

关于dataset类定义的例子很多,建议大家可以看看yolox中关于dataset的定义进行参考,在很多情况下,我们需要针对特定任务进行数据预处理,而这项工作大部分都是在dataset中定义完成的,有时因为涉及到的数据预处理任务比较多,可能会将dataset的定义分为两个部分,使得整个程序看上去不会那么的臃肿,一个是Mapper ,一个是augmentation,这两个部分对数据处理进行了明确的分工,一个用于格式转换映射,一个用于数据预处理增强。

(2)batch_size

这个很好理解了,就是用于提取数据的,批量大小。

(3)shuffle

这个也很好理解,提取数据的过程设置是随机还是按顺序提取,若是随机则为T,否则为F。实际上shuffle参数的设置是调用了torch中固有sampler,如果设置为T,则dataloader会自动调用RandomSampler。

(4)sampler / BatchSampler ---- 采样器 / 批量采样器

采样器是数据处理中的一个比较特别的部分,在目前大部分的情况下,我们都是使用的是torch内部固定的采样器来实现对数据的采样,但是也有少数的情况下,由于一些数据本身的一些原因,我们需要对对采样器进行继承覆写--就是自定义,如果采样器是自定义的话,则shuffle必须为F --- 都自定义了,就不要与框架实现的采样器冲突了。关于采样器自定义的格式如下(以BatchSampler为例):

class sampler(torch.utils.data.sampler):----- 一般这里要继承 torch 采样器类 并对相关的方法进行自定义重写

   def __init__(self, data_source):

       super().__init__():

       ...

   def __iter__(self)-> iterator[int] 或者是 Iterator[list[int]] :用于返回所采样数据 在数据集中的索引idx

       ...

      # 这里的__iter__方法,一般实现的是一个生成器,用yield关键字进行返回值,

      #实现在迭代过程中动态改变采样数据的索引idx---就是改变返回数据的索引idx

   def __len__(self)-> int:

       实现的是采样器 在整个数据集的采样次数 这里的采样次数都是跟batch_size有关 总采样次数len == 数据集总样本数 / 采样的batch_size

       if self.drop_last:

           return len(self.sampler) // self.batch_size  # type: ignore[arg-type]

       else:

           return (len(self.sampler) + self.batch_size - 1) // self.batch_size  # type: ignore[arg-type]

       ...

   def xxx():----- 一般这里是对上述的3个基本的方法 进行补充说明  写一些补充上述3个基本的方法的一些功能或者扩展

       ...

       # 比如可以添加一些多尺度训练的功能,或者是其他对与采集样本的一些功能,这个就比较随机了,自己定义即可。

实现采样器,必须得有__init__, __iter__, __len__方法。

由于BatchSampler中对数据采样的方式以及batch的大小,drop_last的规定已经作了一些说明和定义,因此如果自定义了一个BatchSampler,就不需要batch size、shuffle、sampler、drop_last等参数了 ---- 原则就是自定义的功能不要与dataloader中调用的框架的固有功能冲突。

(5)num_workers ---- 子进程数量,这个在分布式的训练中要特别注意,进程的数量以及GPU数量(word—size)的把控和分配。一般而言。子进程数量越多,dataloader的执行的效率就越高,但是也越耗cpu。

(6)pin_memory -- 锁页内存,主机的内存分为 锁页 和 不锁页 两种内存,因为cuda只接受 锁页内存 的传入,因此在创建DataLoader时,设置pin_memory=True,则意味着生成的Tensor数据最开始就是属于内存中的锁页内存,这样将内存的Tensor转义到GPU的显存就会更快一些----但是缺点是对于服务器内存的要求比较高。

(7)drop_last --- 这个主要用于设置在批量提取数据时,是否要将“不能整除的”最后一部分达不到小批量数目的数据扔掉--不参加训练,默认为F,你也可以设置为T。

(8) collate_fn ---- 封装器。

dataloader通过其定义的sampler(返回采样的批量的数据样本索引idx)对定义的dataset(根据这些索引idx)进行采样并预处理数据。这样的话,dataloader批量迭代数据的结果可能就会包含一个批量batch-size中,所有样本的结果(例如batchsize设置为4,则dataloader就会返回数据集dataset中采样的4个样本的结果),而collate_fn 的作用,就是要对这些一个batch的迭代结果进行封装,使其整合为神经网络所需要的输入形式-----举个例子:就是从batchsize个(c,h,w)转化为大家最熟悉的(b,c,h,w)----- 因此很明显,collate_fn的作用就是为了对dataloader处理的批量输出进行封装整合,转化为网络所需要的输入形式。这项功能既可以自定义,也可以使用默认的框架功能。不过对于不同的框架,不同的环境和任务,很多情况下这个都是自定义的,定义的方法就是一个function,也不需要专门搞一个类的形式来定义它(除非是大型的工程,需要用到很多种封装形式),其基本的定义的格式如下:

def collate_fn(batch):

# 输入为:dataloader在迭代过程中,产生的 批量处理后的 数据样本 --- 例如:batchsize个 list / tuple / dict

# 每个list/tuple/dict 都是dataloader处理后的一个batch中的单个样本的结果

  ...

# 返回为:经处理整合之后的批量的数据样本,并作为dataloader最终的迭代输出结果 -- 例如:一个 list / tuple / dict

当然,如果不用这个封装功能,直接忽略该参数也是可以的,最后dataloader会使用其默认的collate_fn,并返回一个batchsize的结果 ---- 返回的结果来源于,dataset中的__getitem__返回的结果。

百度Vscode中图标含意

ddcb7dc9e3db1296e675a040b579749a.pngf07a5889772500bac87ababf691008d2.png橙色树状结构:类 紫色立方体:方法

9b7c4939622be278c92cea1baf35e27d.pngf1328186f989855a5cbccdc780bca959.png长方体:变量 局部变量 成员变量

2ea342b2c79f239ade3bda02f463bdc4.pnga483280df9e71f53c2cc924170aedfe7.png0a3960bfb7e6420c1925d66e1308ea87.png命名空间。 属性 。事件

百度list 与 iterator 的区别,

1、返回的类型不同,list()返回List,iterate()返回Iterator

2、获取方式不同,list会一次性将数据库中的信息全部查询出,iterate会先把所有数据的id查询出来,然后真正要遍历某个对象的时候先到缓存中查找,如果找不到,以id为条件再发送一条sql到数据库,这样如果缓存中没有数据,则查询数据库的次数为n+1

3、iterate会查询2级缓存,list只会查询一级缓存

4、list中返回的List中每个对象都是原本的对象,iterate中返回的对象是代理对象。(debug可以发现)

百度yield的用法

1 什么是yield函数?

Python中yield函数是一个生成器(generator),可用于迭代;在函数中yield类似于return,不同的是,yield返回一个return的值并且记住这个返回值的位置,下次迭代就从记住的这个位置开始,并且下一次迭代时,从上一次迭代遇到的yield后面的代码开始执行。

2 yield函数的特点及用法。

yield函数的优点在于它可迭代,但又不直接生成返回值,如果采用return来返回值,就会直接生成返回值;如果返回的值,或者迭代的数据太大,都会使得内存消耗过大;yield函数就会很好的减少内存的消耗,但是它只可读取一次。带有yield的函数不仅仅可以用于for循环,还可以用于函数的参数,例如:

#用于for循环
def yields(n):
    print('yield用法:')
    while n<10:
        n+=1
        yield n
    return 'pass'
c=yields(0)
print(next(c))
print(next(c))
print(next(c))
输出:
1
2
3
#用于函数的参数
def a():
    print('aaa')
    p = yield '123'
    print('bbb')
    k = yield '234'
r = a()
print(next(r))
输出:
aaa
123

思考一下如果将用于函数参数的yield再增加一个输出next()会发生什么情况呢?

def a():
    print('aaa')
    p = yield '123'
    print('bbb')
    k = yield '234'
r = a()
print(next(r))
print(next(r))
输出:
aaa
123
bbb
234

由以上代码以及运行结果不难发现,每一个next返回值,都会在执行到yield函数后暂停生成,下一次next返回值则会继续从上一个暂停的位置执行,这也是yield函数的特点与用法。

3 send()与next()用法的异同。

next()函数可以不断打印yield生成器的值;

send()函数特别之处在于它可以携带参数,并修改上一个表达式的值,同时用法也与next()有很多相同之处;

3.1相同点

相同点在于,当send()所携带的参数为None(即未携带任何参数)时,用法与next()一模一样,都仅仅是来打印yield生成器的值。

3.2 不同点

不同点在于当send()所携带的参数时,就会将所带参数赋值给上一个表达式;实例:

def a():
    print('send():')
    i = yield 123
    print(i)
    if i==234:
        print("send传入的参数为234")
    k = yield 345
    print(k)
r=a()
next(r)
r.send(234)
输出:
send():
234
Send传入的参数为234

分析:首先执行next(r),当第一次遇见yield跳出输出send():;然后执行r.send(234),send()直接将234参数传给i中并从yield位置继续执行,输出i,值为234,然后输出if条件语句,当执行到下一个yield时,也就是k=yield 345时,跳出。

注意:yield的第一次执行一定为next(r)或者r.send(None)。

3 结语

了解了Dataloader 其主要的参数,有助于我更好地理解和使用这个类,从而解决图像基本信息问题。

Vscode中图标含意有助与我在日后的写代码的过程中快速的选择自己想要的函数。

list 与 iterator 的区别,yield的用法。有助于在今后代码的迭代选择时应需求选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249669.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++入门——“C++11-lambda”

引入 C11支持lambda表达式&#xff0c;lambda是一个匿名函数对象&#xff0c;它允许在函数体中直接定义。 一、初识lambda lambda的结构是&#xff1a;[ ] () -> 返回值类型 { }。从左到右依次是&#xff1a;捕捉列表 函数参数 -> 返回值类型 函数体。 以下是一段用lam…

【Linux网络编程】第二弹---Socket编程入门指南:从IP、端口号到传输层协议及编程接口全解析

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【Linux网络编程】 目录 1、Socket 编程预备 1.1、理解源 IP 和目的 IP 1.2、认识端口号 1.2.1、端口号范围划分 1.2.2、理解 &q…

《用Python实现3D动态旋转爱心模型》

简介 如果二维的爱心图案已经无法满足你的创意&#xff0c;那今天的内容一定适合你&#xff01;通过Python和matplotlib库&#xff0c;我们可以实现一个动态旋转的3D爱心模型&#xff0c;充满立体感和动感。# 实现代码&#xff08;完整代码底部名片私信&#xff09; 以下是完…

shell-函数调用进阶即重定向

shell-函数调用进阶 声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷…

【高等数学学习记录】微分中值定理

一、知识点 &#xff08;一&#xff09;罗尔定理 费马引理 设函数 f ( x ) f(x) f(x) 在点 x 0 x_0 x0​ 的某邻域 U ( x 0 ) U(x_0) U(x0​) 内有定义&#xff0c;并且在 x 0 x_0 x0​ 处可导&#xff0c;如果对任意的 x ∈ U ( x 0 ) x\in U(x_0) x∈U(x0​) &#xff0…

【vue-router】vue-router如何实现动态路由

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Web前端技术浅谈CooKieAG网址漏洞与XSS攻防策略

随着互联网技术的飞速发展,Web前端开发已经成为构建网站和应用程序的重要环节。然而,Web前端开发中存在许多安全问题,这些问题不仅会影响用户体验,还可能给企业和个人带来严重的经济损失。但是web前端安全方面技术包含的东西较多&#xff0c;我们这里着重聊一聊关于XSS 的危害与…

关于VNC连接时自动断联的问题

在服务器端打开VNC Server的选项设置对话框&#xff0c;点左边的“Expert”&#xff08;专家&#xff09;&#xff0c;然后找到“IdleTimeout”&#xff0c;将数值设置为0&#xff0c;点OK关闭对话框。搞定。 注意,服务端有两个vnc服务,这俩都要设置ide timeout为0才行 附件是v…

51c自动驾驶~合集35

我自己的原文哦~ https://blog.51cto.com/whaosoft/12206500 #纯视觉方案的智驾在大雾天还能用吗&#xff1f; 碰上大雾天气&#xff0c;纯视觉方案是如何识别车辆和障碍物的呢&#xff1f; 如果真的是纯纯的&#xff0c;特头铁的那种纯视觉方案的话。 可以简单粗暴的理解为…

计算分数的浮点数值

计算分数的浮点数值 C语言代码C 代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 两个整数a和b分别作为分子和分母&#xff0c;既分数 a/b &#xff0c;求它的浮点数值&#xff08;双精度浮点数&#xff0c;保留小数点…

戴尔电脑安装centos7系统遇到的问题

1&#xff0c;找不到启动盘&#xff08;Operation System Loader signature found in SecureBoot exclusion database(‘dbx’).All bootable devices failed secure Boot Verification&#xff09; 关闭 Secure Boot&#xff08;推荐&#xff09;&#xff1a; 进入 BIOS/UEFI…

简单获取json预览

data: JSON 数据。 collapsedNodeLength: 对象或数组的长度超过此阈值时会折叠 deep: json路径深度超过此值时会折叠 showLineNumber: 显示左侧行号 showIcon: 显示图标。 virtual: 使用虚拟滚动 height: 使用虚拟滚动时列表的高度 itemHeight: 使用虚拟滚动时节点的高…

ChatGPT/AI辅助网络安全运营之-数据解压缩

在网络安全的世界中&#xff0c;经常会遇到各种压缩的数据&#xff0c;比如zip压缩&#xff0c;比如bzip2压缩&#xff0c;gzip压缩&#xff0c;xz压缩&#xff0c;7z压缩等。网络安全运营中需要对这些不同的压缩数据进行解压缩&#xff0c;解读其本意&#xff0c;本文将探索一…

Cookie概念和API

Cookie概念 Cookie在HTTP中它表示服务器送给客户端浏览器的小甜点。其实Cookie就是一个键和一个值构成的&#xff0c;随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来&#xff0c;当下一次再访问服务器时把Cookie再发送给服务器。 Cookie是由服务器…

qt音频实战

一、Qt音频基础知识 1、QT multimedia 2、QMediaPlayer类&#xff1a;媒体播放器&#xff0c;主要用于播放歌曲、网络收音机等功能。 3、QMediaPlaylist类&#xff1a;专用于播放媒体内容的列表。 二、界面设计 三、代码 #include "mainwindow.h" #include "…

GDPU Android移动应用 数据存储

又是学到了数据持久化。 登录界面 题外话&#xff1a;有无动画大佬带带呀&#xff0c;前端移动端可免( •̀ .̫ •́ )&#xff0c;合作可私信哦。 1.用户登陆和“记住我”功能 该内容拥有两个Activity活动视图&#xff1a; &#xff08;1&#xff09;LoginActivity&#x…

Java算法OJ(11)双指针练习

目录 1.前言 2.正文 2.1存在重复数字 2.1.1题目 2.1.2解法一代码 解析&#xff1a; 2.1.3解法二代码 解析&#xff1a; 2.2存在重复数字plus 2.2.1题目 2.2.2代码 2.2.3解析 3.小结 1.前言 哈喽大家好吖&#xff0c;今天来给大家分享双指针算法的相关练习&…

天锐绿盾加密软件与Ping32联合打造企业级安全保护系统,确保敏感数据防泄密与加密管理

随着信息技术的飞速发展&#xff0c;企业在日常经营过程中产生和处理的大量敏感数据&#xff0c;面临着越来越复杂的安全威胁。尤其是在金融、医疗、法律等领域&#xff0c;数据泄漏不仅会造成企业巨大的经济损失&#xff0c;还可能破坏企业的信誉和客户信任。因此&#xff0c;…

Git上传本地项目到远程仓库(gitee/github)

目录 序言一、创建git本地版本库二、连接远程仓库&#xff08;以gitee为例&#xff09;三、将项目提交到git&#xff08;本地&#xff09;版本库1.由工作区添加到暂存区2.由暂存区添加到版本库 四、将代码由本地仓库上传到 gitee远程仓库1.获取远程库与本地同步2.把当前分支 ma…

C7.【C++ Cont】范围for的使用和auto关键字

目录 1.知识回顾 2.范围for 格式 使用 运行结果 运行过程 范围for的本意 作用 注意 3.底层分析范围for的执行过程 反汇编代码 分析 4.auto关键字 格式 基本用法 在范围for中使用auto 1.知识回顾 for循环的使用参见25.【C语言】循环结构之for文章 2.范围for C…