住房城乡建设部招投标网站,模板网站如何做优化,深圳做网站公司华,搜索引擎优化的例子torch.utils.data.DataLoader是PyTorch数据加载工具的核心#xff1b;表示一个Python可迭代数据集#xff1b;
DataLoader支持的数据集类型
map-style 和 iterable-style 的数据集#xff1b;可定制的数据加载顺序#xff1b;自动批量数据集#xff1b;单进程和多进程数…torch.utils.data.DataLoader是PyTorch数据加载工具的核心表示一个Python可迭代数据集
DataLoader支持的数据集类型
map-style 和 iterable-style 的数据集可定制的数据加载顺序自动批量数据集单进程和多进程数据加载自动内存固定
DataLoader构造函数
DataLoader(dataset,batch_size1,shuffleFalse,samplerNone,batch_samplerNone,num_workers0,collate_fnNone,pin_memoryFalse,drop_lastFalse,timeout0,worker_init_fnNone,multiprocessing_contextNone,generatorNone,*prefetch_factor2,persistent_workersFalse,pin_memory_device)
Dataset 类型
DataLoader构造函数中的最重要的参数是datasetdataset指示了加载数据的数据集对象PyTorch支持两种不同类型数据集map-style数据集可迭代类型数据集
Map-Style数据集
实现了__getitem__()函数和__len__函数表示一个从指数/键值到数据样本的映射dataset[idx],可以从磁盘的文件夹中读取第idx序列的图像和相应的标签
可迭代类型数据集
是IterableDataset子类的一个实例实现了__iter__()函数原型表示了一个可迭代的数据样本集该类型的数据集特别适合代价较高的随机读取或者不可随机读取的场合批量数据的大小依赖于获取的数据调用iter(dataset),可以返回一个数据流、远程的服务器或者实时生成的日志
数据加载顺序和采样器
对于可迭代数据集数据加载的顺序取决于用户的定义上述特性允许简单的实现块读取和动态批量大小数据读取对于map-style类型的数据集torch.utils.data.Sampler类用于指定数据加载中的指数/键值序列他们表示数据集的指数可迭代对象在随机梯度下降SGD的情况下Sampler可以随机的排序指数列表且可即时生成一个指数列表或者可以生成一个mini-batch SGD的小量值的指数序列基于shuffle参数可以自动的构建一个序列或者被洗牌的采样器给到DataLoader;相反的用户可用采样器参数指定一个定制的采样器对象生成下一个要获取的指标/键值定制的采样器可生成批量指数的列表并以batch_sampler参数传递给DataLoader通过batch_size和drop_last参数可激活自动批量模式
加载批量的和非批量的数据
通过参数batch_sizedrop_lastbatch_sampler和collate_fnDataLoader支持自动整理获取的数据样本到批量集合中
自动批量默认
最常见的情况对应于获取一个小量数据且整理他们到一个批次样本中也就是包含张量的一个维度作为批量的维度通常是第一维当batch_size默认1非空时数据加载器生成批量的样本batch_size和drop_last参数被用于指定数据加载器如何获得批量的数据集键值对于映射数据集用户可以指定batch_sampler一次生成一个键值的列表
失能自动批量
某些情况下用户可能想要手动处理批量数据集或简单的加载几个样本参数batch_size和batch_sampler都为None时自动批量失能每一个从数据集获取的样本被传递给collate_fn作为参数的函数所处理自动批量失能时默认collate_fn简单转换Numpy数组为PyTorch张量保持一切不受影响
单一进程和多进程数据加载
DataLoader默认使用单一进行加载数据在一个python进程中GIL(Global Interpreter Lock)阻止跨线程真全并行python代码运行为了避免数据加载的计算代码PyTorch提供通过设置num_worker参数为正整数的简单设置切换执行多线程数据加载
单一进程数据加载默认
该模式下在DataLoader初始化的同一进程中获取数据因此数据加载可能会阻塞计算在跨进程共享数据的资源共享的内存和文件描述符有限时该模式被优先考虑或者当整个数据集较小且可以被整体加载进内存时该模式被优先考虑另外单进程加载通常显式更多的可读性错误追踪信息更有利与调试
多进程数据加载
设置num_worker为正整数将会开启多进程数据加载多进程的数量为num_worker的数量一些次数的迭代后加载器工作进程将会同父进程消耗相同的CPU内存这在数据集含大量数据比如在数据集构建时加载大量的文件名列表时可能有问题或者用户使用了多个进程总的内存消耗number_of_workers*size_of_parent_process时可能会有问题最简单的应变方式为使用非参考计数的表示比如PandasNumpy或者PyArrow对象替换python对象该模式下在一个DataLoader迭代器被创建时num_workers数量的进程被创建datasetcollate_fn和worker_init_fn被传递到每一个进程上述三者被用于进程初始化和数据的获取这意味着在工作进程的运行中内部IO转换操作同数据获取被一同处理torch.utils.data.get_worker_info()在一个工作进程中返回多种有用信息包括进程id数据集副本初始化速度等且在主进程中返回None用户可以在数据集代码中使用torch.utils.data.get_worker_info()函数worker_init_fn独立配置每一个数据集副本以确定是否在工作进程中运行代码对映射类型的数据集主进程使用采样器生成索引并传送到工作进程中任何随机洗牌在主程序中执行主程序通过分配索引确定数据加载顺序对可迭代类型数据集每一个工作进程获取一个数据集对象的副本原始的多进程加载将导致数据的复制使用torch.utils.data.get_worker_info()和worker_init_fn用户可以独立配置每一个副本多线程加载中drop_last参数去掉每一个进程中的可迭代数据集副本的不完整批量数据当迭代的最后一位被达到时进程被关闭基于多进程中使用CUDA和共享CUDA张量的细节原因在多进程加载中不推荐返回CUDA张量推荐使用自动内存固定(设置pin_memoryTrue)能够更快传递数据到CUDA使能的GPU中;
基于平台的行为
由于工作进程依赖于Python multiprocessing进程启动行为windows和Unix是有区别的UNix上fork() 是默认的multiprocessing启动方法使用fork()直接通过克隆的地址空间子工作进程可获取dataset和Python参数windows或者MacOS上spawn()是默认的multiprocessing启动方法使用spawn(),另一个解释器被启动运行用户的主要脚本以及通过pickle序列化接收数据集的内部工作进程函数、collate_fn和其他参数以上单独的序列化意味着应该采取两个步骤以确保在使用多进程数据加载时与windows兼容打包大部分主要的脚本代码在if __name____main__:程序块中确保当每一个工作进程被启动时if __name____main__:不再次启动你可以在if __name____main__:程序块中放置数据集和DataLoader·实例创建逻辑因为在工作进程中其不需要被再次执行确保collate_fnworker_init_fn或者dataset代码声明在顶级的__main__检查之外的定义中这就保证了上述代码声明在工作进程中是可用的
多进程数据加载的随机性
默认情况下每一个工作进程将具有自己的PyTorch种子设置为base_seedworker_id这里base_seed是一个由主进程使用他的RNG或者一个指定的生成器生成的长周期数据然而用于其他库的种子可以通过初始化工作进程被复制导致每一个工作进程返回一致的随机数在worker_init_fn中你可以获取PyTroch种子集用于每一个工作进程使用torch.utils.data.get_worker_info().seed或者torch.initial_seed();也可以使用上述两个种子为其他库在数据加载之前设置种子
内存锁定
主机到GPU的拷贝更快当数据来自锁定内存时对数据加载,DataLoader的pin_memoryTrue时自动将获取的数据张量放到锁定内存中默认的内存锁定逻辑仅识别张量和映射以及包含张量的可迭代对象默认情况下锁定逻辑观察到一个批量定制数据类型当有一个collate_fn返回一个定制批量类型时或者批量数据中的每一个单元都是定制类型时锁定逻辑不能识别他们将返回不在锁定内存中的批量数据或者单元为了使能内存锁定用于定制批量数据或者数据类型定义一个pin_memory方法在你的定制类型中
内存锁定实例
import torch
from torch.utils.data import DataLoader
class SimpleCustomBatch:def __init__(self,data):transposed_datalist(zip(*data))self.inptorch.stack(transposed_data[0],0)self.tgttorch.stack(transposed_data[1],0)def pin_memory(self):self.inpself.inp.pin_memory()self.tgtself.tgt.pin_memory()return selfdef collate_wrapper(batch):return SimpleCustomBatch(batch)inpstorch.arange(10*5,dtypetorch.float32).view(10,5)
tgtstorch.arange(10*5,dtypetorch.float32).view(10,5)
datasetTensorDataset(inps,tgts)loaderDataLoader(dataset,batch_size2,collate_fncollate_wrapper,pin_memoryTrue)for batch_ndx,sample in enumerate(loader):print(sample.inp.is_pinned())print(sample.tgt.is_pinned())
DataLoader参数解析
DataLoader合并一个数据和一个采样器提供一个可迭代的采样器DataLoader在单线程或多线程模式下支持映射类型数据集和可迭代类型数据集DataLoader支持定制的加载顺序和可优化的自动批量整理和内存锁定;dataset(Dataset)---加载数据的数据集batch_sizeIntoptional---每一批次加载多少数据样本默认为1shuffle(bool,optional)---设置为True每一代都进行数据洗牌默认Falsesampler(Sampler or iterable,optional)---定义从数据集抽取样本的策略可以是实现__len__功能的任意Iterable对象如果指定的话shuffle必须不指定batch_samplerSampler or iterableoptional---类似与sampler但是一次返回一个索引批次同batch_sizeshufflesampler和drop_last相互排斥num_workersintoptional---多少子进程用于数据加载0意味着将在主进程加载数据默认0collate_fnCallableoptional---合并一个样本列表为一个张量mini-batch的型式当从映射数据集使用批次加载时使用pin_memorybooloptional---如果设置为True在返回数据之前数据加载器将拷贝张量到设备/CUDA的锁定内存区.如果你的数据单元是一个定制类型或者你的collate_fn返回一个批次定制类型参考文档中的实例drop_lastbooloptional---设置为true丢弃最后不完整的批次如果数据集的大小不能被批量大小整除的话。如果设置为False且数据集的大小不被批次大小整除最后的批次将很小默认Falsetimeoutnumericoptional---如果为正数超时值用于收集一个工作进程的批次应当总是非正数默认0worker_init_fnCallableoptional---如果非空该函数将会被在每一个工作子进程被调用以工作进程id一个正数在【0num_workers-1】范围内作为输入multiprocessing_context(str or multiprocessing.context.BaseContext,optional)---如果为空操作系统的默认多进程上下文会被使用默认为空generator(torch.Generator,optional)---如果非空随机采样器将使用RNG生成随机指标并多进程申城base_seed用于工作进程默认为空prefetch_factor(int,optional,keywork-only arg)---每一个工作进程提前加载的批次数量2意味着对于所有的工作进程将有总数为2*num_worker批次的预取数据默认值依赖于参数num_worker的值如果num_worker0默认值为空否则num_worker0,默认值为2persistent_workers(bool,optional)---如果为True,数据加载器在一个数据集被消耗一次之后将不关闭工作进程,这允许保持工作进程数据集实例为活动状态(默认为False);pin_memory_device(str,optional)---如果为True,设备锁定内存运行.