时间:2021-05-22
在使用pytorch训练模型,经常需要加载大量图片数据,因此pytorch提供了好用的数据加载工具Dataloader。
为了实现小批量循环读取大型数据集,在Dataloader类具体实现中,使用了迭代器和生成器。
这一应用场景正是python中迭代器模式的意义所在,因此本文对Dataloader中代码进行解读,可以更好的理解python中迭代器和生成器的概念。
本文的内容主要有:
python迭代基础
python中围绕着迭代有以下概念:
这三个概念互相关联,并不是孤立的。在可迭代对象的基础上发展了迭代器,在迭代器的基础上又发展了生成器。
学习这些概念的名词解释没有多大意义。编程中很多的抽象概念都是为了更好的实现某些功能,才去人为创造的协议和模式。
因此,要理解它们,需要探究概念背后的逻辑,为什么这样设计?要解决的真正问题是什么?在哪些场景下应用是最好的?
迭代模式首先要解决的基础问题是,需要按一定顺序获取集合内部数据,比如循环某个list。
当数据很小时,不会有问题。但当读取大量数据时,一次性读取会超出内存限制,因此想出以下方法:
循环读数据可分为下面三种应用场景,对应着容器(可迭代对象),迭代器和生成器:
代码示例:
# 普通循环 for x in listnumbers = [1, 2, 3,]for n in numbers: print(n) # 1,2,3# for循环实际干的事情# iter输入一个可迭代对象list,返回迭代器# next方法取数据my_iterator = iter(numbers)next(my_iterator) # 1next(my_iterator) # 2next(my_iterator) # 3next(my_iterator) # StopIteration exception# 迭代器循环 for x in iteratorfor i,n in enumerate(numbers): print(i,n) # 0,1 / 1,3 / 2,3# 生成器循环 for x in generatorfor i in range(3): print(i) # 0,1,2上面示例代码中python内置函数iter和next的用法:
比较容易混淆的是__iter__和__next__两个方法。它们的区别是:
__iter__返回自身的做法有点类似 python中的类型系统。为了保持一致性,python中一切皆对象。
每个对象创建后,都有类型指针,而类型对象的指针指向元对象,元对象的指针指向自身。
生成器,是在__iter__方法中加入yield语句,好处有:
yield作用:
三种循环模式常用函数
for x in container 方法:
for x in iterator 方法:
for x in generator 方法:
Dataloder源码分析
pytorch采用for x in iterator 模式,从Dataloader类中读取数据。
以下代码只截取了单线程下的数据读取。
class DataLoader(object): r""" Data loader. Combines a dataset and a sampler, and provides single- or multi-process iterators over the dataset. """ def __init__(self, dataset, batch_size=1, shuffle=False, ...): self.dataset = dataset self.batch_sampler = batch_sampler ... def __iter__(self): return _DataLoaderIter(self) def __len__(self): return len(self.batch_sampler)class _DataLoaderIter(object): r"""Iterates once over the DataLoader's dataset, as specified by the sampler""" def __init__(self, loader): self.sample_iter = iter(self.batch_sampler) ... def __next__(self): if self.num_workers == 0: # same-process loading indices = next(self.sample_iter) # may raise StopIteration batch = self.collate_fn([self.dataset[i] for i in indices]) if self.pin_memory: batch = pin_memory_batch(batch) return batch ... def __iter__(self): return selfDataloader类中读取数据Index的方法,采用了for x in generator 方式,但是调用采用iter和next函数
总结
本文总结了python中循环的三种模式:
pytorch中的数据加载模块 Dataloader,使用生成器来返回数据的索引,使用迭代器来返回需要的张量数据,可以在大量数据情况下,实现小批量循环迭代式的读取,避免了内存不足问题。
参考文章
迭代器和生成器
流畅的Python-第14章:可迭代的对象、迭代器和生成器
pytorch-dataloader源码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
Python中迭代器与生成器实例详解本文通过针对不同应用场景及其解决方案的方式,总结了Python中迭代器与生成器的一些相关知识,具体如下:1.手动遍历迭代器应
前言生成器generator生成器的本质是一个迭代器(iterator)要理解生成器,就要在理解一下迭代,可迭代对象,迭代器,这三个概念Python生成器gen
生成器就是自己用python代码写的迭代器,生成器的本质就是迭代器。通过以下两种方式构建一个生成器:1、通过生成器函数2、生成器表达式生成器函数:函数deffu
4.生成器(generator)4.1.生成器简介首先请确信,生成器就是一种迭代器。生成器拥有next方法并且行为与迭代器完全相同,这意味着生成器也可以用于Py
在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor)。一、迭代器(iterator)在Python中,f