<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【深度學(xué)習(xí)】PyTorch 數(shù)據(jù)集隨機(jī)值的完美實(shí)踐

          共 4178字,需瀏覽 9分鐘

           ·

          2021-09-13 22:59

            作者 | Elvanth@知乎
          來(lái)源 | https://zhuanlan.zhihu.com/p/377155682
          編輯 | 極市平臺(tái)
          本文僅作學(xué)術(shù)交流,版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系刪除。

          導(dǎo)讀

           

          本文所分析的問(wèn)題與解決方案將在最近發(fā)布的pytorch版本中解決;因此解決所有煩惱的根源是方法,更新pytorch~ >>

          一個(gè)快捷的解決方案:

          def worker_init_fn(worker_id):
          worker_seed = torch.initial_seed() % 2**32
          np.random.seed(worker_seed)
          random.seed(worker_seed)

          ds = DataLoader(ds, 10, shuffle=False, num_workers=4, worker_init_fn=worker_init_fn)

          01 關(guān)于pytorch數(shù)據(jù)集隨機(jī)種子的基本認(rèn)識(shí)

          在pytorch中random、torch.random等隨機(jī)值產(chǎn)生方法一般沒(méi)有問(wèn)題,只有少數(shù)工人運(yùn)行也可以保障其不同的最終值.

          np.random.seed 會(huì)出現(xiàn)問(wèn)題的原因是,當(dāng)多處理采用 fork 方式產(chǎn)生子進(jìn)程時(shí),numpy 不會(huì)對(duì)不同的子進(jìn)程產(chǎn)生不同的隨機(jī)值.

          換言之,當(dāng)沒(méi)有多處理使用時(shí),numpy 不會(huì)出現(xiàn)隨機(jī)種子的不同的問(wèn)題;實(shí)驗(yàn)代碼的可復(fù)現(xiàn)性要求一個(gè)是工人種子 ,即工人內(nèi)包括numpy,random,torch.random所有的隨機(jī)表現(xiàn);另一個(gè)是Base ,即程序運(yùn)行后的初始隨機(jī)值,其可以通過(guò)以下兩種方式產(chǎn)生

          1. torch.manual_seed(base_seed)

          2. 由特定的seed generator設(shè)置

          generator = torch. Generator()
          g.manual_seed(base_seed)
          DataLoader(dataset, ..., generator=generator)

          使用spawn模式可以斬?cái)嘁陨纤袩?

          02 直接在網(wǎng)上搜這個(gè)問(wèn)題會(huì)得到什么答案

          參考很多的解決方案時(shí),往往會(huì)提出以下功能:

          def worker_init_fn(worker_id):
          np.random.seed(np.random.get_state()[1][0] + worker_id)

          讓我們看看它的輸出結(jié)果:
          (第0,3列是索引,第1,4列是np.random的結(jié)果,第2,5列是random.randint的結(jié)果)

          epoch 0
          tensor([[ 0, 5125, 13588, 0, 15905, 23182],
          [ 1, 7204, 19825, 0, 13653, 25225]])
          tensor([[ 2, 1709, 11504, 0, 12842, 23238],
          [ 3, 5715, 14058, 0, 15236, 28033]])
          tensor([[ 4, 1062, 11239, 0, 10142, 29869],
          [ 5, 6574, 15672, 0, 19623, 25600]])
          ============================================================
          epoch 1
          tensor([[ 0, 5125, 18134, 0, 15905, 28990],
          [ 1, 7204, 13206, 0, 13653, 25106]])
          tensor([[ 2, 1709, 15512, 0, 12842, 29703],
          [ 3, 5715, 14201, 0, 15236, 27696]])
          tensor([[ 4, 1062, 13994, 0, 10142, 23411],
          [ 5, 6574, 18532, 0, 19623, 21744]])
          ============================================================

          假設(shè)上述方案對(duì)一個(gè)時(shí)代內(nèi)可以防止不同的工人出現(xiàn)隨機(jī)值相同的情況,但不同的時(shí)代之間,其最終的隨機(jī)種子仍然是不變的。

          03 那應(yīng)該如何解決

          來(lái)自pytorch官方的解決方案:

          https://github.com/pytorch/pytorch/pull/56488#issuecomment-825128350

          def worker_init_fn(worker_id):
          worker_seed = torch.initial_seed() % 2**32
          np.random.seed(worker_seed)
          random.seed(worker_seed)

          ds = DataLoader(ds, 10, shuffle=False, num_workers=4, worker_init_fn=worker_init_fn)

          來(lái)自numpy.random原作者的解決方案:

          https://github.com/pytorch/pytorch/issues/5059#issuecomment-817392562

          def worker_init_fn(id):
          process_seed = torch.initial_seed()
          # Back out the base_seed so we can use all the bits.
          base_seed = process_seed - id
          ss = np.random.SeedSequence([id, base_seed])
          # More than 128 bits (4 32-bit words) would be overkill.
          np.random.seed(ss.generate_state(4))

          ds = DataLoader(ds, 10, shuffle=False, num_workers=4, worker_init_fn=worker_init_fn)

          一個(gè)更簡(jiǎn)單但不保證正確性的解決方案:

          def worker_init_fn(worker_id):
          np.random.seed((worker_id + torch.initial_seed()) % np.iinfo(np.int32).max)

          ds = DataLoader(ds, 10, shuffle=False, num_workers=4, worker_init_fn=worker_init_fn)

          04 附上可運(yùn)行的完整文件

          import numpy as np
          import random
          import torch

          # np.random.seed(0)

          class Transform(object):
          def __init__(self):
          pass

          def __call__(self, item = None):
          return [np.random.randint(10000, 20000), random.randint(20000,30000)]

          class RandomDataset(object):
          def __init__(self):
          pass

          def __getitem__(self, ind):
          item = [ind, np.random.randint(1, 10000), random.randint(10000, 20000), 0]
          tsfm =Transform()(item)
          return np.array(item + tsfm)
          def __len__(self):
          return 20

          from torch.utils.data import DataLoader

          def worker_init_fn(worker_id):
          np.random.seed(np.random.get_state()[1][0] + worker_id)

          ds = RandomDataset()
          ds = DataLoader(ds, 10, shuffle=False, num_workers=4, worker_init_fn=worker_init_fn)

          for epoch in range(2):
          print("epoch {}".format(epoch))
          np.random.seed()
          for batch in ds:
                  print(batch)

          如果覺(jué)得有用,就請(qǐng)分享到朋友圈吧!

          往期精彩回顧




          本站qq群851320808,加入微信群請(qǐng)掃碼:
          瀏覽 85
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  超碰在线看不卡了 | 欧美大屌网站 | 97人人操人人操 | 久久久春色 | 亚洲美国日本中文字幕 |