You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch中#1与#2代码的区别及优化器设置相关疑问

PyTorch迁移学习代码疑问解答

原代码片段

model_conv = torchvision.models.resnet18(pretrained=True)
for param in model_conv.parameters():  # 1
    param.requires_grad = False        # 1

# Parameters of newly constructed modules have requires_grad=True by default
num_ftrs = model_conv.fc.in_features
model_conv.fc = nn.Linear(num_ftrs, 2)

model_conv = model_conv.to(device)

criterion = nn.CrossEntropyLoss()

# Observe that only parameters of final layer are being optimized as
# opposed to before.
optimizer_conv = optim.SGD(model_conv.fc.parameters(), lr=0.001, momentum=0.9)  # 2

# Decay LR by a factor of 0.1 every 7 epochs
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_conv, step_size=7, gamma=0.1)

问题解答

1. #1和#2部分的区别

  • #1段代码是冻结预训练模型的所有参数:遍历ResNet18的全部参数,将它们的requires_grad设为False,反向传播时这些参数不会被更新,相当于固定住预训练阶段学到的特征提取能力。
  • #2段代码是仅针对最后一层全连接层(fc)创建优化器:明确指定优化器只优化替换后的新fc层参数,因为前面的特征层已经被冻结,无需纳入优化范围。

两者配合实现的是「固定特征提取层、仅训练分类头」的轻量迁移学习模式。

2. 设置#1后,能否把#2改成optimizer_ft = optim.SGD(model_ft.parameters(), lr=1e-3, momentum=0.9, weight_decay=0.1)?

可以,但完全没必要,还会浪费计算资源:

  • 因为#1已经把旧层参数的requires_grad设为False,即便把整个模型参数传给优化器,PyTorch会自动忽略这些无梯度更新需求的参数,最终还是只优化新fc层。
  • 直接传整个模型参数的话,优化器会遍历所有参数做一次筛选,效率不如直接指定model_conv.fc.parameters()。另外注意变量名要对应,原代码用的是model_conv,你写的model_ft属于笔误,需要修正。

3. 删除#1只保留#2是否可行?

代码能跑,但属于不合理操作:

  • 删除#1后,原预训练层的requires_grad默认是True,但优化器只优化fc层,反向传播时会计算所有层的梯度,却只更新fc层参数——这会做大量无用的梯度计算,拖慢训练速度。
  • 如果想做全模型微调(所有参数都更新),应该删除#1,同时把优化器改成optim.SGD(model_conv.parameters(), ...);如果还是只想训练fc层,保留#1才是正确的做法,能避免无意义的梯度计算。

内容的提问来源于stack exchange,提问作者yy G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 12:00:21