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

PyTorch冻结EfficientNet层设置requires_grad=False报RuntimeError

问题原因
  • torchvision实现的EfficientNet系列模型,最终分类层的属性名是classifier而非传统ResNet所用的fc,你代码中新增的fc层完全没有接入模型的前向计算路径,没有参与任何运算。
  • 你设置的替换层输入维度512也是错误的,EfficientNet-B0经过特征提取后的输出通道数为1280。
  • 由于实际参与前向计算的所有层都被你设置为requires_grad=False,计算图中没有任何需要求梯度的张量,反向传播时就会抛出你看到的RuntimeError。
修正方案

直接调整层替换逻辑和优化器参数传入范围即可,训练循环代码无需修改,修正后的完整实现如下:

from torchvision.models import efficientnet_b0
from torch import nn
from torch import optim

efficientnet_b0_fine = efficientnet_b0(pretrained=True)

# 冻结所有预训练骨干网络参数
for param in efficientnet_b0_fine.parameters():
    param.requires_grad = False

# 正确替换分类头:classifier是包含Dropout和Linear的序列结构,索引1对应最终全连接层
efficientnet_b0_fine.classifier[1] = nn.Linear(1280, 10)

# 优化器仅传入需要训练的分类头参数,避免加载无梯度的冗余参数
optimizer = optim.Adam(efficientnet_b0_fine.classifier.parameters(), lr=0.0001)

loss_function = nn.CrossEntropyLoss()

training(net=efficientnet_b0_fine, n_epochs=epochs, optimizer=optimizer, loss_function=loss_function, train_dl = train_dl)
补充说明
  • 如果后续需要做更深层的微调,可以逐层解冻需要训练的骨干网络层,将对应层的requires_grad设为True,同时把这部分参数加入优化器的参数列表即可。
  • 若要验证可训练参数是否符合预期,可以执行如下代码打印所有会被更新的参数名:
    for name, param in efficientnet_b0_fine.named_parameters():
        if param.requires_grad:
            print(name)
    
    正常冻结骨干仅训练分类头的场景下,输出只会包含classifier.1.weight和classifier.1.bias两项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 07:31:27