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

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) #apply函数会递归地搜索网络内的所有module并把参数表示的函数应用到所有的module上。   
def weights_init(m):
    if isinstance(m, nn.Conv2d):
        xavier(m.weight.data)
        xavier(m.bias.data)     

*Reference:Pytorch参数初始化–默认与自定义

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

seed = 1#seed必须是int,可以自行设置
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)#让显卡产生的随机数一致
torch.cuda.manual_seed_all(seed)#多卡模式下,让所有显卡生成的随机数一致?这个待验证
np.random.seed(seed)#numpy产生的随机数一致
random.seed(seed)

# CUDA中的一些运算,如对sparse的CUDA张量与dense的CUDA张量调用torch.bmm(),它通常使用不确定性算法。
# 为了避免这种情况,就要将这个flag设置为True,让它使用确定的实现。
torch.backends.cudnn.deterministic = True

# 设置这个flag可以让内置的cuDNN的auto-tuner自动寻找最适合当前配置的高效算法,来达到优化运行效率的问题。
# 但是由于噪声和不同的硬件条件,即使是同一台机器,benchmark都可能会选择不同的算法。为了消除这个随机性,设置为 False
torch.backends.cudnn.benchmark = False

*例子&参考:[pytorch 随机种子设置以及模型比对]*

注意

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

#提前定义好了Model类
model_list = []
for i in range(4):
	model_list.append(Model().to(device))

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

你可能感兴趣的:(Pytorch炼丹技巧,pytorch,深度学习,人工智能)