pytorch保存tensor数据,pytorch 读取数据
pytorch的数据读取pytorch数据读取的核心是torch.utils.data.DataLoader类,它具有以下特征:
支持map风格数据集和iterable风格数据集自定义数据读取顺序,自动批量单线程/多线程读取,自动锁定内存页。1.整个流程数据加载器的参数如下,主要涉及dataset、sample、collate_fn和pin_memory。
DataLoader(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,*,prefetch _ factor=2,persistent _ workers=False)py torch读取数据的整体处理流程如下:
无论是map风格还是iterable风格的数据集,整个过程都是
先用采样器采样,一次获取一个样本的索引(iterable-style dataset使用伪采样器,每次都不生成,不管它通过索引得到的值是多少)。使用batch_sampler生成长度为batch_size的索引列表(实际上是使用sampler对batch_size次数进行采样)。使用collate_fn将batch_size长度列表整理成批次样本(张量格式)。2.数据集类型pytorch支持两种类型的数据集,地图样式的数据集和可迭代样式的数据集。
Map-style datasets的典型数据集word是指__getitem__()和__len__()协议的实现,它表示从索引到数据样本的映射。
您可以继承抽象类torch.utils.data.DataSet,并重写__getitem__()和__len__()方法。
注意:Dataloader默认构造的采样器都返回整数索引。如果数据集的索引不是整数,就需要定制采样器。
Iterable风格数据集的迭代数据集是torch.utils.data.iterable数据集的子类,需要实现__iter__()协议来表示数据样本的一轮迭代。
Iterable-style dataset是一个类似于python的迭代对象。使用iter()方法会得到一个迭代器,每次调用next()都会得到下一个样本。无法使用索引提取元素。所以你不能用采样器采样来得到指数,但是你可以用指数来得到样本。在dataloader的实现中,对可迭代数据集使用了一个假采样器InfiniteConstantSampler。每个调用都不返回任何值。
class _ InfiniteConstantSampler(Sampler):r 类似于` ` itertools.repeat(None,None)``。用作以下对象的采样器:class:` ~ torch . utils . data . iterable Dataset `. Args:data _ source(Dataset):要从中采样的数据集 def _ _ init _ _(self):super(_ Infiniteconstallsampler,self)。_ _ init _ _(none)def _ _ ITER _ _(self):while true:yield none此采样器的目的是控制batch_sample期间的采样次数。
3.采样器对于IterableDataset,数据读取的成功与否是由用户自定义迭代决定的。回想一下python的迭代器,我们只能循环调用next()方法依次获取下一个样本。不能改变原来的顺序。
对于may样式的数据集,sampler用于指定读取数据时样本索引的顺序。您可以指定DataLoader的shuffle参数来指导顺序或无序读取。如果shuffle=True,将自动构造一个RandomSampler采样器;如果shuffle=False,将构造一个SequentialSample。您也可以自定采样器,并用sample参数指定它。自定义采样器每次返回下一个样本的索引。注意采样器返回的都是样本索引,不是样本本身。需要根据索引获取样本。
Batch_sampler如果一个采样器采样器一次返回一个批量大小的索引列表,则称为batch_sampler。如果指定batch_size和drop_last参数,将基于采样器自动构造batch_sampler。地图样式数据集也可以使用batch_sampler参数来指定自定义的批处理采样器。
4.collate_fn collate_fn字面上是一个整理函数,处理batch_sampler返回的长度为batch_size的索引列表,处理成模型可以使用的batch_size大小的张量。
这里需要注意采样器采样器/批处理_采样器返回的都是样本索引,校对_fn的输入是批量大小的样本列表。所以在传给校对_fn前要根据索引取样本。
如果是五月风格数据集,这个操作大概等价于:
对于批处理_采样器中的索引:yield collate _ fn([索引中我的数据集[i])如果是可迭代式数据集,大概等价于:
对于batch _ sampler中的索引,dataset _ ITER=ITER(dataset):yield collate _ fn([next(dataset _ ITER)for _ in indexes])可以看到可迭代式的索引其实是没用的,只是用来控制采样的个数。同时,发现校对_fn函数接收的参数是样本列表校对_fn的一个重要功能就是把这个列表加工成框架支持的数据格式张量。通过看框架的源码,如果不指定collate_fn,会使用默认的校对_fn函数,这个函数的功能就是将各种类型的数据转化成张量。也可以自定义衣领_fn函数,然后通过校对_fn参数指定,在自定义的函数中增加需要的操作。例如,将每个样本填料到当前一批的最大样本长度。任何想要对批量数据进行的操作都要定义在这个函数中。
pytroch的默认校对_fn实现:
def default_collate(batch): r 将每个数据字段放入具有外部维度批处理大小 elem=batch[0]elem _ type=type(elem)如果是实例(elem,torch .张量):out=无如果火炬。utils。数据。获取工人信息()不为无:#如果我们在后台进程中,直接串联成一个#共享内存张量以避免额外的副本numel=sum([x . numel()for x in batch])storage=elem。存储()._ new _ shared(numel)out=elem。新(存储)返回火炬。stack(batch,0,out=out) elif elem_type .__module__==numpy 和elem_type .__name__!=str_ \和elem_type .__name__!= string _ :elem=batch[0]if elem _ type ._ _ name _ _== ndarray :# string类的数组和对象if NP _ str _ obj _ array _ pattern。搜索(elem。数据类型。str)not None:引发类型错误(default _ collate _ err _ msg _ format。格式(elem。dtype))返回default _ collate([torch。as _ tensor(b)for b in batch])elif elem。shape==():#标量返回火炬。as _ tensor(batch)elif is instance(elem,float):return torch。tensor(batch,dtypemapping):return { key:default _ collate([d[key]for d in batch])for key in elem } elif is instance(elem,tuple) and hasattr(elem, _ fields ):# named tuple return elem _ type(*(default _ collate(samples)for samples in zip(* batch)))elif is instance(elem,container_abcs。sequence):transposed=zip(* batch)return[default _ collate(samples)for samples in transposed]引发类型错误(default _ collate _ err _ msg _ format。format(elem _ type))5。pin _存储器这部分来自博客
pin _存储器是指锁页内存,什么是锁页内存?
内存分为锁页和不锁页,锁页内存存的内容在任何情况下都不会与机器的虚拟内存(虚拟内存就是硬盘)进行交换。不锁页内存在主机内存不足时,数据会存放到虚拟内存。
如果pin_memory=True,那么生成的数据都会放在锁页内存上,此时将张量拷贝到国家政治保卫局。参见国家政治保卫局的显存会更快。
6.自动批量化/非批量化数据加载器默认返回批量的样本(批量大小默认为1)。当参数批量大小和批次_样本均为没有人时,会关闭自动批量化操作。此时会将采样的单个样本传给校对_fn函数。
参考[1]pytorch官方文档火炬。实用程序。数据部分
[2]博客:pytorch创建数据。数据加载器时,参数pin _存储器的理解
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。