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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PyTorch固定随机数种子

發布時間:2023/12/31 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PyTorch固定随机数种子 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載請注明作者和出處: http://blog.csdn.net/john_bh/

文章目錄

    • 1. 訓練過程
    • 2. 測試過程
    • 3. 代碼隨機種子的設定
    • 4. 參考鏈接

在神經網絡中,參數默認是進行隨機初始化的。不同的初始化參數往往會導致不同的結果。當得到比較好的結果時我們通常希望這個結果是可以復現的,在PyTorch中,通過設置全局隨機數種子可以實現這個目的。本文總結了PyTorch中固定隨機種子的方法。

1. 訓練過程

在訓練過程中,若相同的數據數據集,相同的訓練集、測試集劃分方式,相同的權重初始化,但是每次訓練結果不同,可能有以下幾個原因:

  • Dropout的存在 ;
  • PyTorch、Python、Numpy中的隨機種子沒有固定;
  • 數據預處理、增強方式采用了概率,若沒有設置固定的隨機種子,結果可能不同。例如常用數據增強庫albumentations就采用了Python的隨機產生器;
  • 訓練數據集被隨機打亂了順序;
  • 向上采樣和插值函數/類的向后是不確定的(PyTorch的問題)

舉個例子:

import numpy as npdef no_set_seed():n = 0while (n < 3):n += 1print(np.random.random())def set_seed():n = 0while (n < 3):np.random.seed(5)n += 1print(np.random.random())if __name__=="__main__":print(" ***** no set seed result ***** ")no_set_seed()print(" ***** set seed result ***** ")set_seed()

輸出:

***** no set seed result *****
0.7831834888867475
0.919347615336164
0.9437836768670717
***** set seed result *****
0.22199317108973948
0.22199317108973948
0.22199317108973948

當我們設定一個隨機種子時,那么關于隨機數的選取就確定了。

另外,在PyTorch官方文檔中說明了在Pytorch的不同提交、不同版本和不同平臺上,不能保證完全可重現的結果。此外,即使使用相同的種子,因為存在不同的CPU和GPU,結果也不能重現。

但是對于一個特定的平臺和PyTorch發行版上對您的特定問題進行確定性的計算,需要采取幾個步驟。在can’t reproduce results even set all random seeds給出了解決方式。

其中包括:

  • 設置cuDNN:cudnn中對卷積操作進行了優化,犧牲了精度來換取計算效率。如果需要保證可重復性,可以使用如下設置:torch.backends.cudnn.benchmark = False torch.backends.cudnn.deterministic = True 不過實際上這個設置對精度影響不大,僅僅是小數點后幾位的差別。所以如果不是對精度要求極高,其實不太建議修改,因為會使計算效率降低。
  • 對PyTorch設置隨機種子;
  • 對Python & NumPy設置隨機種子:如果讀取數據的過程采用了隨機預處理(如RandomCrop、RandomHorizontalFlip等),那么對python、numpy的隨機數生成器也需要設置種子;
  • 對dataloader設置隨機種子:如果dataloader采用了多線程(num_workers > 1), 那么由于讀取數據的順序不同,最終運行結果也會有差異。也就是說,改變num_workers參數,也會對實驗結果產生影響。目前暫時沒有發現解決這個問題的方法,但是只要固定num_workers數目(線程數)不變,基本上也能夠重復實驗結果。對于不同線程的隨機數種子設置,主要通過DataLoader的worker_init_fn參數來實現。默認情況下使用線程ID作為隨機數種子。
  • 參考can’t reproduce results even set all random seeds#7068(comment1),建議采用下面方式解決:在運行任何程序之前寫入下面代碼(可以放在主代碼的開頭,在導入模塊之后):torch.manual_seed(seed) # 為CPU設置隨機種子 torch.cuda.manual_seed(seed) # 為當前GPU設置隨機種子 torch.cuda.manual_seed_all(seed) # if you are using multi-GPU,為所有GPU設置隨機種子 np.random.seed(seed) # Numpy module. random.seed(seed) # Python random module. torch.backends.cudnn.benchmark = False torch.backends.cudnn.deterministic = True 將它封裝一個函數,參考can’t reproduce results even set all random seeds#7068 (comment2),代碼如下:def seed_torch(seed=1029):random.seed(seed)os.environ['PYTHONHASHSEED'] = str(seed) # 為了禁止hash隨機化,使得實驗可復現np.random.seed(seed)torch.manual_seed(seed)torch.cuda.manual_seed(seed)torch.cuda.manual_seed_all(seed) # if you are using multi-GPU.torch.backends.cudnn.benchmark = Falsetorch.backends.cudnn.deterministic = Trueseed_torch()
  • 在PyTorch的DataLoader函數中填入為不同的work設置初始化函數,確保您的dataloader在每次調用時都以相同的順序加載樣本(隨機種子固定時)。如果進行裁剪或其他預處理步驟,請確保它們是確定性的。(這樣的模塊可以提供確定性結果(在Pytorch 1.0.0甚至在此版本之前))def _init_fn(worker_id):np.random.seed(int(seed)+worker_id) trainloader = DataLoader(trainset, batch_size=batch_size, shuffle=True, num_workers=num_workers, pin_memory=True, worker_init_fn=_init_fn)
  • 向上采樣和插值函數/類的向后是不確定的(BACKWARD of upsampling and interpolation functionals/classes is non-deterministic)。這意味著,如果你在訓練圖中使用這樣的模塊,無論你做什么,都永遠不會得到確定性的結果。torch.nn.ConvTranspose2d函數是不確定的,除非你使用torch.backends.cudnn.deterministic = True(原文中說you can try to make the operation deterministic … by setting torch.backends.cudnn.deterministic = True,所以這樣做是否能夠得到正確結果也是待定的)。
  • 2. 測試過程

    在測試過程中,相同的權重,相同的測試數據集,結果不同,可能有以下幾個原因:

    • 未設定eval()模式,因為模型中的Dropout和Batchnorm存在,導致結果不固定;
    • PyTorch、Python、Numpy中的隨機種子沒有固定,可能運行時依賴的一些第三方庫;
    • 有隨機性 數據預處理方式中含有概率;
    • 向上采樣和插值函數/類的向后是不確定的(Pytorch的問題)

    隨機種子的設定和訓練中的設置類似,可參考第一節內容。

    3. 代碼隨機種子的設定

    有的時候,不同的隨機種子對應的神經網絡結果不同,我們并不想固定隨機種子,使其能夠搜索最優結果。但是又想能夠根據復現最優結果,所以我們需要每次運行代碼都根據當前時間設定不同的隨機種子,并將隨機種子保存下來。

    可以使用下面代碼產生隨機種子,用于固定Pytorch、Python、Numpy中的隨機種子,你可以將這個值保存到特定的文件中,用于之后使用。

    seed = int(time.time() * 256)

    4. 參考鏈接

  • Pytorch隨機種子
  • 數據增強庫albumentations
  • Python的隨機產生器
  • can’t reproduce results even set all random seeds
  • can’t reproduce results even set all random seeds#7068(comment1)
  • can’t reproduce results even set all random seeds#7068 (comment2)
  • 總結

    以上是生活随笔為你收集整理的PyTorch固定随机数种子的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。