先初始化优化器后修改模型最后层,是否需重新初始化?最佳实践探讨
问题解答
核心结论
必须重新初始化优化器,否则新替换的最后一层(cnn.fc)不会被优化器更新,导致这层参数始终处于随机初始化状态,无法参与训练。
原因分析
你当前代码中,优化器是在模型结构修改前定义的,此时优化器仅注册了原ResNet18的所有参数(包括初始的全连接层fc)。当你在main函数里替换cnn.fc后,新的全连接层参数并未被加入到优化器的参数列表中,后续训练时优化器只会更新原来的参数,新的fc层完全得不到训练。
最佳实践
正确流程是:先完成模型的所有结构修改(比如替换最后一层),再初始化优化器,确保优化器能准确包含所有需要训练的模型参数。
修改后的代码示例:
batch_size = 8 learning_rate = 2e-4 num_epochs = 100 # 先初始化模型,暂不定义优化器 cnn = models.resnet18(weights='DEFAULT') loss_func = nn.CrossEntropyLoss() def main(): dataset = datasets.ImageFolder(root=mydir) loader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=True) num_classes = len(dataset.classes) num_ftrs = cnn.fc.in_features # 完成模型最后一层的修改 cnn.fc = nn.Linear(num_ftrs, num_classes) # 模型修改完成后,初始化优化器 optimizer = optim.Adam(cnn.parameters(), lr=learning_rate) # 后续训练逻辑... if __name__ == '__main__': main()
如果有冻结预训练特征层的需求,也可以仅让优化器更新新替换的最后一层参数,示例如下:
# 冻结特征提取层的所有参数 for param in cnn.parameters(): param.requires_grad = False # 解冻新的全连接层参数 cnn.fc.requires_grad = True # 仅优化新的全连接层参数 optimizer = optim.Adam(cnn.fc.parameters(), lr=learning_rate)
内容的提问来源于stack exchange,提问作者user16971617
相关产品推荐
相关产品推荐

