在Notebook中固定随机种子seed遇到的坑

在Notebook中固定随机种子seed遇到的坑

oyxy2019 263 2023-12-14

问题记录

今天在colab中遇到,明明固定了随机种子,但两次运行model初始化参数却不一致的问题,如下:

import numpy as np
import torch
import random

def same_seeds(seed):
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    if torch.cuda.is_available():
        torch.cuda.manual_seed(seed)
        torch.cuda.manual_seed_all(seed)
    torch.backends.cudnn.benchmark = False
    torch.backends.cudnn.deterministic = True

same_seeds(1314)
import torch
import torch.nn as nn

# torch.manual_seed(1314)
class MLP(nn.Module):
  def __init__(self, input_dim=3828, hidden_dim=512, output_dim=1, hidden_layers=5, dropout_rate=0.3):
    super(MLP, self).__init__()

    layerlist = []

    # First_layer
    layerlist.append(nn.Linear(input_dim, hidden_dim))
    layerlist.append(nn.ReLU())
    layerlist.append(nn.Dropout(p=dropout_rate))

    # Hidden_layers
    for _ in range(hidden_layers):
      layerlist.append(nn.Linear(hidden_dim, hidden_dim))
      layerlist.append(nn.ReLU())
      layerlist.append(nn.Dropout(p=dropout_rate))

    # Last_layer
    layerlist.append(nn.Linear(hidden_dim, output_dim))
    layerlist.append(nn.Sigmoid())

    self.model = nn.Sequential(*layerlist)

  def forward(self, x):
    return self.model(x)

model = MLP()
# Print model parameters
for name, param in model.named_parameters():
    print(f"{name}: {param}")
    break

解决方法

  • 起初我以为是固定seed后,如果二次导入torch,会导致固定种子失效,但经过实验发现并不是这样。
  • 真正原因是:在notebook中,same_seeds这个单元格我只运行了一次,后面我重复运行model这个单元格的时候,就没有再运行过固定种子这个函数了,所以在每次再实例化model = MLP()的时候,就是随机数表里的下一个随机数了!
  • 换句话说,虽然前后两次实例化MLP1和MLP2的参数不一样,但是如果重新从头开始运行,MLP1和MLP1’是一样的,MLP2和MLP2’是一样的。
  • 也就造成了same_seeds只能起一次作用的这种假象。
  • 所以要想模型的初始化参数跟之前一样:就需要重新再运行一遍same_seeds,或者在代码前再加一遍。