由於在模型訓練的過程中存在大量的隨機操作,使得對於同乙份**,重複執行後得到的結果不一致。因此,為了得到可重複的實驗結果,我們需要對隨機數生成器設定乙個固定的種子。
許多部落格都有介紹如何解決這個問題,但是很多都不夠全面,往往不能保證結果精確一致。我經過許多調研和實驗,總結了以下方法,記錄下來。
全部設定可以分為三部分:
from torch.backends import cudnn
cudnn.benchmark =
false
# if benchmark=true, deterministic will be false
cudnn.deterministic =
true
不過實際上這個設定對精度影響不大,僅僅是小數點後幾位的差別。所以如果不是對精度要求極高,其實不太建議修改,因為會使計算效率降低。
torch.manual_seed(seed)
# 為cpu設定隨機種子
torch.cuda.manual_seed(seed)
# 為當前gpu設定隨機種子
torch.cuda.manual_seed_all(seed)
# 為所有gpu設定隨機種子
如果讀取資料的過程採用了隨機預處理(如randomcrop、randomhorizontalflip等),那麼對python、numpy的隨機數生成器也需要設定種子。
import random
import numpy as np
random.seed(seed)
np.random.seed(seed)
最後,關於dataloader:
注意,如果dataloader採用了多執行緒(num_workers > 1), 那麼由於讀取資料的順序不同,最終執行結果也會有差異。也就是說,改變num_workers引數,也會對實驗結果產生影響。目前暫時沒有發現解決這個問題的方法,但是只要固定num_workers數目(執行緒數)不變,基本上也能夠重複實驗結果。
global_seed =
1def
set_seed
(seed)
: random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
global_worker_id =
none
defworker_init_fn
(worker_id)
:global global_worker_id
global_worker_id = worker_id
set_seed(global_seed + worker_id)
dataloader = dataloader(dataset, batch_size=
16, shuffle=
true
, num_workers=
2, worker_init_fn=worker_init_fn)
pytorch 保證實驗的可重複性
如何讓每次實驗執行後得到的結果都一致?可以通過將以下設定放在 import 後,正式 前 np.random.seed 0 random.seed 0 torch.manual seed 0 torch.cuda.manual seed 0 torch.backends.cudnn.determin...
Windows EFS驗證實驗
在 windows 環境下,利用 efs 服務實現或驗證以下功能 1.使用 efs 既可加密檔案,也可加密資料夾 2.efs 加密位於檔案系統層,加解密效率高 3.帳戶 a 進行 efs 加密的檔案無法用帳戶 b 開啟,除非設定共享 4.帳戶 a 進行 efs 加密的資料夾無法用帳戶 b 開啟,除非...
Windows EFS驗證實驗
在windows 環境下,利用efs 服務實現或驗證以下功能 1.使用efs 既可加密檔案,也可加密資料夾 2.efs 加密位於檔案系統層,加解密效率高 3.帳戶a 進行efs 加密的檔案無法用帳戶b 開啟,除非設定共享 4.帳戶a 進行efs 加密的資料夾無法用帳戶b 開啟,除非設定共享 5.只有...