pytorch初始化模型参数的两种方法

    一种是采用 apply 函数,另一种是遍历 modules.

    利用 apply 方法(来自 pytorch 框架)

    1. def weights_init(m):
    2. classname = m.__class__.__name__
    3. if classname.find('Conv1d') != -1:
    4. m.weight.data.normal_(0.0, 0.02)
    5. if m.bias is not None:
    6. m.bias.data.fill_(0)
    7. elif classname.find('Conv2d') != -1:
    8. m.weight.data.normal_(0.0, 0.02)
    9. if m.bias is not None:
    10. m.bias.data.fill_(0)
    11. elif classname.find('BatchNorm') != -1:
    12. m.weight.data.normal_(1.0, 0.02)
    13. m.bias.data.fill_(0)
    14. model = Model()
    15. model.apply(weights_init)

    利用遍历
    结合 python 的 isinstance 函数(该函数和 type 函数类似),来判断算子是哪个算子(类)

    1. class Model(nn.Module):
    2. def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
    3. super().__init__()
    4. self.layer = nn.Sequential(
    5. nn.Linear(in_dim, n_hidden_1),
    6. nn.ReLU(True),
    7. nn.Linear(n_hidden_1, n_hidden_2),
    8. nn.ReLU(True),
    9. nn.Linear(n_hidden_2, out_dim),
    10. nn.Softmax(dim=1)
    11. )
    12. # init weights
    13. for m in self.modules():
    14. if isinstance(m, nn.Conv2d):
    15. nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
    16. elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
    17. nn.init.constant_(m.weight, 1)
    18. nn.init.constant_(m.bias, 0)
    19. def forward(self, x):
    20. x = self.layer(x)
    21. return x

    由于模型参数初始化的随机性、样本输入模型进行训练的训练的随机性以及随机数产生过程的随机性等,使得每次模型训练得到的效果可能都不同。那么这样来对比不同模型的性能就非常不合理。为了公平起见,往往需要设置相同的随机种子,采用相同的模型初始化方法,来对比不同模型的效果。

    所以,在设计模型,对比改进模型和改进之前的效果差异的时候,同样需要这样做。这样才能看到引入的一些操作是否有效。 下面是一种固定随机种子的方法:

    1. def setup_seed(seed):
    2. torch.manual_seed(seed)
    3. torch.cuda.manual_seed_all(seed)
    4. np.random.seed(seed)
    5. random.seed(seed)
    6. torch.backends.cudnn.deterministic = True