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

一文弄懂Pytorch的DataLoader, DataSet, Sampler之間的關(guān)系

 更新時(shí)間:2020年07月03日 09:43:43   作者:marsggbo  
這篇文章主要介紹了一文弄懂Pytorch的DataLoader, DataSet, Sampler之間的關(guān)系,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

以下內(nèi)容都是針對(duì)Pytorch 1.0-1.1介紹。

很多文章都是從Dataset等對(duì)象自下往上進(jìn)行介紹,但是對(duì)于初學(xué)者而言,其實(shí)這并不好理解,因?yàn)橛械臅r(shí)候會(huì)不自覺(jué)地陷入到一些細(xì)枝末節(jié)中去,而不能把握重點(diǎn),所以本文將會(huì)自上而下地對(duì)Pytorch數(shù)據(jù)讀取方法進(jìn)行介紹。

自上而下理解三者關(guān)系

首先我們看一下DataLoader.next的源代碼長(zhǎng)什么樣,為方便理解我只選取了num_works為0的情況(num_works簡(jiǎn)單理解就是能夠并行化地讀取數(shù)據(jù))。

class DataLoader(object):
	...
	
 def __next__(self):
  if self.num_workers == 0: 
   indices = next(self.sample_iter) # Sampler
   batch = self.collate_fn([self.dataset[i] for i in indices]) # Dataset
   if self.pin_memory:
    batch = _utils.pin_memory.pin_memory_batch(batch)
   return batch

在閱讀上面代碼前,我們可以假設(shè)我們的數(shù)據(jù)是一組圖像,每一張圖像對(duì)應(yīng)一個(gè)index,那么如果我們要讀取數(shù)據(jù)就只需要對(duì)應(yīng)的index即可,即上面代碼中的indices,而選取index的方式有多種,有按順序的,也有亂序的,所以這個(gè)工作需要Sampler完成,現(xiàn)在你不需要具體的細(xì)節(jié),后面會(huì)介紹,你只需要知道DataLoader和Sampler在這里產(chǎn)生關(guān)系。

那么Dataset和DataLoader在什么時(shí)候產(chǎn)生關(guān)系呢?沒(méi)錯(cuò)就是下面一行。我們已經(jīng)拿到了indices,那么下一步我們只需要根據(jù)index對(duì)數(shù)據(jù)進(jìn)行讀取即可了。

再下面的if語(yǔ)句的作用簡(jiǎn)單理解就是,如果pin_memory=True,那么Pytorch會(huì)采取一系列操作把數(shù)據(jù)拷貝到GPU,總之就是為了加速。

綜上可以知道DataLoader,Sampler和Dataset三者關(guān)系如下:

在閱讀后文的過(guò)程中,你始終需要將上面的關(guān)系記在心里,這樣能幫助你更好地理解。

Sampler

參數(shù)傳遞

要更加細(xì)致地理解Sampler原理,我們需要先閱讀一下DataLoader 的源代碼,如下:

class DataLoader(object):
 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)

可以看到初始化參數(shù)里有兩種sampler:samplerbatch_sampler,都默認(rèn)為None。前者的作用是生成一系列的index,而batch_sampler則是將sampler生成的indices打包分組,得到一個(gè)又一個(gè)batch的index。例如下面示例中,BatchSamplerSequentialSampler生成的index按照指定的batch size分組。

>>>in : list(BatchSampler(SequentialSampler(range(10)), batch_size=3, drop_last=False))
>>>out: [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

Pytorch中已經(jīng)實(shí)現(xiàn)的Sampler有如下幾種:

  • SequentialSampler
  • RandomSampler
  • WeightedSampler
  • SubsetRandomSampler

需要注意的是DataLoader的部分初始化參數(shù)之間存在互斥關(guān)系,這個(gè)你可以通過(guò)閱讀源碼更深地理解,這里只做總結(jié):

  • 如果你自定義了batch_sampler,那么這些參數(shù)都必須使用默認(rèn)值:batch_size, shuffle,sampler,drop_last.
  • 如果你自定義了sampler,那么shuffle需要設(shè)置為False
  • 如果sampler和batch_sampler都為None,那么batch_sampler使用Pytorch已經(jīng)實(shí)現(xiàn)好的BatchSampler,而sampler分兩種情況:
    • 若shuffle=True,則sampler=RandomSampler(dataset)
    • 若shuffle=False,則sampler=SequentialSampler(dataset)

如何自定義Sampler和BatchSampler?

仔細(xì)查看源代碼其實(shí)可以發(fā)現(xiàn),所有采樣器其實(shí)都繼承自同一個(gè)父類(lèi),即Sampler,其代碼定義如下:

class Sampler(object):
 r"""Base class for all Samplers.
 Every Sampler subclass has to provide an :meth:`__iter__` method, providing a
 way to iterate over indices of dataset elements, and a :meth:`__len__` method
 that returns the length of the returned iterators.
 .. note:: The :meth:`__len__` method isn't strictly required by
    :class:`~torch.utils.data.DataLoader`, but is expected in any
    calculation involving the length of a :class:`~torch.utils.data.DataLoader`.
 """

 def __init__(self, data_source):
  pass

 def __iter__(self):
  raise NotImplementedError
		
 def __len__(self):
  return len(self.data_source)

所以你要做的就是定義好__iter__(self)函數(shù),不過(guò)要注意的是該函數(shù)的返回值需要是可迭代的。例如SequentialSampler返回的是iter(range(len(self.data_source)))。

另外BatchSampler與其他Sampler的主要區(qū)別是它需要將Sampler作為參數(shù)進(jìn)行打包,進(jìn)而每次迭代返回以batch size為大小的index列表。也就是說(shuō)在后面的讀取數(shù)據(jù)過(guò)程中使用的都是batch sampler。

Dataset

Dataset定義方式如下:

class Dataset(object):
	def __init__(self):
		...
		
	def __getitem__(self, index):
		return ...
	
	def __len__(self):
		return ...

上面三個(gè)方法是最基本的,其中__getitem__是最主要的方法,它規(guī)定了如何讀取數(shù)據(jù)。但是它又不同于一般的方法,因?yàn)樗莗ython built-in方法,其主要作用是能讓該類(lèi)可以像list一樣通過(guò)索引值對(duì)數(shù)據(jù)進(jìn)行訪問(wèn)。假如你定義好了一個(gè)dataset,那么你可以直接通過(guò)dataset[0]來(lái)訪問(wèn)第一個(gè)數(shù)據(jù)。在此之前我一直沒(méi)弄清楚__getitem__是什么作用,所以一直不知道該怎么進(jìn)入到這個(gè)函數(shù)進(jìn)行調(diào)試?,F(xiàn)在如果你想對(duì)__getitem__方法進(jìn)行調(diào)試,你可以寫(xiě)一個(gè)for循環(huán)遍歷dataset來(lái)進(jìn)行調(diào)試了,而不用構(gòu)建dataloader等一大堆東西了,建議學(xué)會(huì)使用ipdb這個(gè)庫(kù),非常實(shí)用?。?!以后有時(shí)間再寫(xiě)一篇ipdb的使用教程。另外,其實(shí)我們通過(guò)最前面的Dataloader的__next__函數(shù)可以看到DataLoader對(duì)數(shù)據(jù)的讀取其實(shí)就是用了for循環(huán)來(lái)遍歷數(shù)據(jù),不用往上翻了,我直接復(fù)制了一遍,如下:

class DataLoader(object): 
 ... 
  
 def __next__(self): 
  if self.num_workers == 0: 
   indices = next(self.sample_iter) 
   batch = self.collate_fn([self.dataset[i] for i in indices]) # this line 
   if self.pin_memory: 
    batch = _utils.pin_memory.pin_memory_batch(batch) 
   return batch

我們仔細(xì)看可以發(fā)現(xiàn),前面還有一個(gè)self.collate_fn方法,這個(gè)是干嘛用的呢?在介紹前我們需要知道每個(gè)參數(shù)的意義:

  • indices: 表示每一個(gè)iteration,sampler返回的indices,即一個(gè)batch size大小的索引列表
  • self.dataset[i]: 前面已經(jīng)介紹了,這里就是對(duì)第i個(gè)數(shù)據(jù)進(jìn)行讀取操作,一般來(lái)說(shuō)self.dataset[i]=(img, label)

看到這不難猜出collate_fn的作用就是將一個(gè)batch的數(shù)據(jù)進(jìn)行合并操作。默認(rèn)的collate_fn是將img和label分別合并成imgs和labels,所以如果你的__getitem__方法只是返回 img, label,那么你可以使用默認(rèn)的collate_fn方法,但是如果你每次讀取的數(shù)據(jù)有img, box, label等等,那么你就需要自定義collate_fn來(lái)將對(duì)應(yīng)的數(shù)據(jù)合并成一個(gè)batch數(shù)據(jù),這樣方便后續(xù)的訓(xùn)練步驟。

到此這篇關(guān)于一文弄懂Pytorch的DataLoader, DataSet, Sampler之間的關(guān)系的文章就介紹到這了,更多相關(guān)Pytorch DataLoader DataSet Sampler內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • pip命令突然無(wú)法使用問(wèn)題以及解決

    pip命令突然無(wú)法使用問(wèn)題以及解決

    當(dāng)你在使用pip安裝Python庫(kù)時(shí)遇到問(wèn)題,可以嘗試以下兩種解決方案,第一種是直接在Scripts文件夾內(nèi)使用CMD命令進(jìn)行安裝,第二種是將Scripts的路徑設(shè)置為系統(tǒng)環(huán)境變量,這樣就可以直接在dos中使用pip install進(jìn)行安裝了,以上解決方案僅供參考,如有更好的方法歡迎交流分享
    2024-10-10
  • Python爬取網(wǎng)易云音樂(lè)熱門(mén)評(píng)論

    Python爬取網(wǎng)易云音樂(lè)熱門(mén)評(píng)論

    本文將詳細(xì)介紹了Python獲取網(wǎng)易云音樂(lè)熱門(mén)評(píng)論的實(shí)例。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-03-03
  • Pycharm連接遠(yuǎn)程mysql報(bào)錯(cuò)的實(shí)現(xiàn)

    Pycharm連接遠(yuǎn)程mysql報(bào)錯(cuò)的實(shí)現(xiàn)

    本文主要介紹了Pycharm連接遠(yuǎn)程mysql報(bào)錯(cuò)的實(shí)現(xiàn),文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • Python批量轉(zhuǎn)換文件編碼格式

    Python批量轉(zhuǎn)換文件編碼格式

    需要將工作目錄下的文件進(jìn)行轉(zhuǎn)碼,開(kāi)始的編碼是GBK的,需要將其轉(zhuǎn)換為utf-8的。文件較多,手動(dòng)轉(zhuǎn)換肯定不行,用Python寫(xiě)個(gè)腳本來(lái)實(shí)現(xiàn)。
    2015-05-05
  • Python定制類(lèi)你不知道的魔術(shù)方法

    Python定制類(lèi)你不知道的魔術(shù)方法

    你知道什么是定制類(lèi)?Python中包含很多內(nèi)置的(Built-in)函數(shù),異常,對(duì)象。分別有不同的作用,我們可以重寫(xiě)這些功能,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2022-07-07
  • Python畫(huà)圖高斯分布的示例

    Python畫(huà)圖高斯分布的示例

    今天小編就為大家分享一篇Python畫(huà)圖高斯分布的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • PyCharm2018 安裝及破解方法實(shí)現(xiàn)步驟

    PyCharm2018 安裝及破解方法實(shí)現(xiàn)步驟

    這篇文章主要介紹了PyCharm2018 安裝及破解方法實(shí)現(xiàn)步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-09-09
  • Python使用cProfile分析和定位應(yīng)用性能瓶頸點(diǎn)

    Python使用cProfile分析和定位應(yīng)用性能瓶頸點(diǎn)

    cProfile?是?Python?標(biāo)準(zhǔn)庫(kù)中的一個(gè)模塊,用于對(duì)?Python?程序進(jìn)行性能分析,它能輸出每個(gè)函數(shù)的調(diào)用次數(shù)、執(zhí)行耗時(shí)等詳細(xì)信息,下面我們來(lái)看看如何使用cProfile分析和定位應(yīng)用性能瓶頸點(diǎn)吧
    2024-12-12
  • 用Python每天自動(dòng)給女友免費(fèi)發(fā)短信

    用Python每天自動(dòng)給女友免費(fèi)發(fā)短信

    大家好,本篇文章主要講的是用Python每天自動(dòng)給女友免費(fèi)發(fā)短信,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Python利用flask操作Redis的方法詳解

    Python利用flask操作Redis的方法詳解

    這篇文章主要為大家詳細(xì)介紹了Python如何利用flask操作Redis,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定的幫助,需要的可以參考一下
    2023-02-02

最新評(píng)論

宁陕县| 信丰县| 恭城| 泸西县| 保山市| 杂多县| 嵊泗县| 古浪县| 青冈县| 池州市| 宁都县| 平武县| 锦屏县| 韶山市| 资阳市| 建昌县| 报价| 台州市| 辽阳市| 工布江达县| 巫溪县| 宾阳县| 庄河市| 珠海市| 金坛市| 龙里县| 秀山| 上林县| 临海市| 邛崃市| 二手房| 六安市| 临湘市| 南郑县| 武平县| 芒康县| 车险| 丰顺县| 澎湖县| 西城区| 冀州市|