一般而言,可以按照如下方式固定隨機數種子,以便復現實驗:
# 來自相關於 GCN 代碼: 例如 grand.py 等的代碼
parser.add_argument('--seed', type=int, default=42, help='Random seed.')
np.random.seed(args.seed)
torch.manual_seed(args.seed)
if args.cuda:
torch.cuda.manual_seed(args.seed)
# 自己之前所寫的 noisy label 的代碼,參照某一篇 blog
def seed_torch(seed=0):
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
即使設置了隨機數種子, 當改寫了幾行代碼 ,即使期望實現功能完全相同,但也可能無法復現原來的結果
原因在於:隨機數是順序生成的,如果中間被額外的步驟多調用了一次隨機數生成器,就會導致最終的結果完全不同。
例如:優化 \(loss1+\lambda\times loss2\)
假定 \(loss1\)的計算過程要用到隨機數, 若在 \(loss2\) 的計算過程中也要調用了隨機數發生器,則會打亂先前供計算 \(loss1\) 使用的隨機數列,導致如下兩種情況最終結果不同:
- case 1: 僅優化 \(loss1\),不計算 \(loss2\)
- case 2: 優化 \(loss1+0.0\times loss2\) (這里設置 \(loss2\) 項前的參數 \(\lambda\) 為 \(0.0\), 也即沒有參與最終的優化。)
python 在主函數中設置隨機數種子,似乎也可以將子函數 or 其他被主函數調用的隨機模塊給固定下來。https://www.cnblogs.com/yongjieShi/p/9594349.html