大数据现象形成的原因,大数据是怎么形成的因素,大数据的现象是怎样形成的
目录
1 .简介
2.整体流程
3.取样器和批量取样器
3.1取样器
3.2批量取样器
4.数据加载器
4.1数据加载器
4.2 _数据加载器
1.引言本文将介绍pytorch
采样器Sampler
和数据加载器DataLoader
,讲解读取数据时各个批次形成的过程,并附上部分源代码说明。了解这些可以帮助我们更好地研究抽样方法和模型训练。希望看完之后,你能对数据批量生成的过程有更清晰的认识。
让我们开始吧。
2.总体流程简单来说,在pytorch中,采样器负责确定读取数据的顺序,DataLoader负责加载数据,并根据采样器提供的顺序排列数据。具体工艺图及说明如下。
在初始化DataLoader时,需要指定数据集(包括数据和标签),采样器是可选的。如果没有采样器,将根据数据顺序是否打乱,分别使用顺序采样器和随机采样器。
第一步,采样器首先根据数据集的大小n形成一个迭代序列号列表[0~n-1]。
第二步:batchSampler根据DataLoader的batch_size参数将Sampler提供的序列分成若干个批量大小的迭代序列组,drop_last参数决定是否保留最后一组。
(3)第三步:双向采样器(batchSampler)和数据集合二为一。当DataLoader被迭代读取时,BatchSampler中一个批次的编号被用来在Dataset中查找对应的数据和标签,一个批次数据被读出。
以批量数据的形成为例。
假设数据集D={X,Y},其中数据X是【野外的野兔。png,野外的野猫。png,家里的野狗。png,野外的野狗。png],标签y是[0,1,1,2,2]
(1)初始流水号列表为
[0, 1, 2, 3, 4]
,用RandomSampler不重复采样(replacement==FALSE),采样流水号列表为[3, 2, 1, 0, 4]
。第二步:输入batch_size为2,drop_last为FALSE,那么使用BatchSampler进行批量采样,形成列表[[3,2],[1,0],[4]];如果drop_last为TRUE,则列表变为[[3,2],[1,0]]
第三步:迭代读取数据,根据序号从数据集中找到对应的数据和标签。例如,第一批是:
home.png的野狗,家里的野猫. png],[2,1]]
以上是形成一批数据的全过程。下面将从代码的角度介绍每个类中的重要参数和函数。我用的是pytorch的老版本(0.4.1.post2),自己对比了1.7.0版本的代码。其中BatchSampler类基本相同,Sampler类去掉了__len__()方法。一般来说,抽样变化不大;DataLoader类主要针对多线程进行了优化,具体代码中加入了大量注释。整体基础还是本文提到的方法。
3.采样器和BatchSampler 3.1采样器知乎在上一篇文章中详细解释了pytorch采样器:一篇文章理解了Pytorch的DataLoader、DataSet、采样器之间的关系。
简单来说,Sampler类__init__()方法用于初始化采样算法,__iter__()方法使用torch的随机和多项式方法实现随机和基于权重的采样并返回一个可迭代对象,__len__()为返回采样长度。
3.2批量取样器参数:
采样器(采样器类):输入采样器。
Batch_size(int class):设置批量大小
Drop_last(bool类):是否丢弃最后一个小于batch_size的批处理?
重要功能:
__init__初始化各种参数
def __init__(self,sampler,batch_size,Drop _ last):self . sampler=sampler self . batch _ size=batch _ size self . drop _ last=drop _ last _ _ ITER _ _循环读取采样器生成的序列号列表。采样足够batch _ size的大小后,返回batch,下一次清空Batch继续采集。
def _ _ ITER _ _(self):batch=[]for idx in self。采样器:批量。如果len(batch)==self,则追加(idx)。批量大小:#通过产量返回,下一个国际热核聚变实验堆时清空一批继续采集产量批次批次=[] #如果不需滴最后一组返回最后一组如果len(批次)为0且不是自我。drop _ last:产量批_ _ len _ _返回一批数量,如果滴最后一个,则序列长度对批量大小取整,否则加上一
def _ _ len _ _(self):如果self。drop _ last:return len(self。采样器)//self。batch _ size else:return(len(self。采样器)自己。batch _ size-1)//self。批量大小为4。数据加载器4.1数据加载器重要参数:
数据集(数据集类):数据集类型的输入数据,由数据和标签组成
批处理大小(整数类):同批量取样器
洗牌(布尔类):是否打乱数据顺序
采样器(采样器类):同批量取样器
批处理_采样器(批量取样器类)
drop_last(bool类):同批量取样器
重要函数:
__init__中对参数关系中的互斥情况进行了排除,指定刺绣样本并通过批处理_采样器分出批次,
def __init__(self,dataset,batch_size=1,shuffle=False,sampler=None,batch_sampler=None,num_workers=0,collate_fn=default_collate,pin_memory=False,drop_last=False,timeout=0,worker_init_fn=None): #.# 互斥关系,指定了批处理_采样器时、批量大小、无序播放、采样器和drop_last无效如果批处理_采样器不是无:如果批量大小1或洗牌或刺绣样本不是没有人或drop_last:提高值错误( batch _ sampler option )与批量大小、洗牌、取样和 删除最后一个互斥)自我。batch _ size=无自身。drop _ last=None #互斥关系,指定了刺绣样本时,洗牌无效如果刺绣样本不为没有人且无序播放:提高值错误(采样器选项与“洗牌”互斥)如果自我。num _ workers 0:提高值错误( num _ workers选项不能为负;请使用num_workers=0来禁用多处理。) # 此处可以看出,洗牌与否其实还是靠刺绣样本类型实现的# 当不指定刺绣样本时,不洗牌就是顺序采样,洗牌就是随机采样if批处理_采样器为无:如果采样器为无:如果随机:采样器=随机采样器(数据集)否则:采样器=顺序采样器(数据集)#用批处理_采样器对刺绣样本产生的序列划分batch batch _ sampler=batch sampler(sampler,batch_size,drop _ last)自身。采样器=采样器本身。批处理取样器=批处理取样器本身.__initialized=True DataLoader的__iter__是在_DataLoaderIter类中实现的,该类也是整个迭代方法的核心
def _ _ ITER _ _(self):return _ DataLoaderIter(self)4.2 _ DataLoaderIter _ _ init _ _初始化并指定了采样器_iter,即批处理_采样器
def __init__(self,loader):self。数据集=加载器。数据集自身。collate _ fn=loader。collate _ fn自我。batch _ sampler=loader。批处理_采样器自身。num _ workers=loader。num _ workers self。pin _ memory=loader。pin _存储器和火炬。cuda。is _ available()self。超时=加载程序。暂停自我。done _ event=线程化.事件()自身。sample _ ITER=ITER(自我。批处理_采样器)#._获取_批处理读取数据,加入了连接超时的判断
定义_获取_批处理(自身):#连接超时如果自我。超时0:尝试:返回自我。数据队列。get(time out=self。超时)队列除外.空:引发运行时错误("数据加载器在{}秒后超时")。格式(自我。time out))else:回归自我。数据队列。get()_ DataLoaderIter在每次调用时会执行__下一个_ _方法返回下一个一批
def _ _ next _ _(self):如果self。num _ workers==0:#相同进程加载索引=next(self。样品_ ITER)#五月引发停止迭代批次=自身。collate _ fn([self。dataset[I]for I in indexes]),如果self。pin _ memory:batch=pin _ memory _ batch(batch)返回批次号检查是否已经生成下一个样本如果自我。reorder _ dict:batch=self。reorder _ dict。pop(自我。rcvd _ idx)_ process _ next _ batch(batch)如果self。batches _ outstanding==0:self ._shutdown_workers()在真实的时引发停止迭代:断言(非自身。关闭和自我。batches _ outstanding 0)idx,batch=self ._ get _ batch()self。batches _ outstanding-=1 if idx!=self.rcvd_idx: # store无序样本self.reorder_dict[idx]=批处理继续返回自我._process_next_batch(批处理)#调用时执行__next__next=__next__ # Python 2兼容性
欢迎交流和指正。