最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

pytorch::Dataloader中的迭代器和生成器應(yīng)用詳解

 更新時(shí)間:2020年01月03日 08:26:44   作者:hansoluo  
這篇文章主要介紹了pytorch::Dataloader中的迭代器和生成器應(yīng)用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在使用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中圍繞著迭代有以下概念:

  1. 可迭代對(duì)象 iterables
  2. 迭代器 iterator
  3. 生成器 generator

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

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

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

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

當(dāng)數(shù)據(jù)很小時(shí),不會(huì)有問題。但當(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)存和加速,使用生成器來實(shí)現(xiàn)惰性加載,在迭代器的基礎(chǔ)上加入了yield語句,最簡(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

上面示例代碼中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)用是通過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語句,好處有:

  • 減少循環(huán)判斷邏輯的復(fù)雜度
  • 惰性取值,節(jié)省內(nèi)存和時(shí)間

yield作用:

  • 代替函數(shù)中的return語句
  • 記住上一次循環(huán)迭代器內(nèi)部元素的位置

三種循環(huán)模式常用函數(shù)

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(...)]

Dataloder源碼分析

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

  1. 為了實(shí)現(xiàn)該迭代模式,在Dataloader內(nèi)部實(shí)現(xiàn)__iter__方法,實(shí)際返回的是_DataLoaderIter類。
  2. _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ù)

  1. 構(gòu)建隨機(jī)采樣類RandomSampler,內(nèi)部實(shí)現(xiàn)了 __iter__方法
  2. __iter__方法內(nèi)部使用了 yield,循環(huán)遍歷數(shù)據(jù)集,當(dāng)數(shù)量達(dá)到batch_size大小時(shí),就返回
  3. 實(shí)例化隨機(jī)采樣類,傳入iter函數(shù),返回一個(gè)迭代器
  4. 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,使用生成器來返回?cái)?shù)據(jù)的索引,使用迭代器來返回需要的張量數(shù)據(jù),可以在大量數(shù)據(jù)情況下,實(shí)現(xiàn)小批量循環(huán)迭代式的讀取,避免了內(nèi)存不足問題。

參考文章

迭代器和生成器
流暢的Python-第14章:可迭代的對(duì)象、迭代器和生成器
pytorch-dataloader源碼

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 在?Python?中如何將天數(shù)添加到日期

    在?Python?中如何將天數(shù)添加到日期

    這篇文章主要介紹了在?Python?中將天數(shù)添加到日期,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • 使用pandas中的DataFrame數(shù)據(jù)繪制柱狀圖的方法

    使用pandas中的DataFrame數(shù)據(jù)繪制柱狀圖的方法

    下面小編就為大家分享一篇使用pandas中的DataFrame數(shù)據(jù)繪制柱狀圖的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Python中將dataframe轉(zhuǎn)換為字典的實(shí)例

    Python中將dataframe轉(zhuǎn)換為字典的實(shí)例

    下面小編就為大家分享一篇Python中將dataframe轉(zhuǎn)換為字典的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Python正則表達(dá)式和re庫知識(shí)點(diǎn)總結(jié)

    Python正則表達(dá)式和re庫知識(shí)點(diǎn)總結(jié)

    在本篇文章中小編給大家分享了關(guān)于Python正則表達(dá)式和re庫知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們學(xué)習(xí)下。
    2019-02-02
  • 用Python制作檢測(cè)Linux運(yùn)行信息的工具的教程

    用Python制作檢測(cè)Linux運(yùn)行信息的工具的教程

    這篇文章主要介紹了用Python制作檢測(cè)Linux運(yùn)行信息的工具的教程,主要是用CPython讀取運(yùn)行系統(tǒng)的硬件參數(shù)、網(wǎng)絡(luò)傳輸流量統(tǒng)計(jì)等,需要的朋友可以參考下
    2015-04-04
  • Python實(shí)現(xiàn)Event回調(diào)機(jī)制的方法

    Python實(shí)現(xiàn)Event回調(diào)機(jī)制的方法

    今天小編就為大家分享一篇Python實(shí)現(xiàn)Event回調(diào)機(jī)制的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • Python getattr()函數(shù)使用方法代碼實(shí)例

    Python getattr()函數(shù)使用方法代碼實(shí)例

    這篇文章主要介紹了Python getattr()函數(shù)使用方法代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Python上下文管理器詳細(xì)使用教程

    Python上下文管理器詳細(xì)使用教程

    Python有三大神器,一個(gè)是裝飾器,一個(gè)是迭代器、生成器,最后一個(gè)就是今天文章的主角 -- 「上下文管理器」。上下文管理器在日常開發(fā)中的作用是非常大的,可能有些人用到了也沒有意識(shí)到這一點(diǎn)
    2023-02-02
  • 如何利用python 讀取配置文件

    如何利用python 讀取配置文件

    這篇文章主要介紹了如何利用python 讀取配置文件,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2021-01-01
  • Django實(shí)現(xiàn)單用戶登錄的方法示例

    Django實(shí)現(xiàn)單用戶登錄的方法示例

    這篇文章主要介紹了Django實(shí)現(xiàn)單用戶登錄的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03

最新評(píng)論

塔城市| 金湖县| 铜川市| 微山县| 武宣县| 松阳县| 波密县| 南阳市| 瓦房店市| 宣武区| 乐昌市| 赤城县| 辉县市| 靖远县| 武冈市| 藁城市| 连城县| 梅州市| 玉龙| 安吉县| 彭州市| 大厂| 珲春市| 理塘县| 德钦县| 邢台县| 井陉县| 盐边县| 芜湖市| 尼玛县| 汶上县| 商都县| 赤城县| 宜宾市| 南岸区| 四川省| 海淀区| 云阳县| 乐昌市| 监利县| 云霄县|