日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

dataloader 源码_pytorch :: Dataloader中的迭代器和生成器应用

發(fā)布時(shí)間:2025/3/15 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 dataloader 源码_pytorch :: Dataloader中的迭代器和生成器应用 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在使用pytorch訓(xùn)練模型,經(jīng)常需要加載大量圖片數(shù)據(jù),因此pytorch提供了好用的數(shù)據(jù)加載工具Dataloader。

為了實(shí)現(xiàn)小批量循環(huán)讀取大型數(shù)據(jù)集,在Dataloader類具體實(shí)現(xiàn)中,使用了迭代器和生成器。

這一應(yīng)用場(chǎng)景正是python中迭代器模式的意義所在,因此本文對(duì)Dataloader中代碼進(jìn)行解讀,可以更好的理解python中迭代器和生成器的概念。

本文的內(nèi)容主要有:

解釋python中的迭代器和生成器概念

解讀pytorch中Dataloader代碼,如何使用迭代器和生成器實(shí)現(xiàn)數(shù)據(jù)加載

python迭代基礎(chǔ)

python中圍繞著迭代有以下概念:

可迭代對(duì)象 iterables

迭代器 iterator

生成器 generator

這三個(gè)概念互相關(guān)聯(lián),并不是孤立的。在可迭代對(duì)象的基礎(chǔ)上發(fā)展了迭代器,在迭代器的基礎(chǔ)上又發(fā)展了生成器。

學(xué)習(xí)這些概念的名詞解釋沒(méi)有多大意義。編程中很多的抽象概念都是為了更好的實(shí)現(xiàn)某些功能,才去人為創(chuàng)造的協(xié)議和模式。

因此,要理解它們,需要探究概念背后的邏輯,為什么這樣設(shè)計(jì)?要解決的真正問(wèn)題是什么?在哪些場(chǎng)景下應(yīng)用是最好的?

迭代模式首先要解決的基礎(chǔ)問(wèn)題是,需要按一定順序獲取集合內(nèi)部數(shù)據(jù),比如循環(huán)某個(gè)list。

當(dāng)數(shù)據(jù)很小時(shí),不會(huì)有問(wèn)題。但當(dāng)讀取大量數(shù)據(jù)時(shí),一次性讀取會(huì)超出內(nèi)存限制,因此想出以下方法:

把大的數(shù)據(jù)分成幾個(gè)小塊,分批處理

惰性的取值方式,按需取值

循環(huán)讀數(shù)據(jù)可分為下面三種應(yīng)用場(chǎng)景,對(duì)應(yīng)著容器(可迭代對(duì)象),迭代器和生成器:

for x in container: 為了遍歷python內(nèi)部序列容器(如list), 這些類型內(nèi)部實(shí)現(xiàn)了__getitem__() 方法,可以從0開始按順序遍歷序列容器中的元素。

for x in iterator: 為了循環(huán)用戶自定義的迭代器,需要實(shí)現(xiàn)__iter__和__next__方法,__iter__是迭代協(xié)議,具體每次迭代的執(zhí)行邏輯在 __next__或next方法里

for x in generator: 為了節(jié)省循環(huán)的內(nèi)存和加速,使用生成器來(lái)實(shí)現(xiàn)惰性加載,在迭代器的基礎(chǔ)上加入了yield語(yǔ)句,最簡(jiǎn)單的例子是 range(5)

代碼示例:

# 普通循環(huán) for x in list

numbers = [1, 2, 3,]

for n in numbers:

print(n) # 1,2,3

# for循環(huán)實(shí)際干的事情

# iter輸入一個(gè)可迭代對(duì)象list,返回迭代器

# next方法取數(shù)據(jù)

my_iterator = iter(numbers)

next(my_iterator) # 1

next(my_iterator) # 2

next(my_iterator) # 3

next(my_iterator) # StopIteration exception

# 迭代器循環(huán) for x in iterator

for i,n in enumerate(numbers):

print(i,n) # 0,1 / 1,3 / 2,3

# 生成器循環(huán) for x in generator

for i in range(3):

print(i) # 0,1,2

for x in container方法:

list, deque, …

set, frozensets, …

dict, defaultdict, OrderedDict, Counter, …

tuple, namedtuple, …

str

for x in iterator方法:

enumerate() # 加上list的index

sorted() # 排序list

reversed() # 倒序list

zip() # 合并list

for x in generator方法:

range()

map()

filter()

reduce()

[x for x in list(...)]

上面示例代碼中python內(nèi)置函數(shù)iter和next的用法:

iter函數(shù),調(diào)用__iter__,返回一個(gè)迭代器

next函數(shù),輸入迭代器,調(diào)用__next__,取出數(shù)據(jù)

比較容易混淆的是__iter__和__next__兩個(gè)方法。它們的區(qū)別是:

__iter__是為了可以迭代,真正執(zhí)行取數(shù)據(jù)的邏輯是__next__方法實(shí)現(xiàn)的,實(shí)際調(diào)用是通過(guò)next(iterator)完成

__iter__可以返回自身(return self),實(shí)際讀取數(shù)據(jù)的實(shí)現(xiàn)放在__next__方法

__iter__可以和yield搭配,返回生成器對(duì)象

__iter__返回自身的做法有點(diǎn)類似 python中的類型系統(tǒng)。為了保持一致性,python中一切皆對(duì)象。

每個(gè)對(duì)象創(chuàng)建后,都有類型指針,而類型對(duì)象的指針指向元對(duì)象,元對(duì)象的指針指向自身。

生成器,是在__iter__方法中加入yield語(yǔ)句,好處有:

減少循環(huán)判斷邏輯的復(fù)雜度

惰性取值,節(jié)省內(nèi)存和時(shí)間

yield作用:

代替函數(shù)中的return語(yǔ)句

記住上一次循環(huán)迭代器內(nèi)部元素的位置

Dataloder源碼分析

pytorch采用for x in iterator模式,從Dataloader類中讀取數(shù)據(jù)。

為了實(shí)現(xiàn)該迭代模式,在Dataloader內(nèi)部實(shí)現(xiàn)__iter__方法,實(shí)際返回的是_DataLoaderIter類。

_DataLoaderIter類里面,實(shí)現(xiàn)了 __iter__方法,返回自身,具體執(zhí)行讀數(shù)據(jù)的邏輯,在__next__方法中。

以下代碼只截取了單線程下的數(shù)據(jù)讀取。

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 self

Dataloader類中讀取數(shù)據(jù)Index的方法,采用了 for x in generator方式,但是調(diào)用采用iter和next函數(shù)

構(gòu)建隨機(jī)采樣類RandomSampler,內(nèi)部實(shí)現(xiàn)了 __iter__方法

__iter__方法內(nèi)部使用了 yield,循環(huán)遍歷數(shù)據(jù)集,當(dāng)數(shù)量達(dá)到batch_size大小時(shí),就返回

實(shí)例化隨機(jī)采樣類,傳入iter函數(shù),返回一個(gè)迭代器

next會(huì)調(diào)用隨機(jī)采樣類中生成器,返回相應(yīng)的index數(shù)據(jù)

class RandomSampler(object):

"""random sampler to yield a mini-batch of indices."""

def __init__(self, batch_size, dataset, drop_last=False):

self.dataset = dataset

self.batch_size = batch_size

self.num_imgs = len(dataset)

self.drop_last = drop_last

def __iter__(self):

indices = np.random.permutation(self.num_imgs)

batch = []

for i in indices:

batch.append(i)

if len(batch) == self.batch_size:

yield batch

batch = []

## if images not to yield a batch

if len(batch)>0 and not self.drop_last:

yield batch

def __len__(self):

if self.drop_last:

return self.num_imgs // self.batch_size

else:

return (self.num_imgs + self.batch_size - 1) // self.batch_size

batch_sampler = RandomSampler(batch_size. dataset)

sample_iter = iter(batch_sampler)

indices = next(sample_iter)

總結(jié)

本文總結(jié)了python中循環(huán)的三種模式:

for x in container 可迭代對(duì)象

for x in iterator 迭代器

for x in generator 生成器

pytorch中的數(shù)據(jù)加載模塊 Dataloader,使用生成器來(lái)返回?cái)?shù)據(jù)的索引,使用迭代器來(lái)返回需要的張量數(shù)據(jù),可以在大量數(shù)據(jù)情況下,實(shí)現(xiàn)小批量循環(huán)迭代式的讀取,避免了內(nèi)存不足問(wèn)題。

參考文章

python is、==區(qū)別;with;gil;python中tuple和list的區(qū)別;Python 中的迭代器、生成器、裝飾器

1. is 比較的是兩個(gè)實(shí)例對(duì)象是不是完全相同,它們是不是同一個(gè)對(duì)象,占用的內(nèi)存地址是否相同 == 比較的是兩個(gè)對(duì)象的內(nèi)容是否相等 2. with語(yǔ)句時(shí)用于對(duì)try except finally 的優(yōu) ...

Python中的迭代器和生成器

本文以實(shí)例詳解了python的迭代器與生成器,具體如下所示: 1. 迭代器概述:?迭代器是訪問(wèn)集合元素的一種方式.迭代器對(duì)象從集合的第一個(gè)元素開始訪問(wèn),直到所有的元素被訪問(wèn)完結(jié)束.迭代器只能往前不會(huì)后 ...

終于理解Python中的迭代器和生成器了!

迭代器和生成器 目錄 迭代器和生成器 可迭代對(duì)象和迭代器 基礎(chǔ)概念 判斷 for循環(huán)本質(zhì) 不想用for循環(huán)迭代了,如何使用迭代器? 列表推導(dǎo)式 生成器Generator 概念 如何實(shí)現(xiàn)和使用? 生成器 ...

Python中的迭代器、生成器

from collections import Iterable, Iterator 1. 可迭代(iterable)對(duì)象 參考官網(wǎng)鏈接 class I: def __init__(self, v): ...

python中的迭代器和生成器學(xué)習(xí)筆記總結(jié)

生成器就是一個(gè)在行為上和迭代器非常類似的對(duì)象.?? 是個(gè)對(duì)象! 迭代,顧名思意就是不停的代換的意思,迭代是重復(fù)反饋過(guò)程的活動(dòng),其目的通常是為了逼近所需目標(biāo)或結(jié)果.每一次對(duì)過(guò)程的重復(fù)稱為一次“迭代”,而 ...

python中的迭代器與生成器

迭代器 迭代器的引入 假如我現(xiàn)在有一個(gè)列表l=['a','b','c','d','e'],我想取列表中的內(nèi)容,那么有幾種方式? 1.通過(guò)索引取值 ,如了l[0],l[1] 2.通過(guò)for循環(huán)取值 fo ...

JS中的迭代器和生成器

利用迭代器生成一個(gè)遍歷方法: let arr1 = [1, 2, 3, 11, 22, 13, 24]; function forOf(arr, callback) { // 找到迭代器函數(shù) let ...

python中迭代器和生成器

l=[1,2,3,4] for n in l: print n 在看上面這段代碼的時(shí)候,我們沒(méi)有顯式的控制列表的偏移量,就可以自動(dòng)的遍歷了整個(gè)列表對(duì)象.那么for 語(yǔ)句是怎么來(lái)遍歷列表l的呢?要回答這 ...

ES6中的迭代器(Iterator)和生成器(Generator)

前面的話 用循環(huán)語(yǔ)句迭代數(shù)據(jù)時(shí),必須要初始化一個(gè)變量來(lái)記錄每一次迭代在數(shù)據(jù)集合中的位置,而在許多編程語(yǔ)言中,已經(jīng)開始通過(guò)程序化的方式用迭代器對(duì)象返回迭代過(guò)程中集合的每一個(gè)元素 迭代器的使用可以極大地簡(jiǎn) ...

隨機(jī)推薦

使用RMAN創(chuàng)建復(fù)制數(shù)據(jù)庫(kù)

我的實(shí)驗(yàn)環(huán)境: - 源數(shù)據(jù)庫(kù)A機(jī): RHEL6.4 + Oracle 11.2.0.4 IP地址:192.168.99.159 db_name=oradb 數(shù)據(jù)庫(kù)已正常運(yùn)行 - 復(fù)制數(shù)據(jù)庫(kù)B機(jī): RH ...

NETMON& Message Analyzer

NMCap /network * /capture? /file c:\folder\t.chn:1MB NMCap /network * /capture (IPv4.SourceAddress = ...

xcode中的第三方庫(kù)配置問(wèn)題總結(jié)

xcode中的第三方庫(kù)配置總結(jié) 在導(dǎo)入第三方庫(kù)的時(shí)候,總是會(huì)遇到許多的問(wèn)題.在這里,我記錄一下學(xué)到的一些知識(shí)點(diǎn).寫得比較亂.只要是想要記錄下來(lái),在第三方庫(kù)導(dǎo)入的時(shí)候,遇到的一些問(wèn)題. 參考網(wǎng)址: ht ...

QLockFile,QRunInfo

http://doc.qt.io/qt-5/qlockfile.html http://www.dushibaiyu.com/2014/10/qruninfo-api-smple.html

Android7.0 PowerManagerService 之亮滅屏(一)

本篇從按下power按鍵后,按鍵事件從InputManagerService 傳到PhoneWindowManager.java開始分析power 按鍵做屏幕亮滅過(guò)程的分析,關(guān)于power 按鍵的其他 ...

Android初級(jí)教程進(jìn)程間的通信AIDL

在介紹跨程序進(jìn)程間通信AIDL前,先看一下本程序activity與某個(gè)服務(wù)是怎么綁定在一起進(jìn)行交互的. 需求:服務(wù)有兩個(gè)方法.分別是播放音樂(lè)與停止播放音樂(lè).該程序的活動(dòng)要訪問(wèn)這兩個(gè)方法,在activi ...

ioremap_nocache() 函數(shù)的使用【轉(zhuǎn)】

本篇文章主要是在ioremap_nocache函數(shù)說(shuō)明的基礎(chǔ)上進(jìn)行整理,加入該函數(shù)的用法簡(jiǎn)介. 函數(shù)原型 void __iomem * ioremap_nocache (unsigned long o ...

單純linux系統(tǒng)下hadoop2.7.3 eclipse,記一次成功的運(yùn)行wordcount的注意事項(xiàng)

hadoop要正確安裝好 hadoop eclipse plugin要對(duì)應(yīng)相應(yīng)的eclipse版本 define hadoop location mr master:9000 另一個(gè)9001? 下面的 ...

沖刺N(yùn)OIP復(fù)習(xí),算法知識(shí)點(diǎn)總結(jié)

前言 ? ? ? ?離NOIP還有一個(gè)星期,匆忙的把整理的算法補(bǔ)充完善,看著當(dāng)時(shí)的整理覺(jué)得那時(shí)還年少.第二頁(yè)貼了幾張從貼吧里找來(lái)的圖片,看著就很熱血的.當(dāng)年來(lái)學(xué)這個(gè)競(jìng)賽就是為了興趣,感受計(jì)算機(jī)之美的. ...

users-and-groups-in-linux

https://www.tecmint.com/compress-files-and-finding-files-in-linux/ https://www.tecmint.com/manage-us ...

總結(jié)

以上是生活随笔為你收集整理的dataloader 源码_pytorch :: Dataloader中的迭代器和生成器应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。