模型初始化与随机种子——Pytorch 炼丹技巧(随手记)

在模型类的__init__()函数中用nn.Linear(input_size,output_size)定义全连接层或者用nn.conv()定义卷积层时,默认使用kaiming_uniform对这些参数初始化。要注意的是,默认情况下,网络参数随机初始化导致的结果就是每次训练开始时(指model = Model()这一步),初始化后的模型的 初始参数是不一样的,这就给我们自己训练带来了随机性。
所以我们可以通过设置固定的随机种子来保证每次训练开始时的网络初始化参数是保持一致的,下面会说明。
首先是自定义初始化,参考这个:https://www.jianshu.com/p/f97791393439
自定义初始化:
可以用 apply()函数初始化,可选用pytorch提供的多种初始化函数,apply函数会递归地搜索网络内的所有module并把参数表示的函数应用到所有的module上。
多种初始化函数:

torch.nn.init.constant(tensor, val)
torch.nn.init.normal(tensor, mean=0, std=1)
torch.nn.init.xavier_uniform(tensor, gain=1)
kaiming_uniform_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
作者:人生一场梦163
def weights_init(m):
    classname=m.__class__.__name__
    if classname.find('Conv') != -1:
        xavier(m.weight.data)
        xavier(m.bias.data)
net = Net()
net.apply(weights_init)
def weights_init(m):
    if isinstance(m, nn.Conv2d):
        xavier(m.weight.data)
        xavier(m.bias.data)

设置固定随机种子来确保每次训练时的初始化参数是一样的
我们在复现文章,或者重复进行实验的时候,可以考虑固定随机种子。有以下几种做法:
这个随机种子不仅可以让网络参数初始化方式一致,dataloader生成的随机index也可能一致(这个我没有验证,但我用sklearn里的交叉验证模块时生成的index确实是一致的)。

seed = 1
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
np.random.seed(seed)
random.seed(seed)

torch.backends.cudnn.deterministic = True

torch.backends.cudnn.benchmark = False

我用交叉验证来在自己的数据集上做分类实验时,为了保证每一折的分类模型的初始化参数一致,尝试了用torch.manual_seed(seed),但我发现在同一个程序运行期间,多次创建模型时它们的初始化参数还是不同的!


model_list = []
for i in range(4):
    model_list.append(Model().to(device))

这样返回的4个模型两两之间初始化参数是不同的,但是当我两次运行这个程序,这两次所产生的model_list中的模型初始化参数是一致的,所以随机种子是 保证多次运行整个程序时每次的初始化参数一致!

Original: https://blog.csdn.net/qq_43679439/article/details/125134408
Author: WWwicky
Title: 模型初始化与随机种子——Pytorch 炼丹技巧(随手记)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/708501/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球