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

运行ResNet预训练模型提取特征时出现register_forward_hook属性报错求解决

错误原因定位

你遇到的'NoneType' object has no attribute 'register_forward_hook'错误的直接原因是layer = model._modules.get('avgpool')返回了None值。_modules.get()当找不到对应命名的层时会返回None而不是报错,导致你后续对None调用hook方法触发异常。
出现这个问题的核心是你使用的第三方resnet50_ft_dag自定义模型的avgpool层没有放在模型最顶层,或者层的命名不是avgpool。你可以先执行print(model)打印完整模型结构,确认avgpool层的层级路径和实际命名。
比如如果avgpool是嵌套在features子模块下,就需要修改层获取的代码为:

# 按实际层级修改,优先用属性访问而不是_modules.get
layer = model.features.avgpool
现有代码的其他修复点
  • 弃用的API替换:transforms.Scale已经被PyTorch弃用,替换为transforms.Resize
  • 移除冗余的Variable调用:PyTorch 0.4之后已经不需要用Variable封装张量,直接用原生张量即可
  • 新增torch.no_grad()上下文:关闭梯度计算可以大幅降低内存占用、提升推理速度
  • 缺失的变量定义:你调用get_vector时用到的list_dir没有定义,需要先补充目录读取代码:
    list_dir = os.listdir('C:/Users/Public/Documents/DIN_Image/average_images/')
    
  • 新增图像通道校验:调用Image.open后加.convert('RGB'),避免灰度图、RGBA图后续处理报错
更优的特征提取方案

不需要手动写hook就能实现稳定的特征提取,推荐以下两种更易维护的方案:

方案1:截断模型去掉分类头

直接去掉模型最后的全连接分类层,前向传播直接返回avgpool的输出:

# 截断模型,保留到avgpool层为止
feature_extractor = nn.Sequential(*list(model.children())[:-1])
feature_extractor.eval()
# 有GPU的话可以执行 feature_extractor = feature_extractor.cuda()

# 特征提取函数
def get_vector(image_path):
    img = Image.open(image_path).convert('RGB')
    # 预处理合并为Compose更易维护
    transform = transforms.Compose([
        transforms.Resize((224, 224)),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.485, 0.456, 0.406],
                            std=[0.229, 0.224, 0.225])
    ])
    t_img = transform(img).unsqueeze(0)
    # 有GPU的话加 t_img = t_img.cuda()
    with torch.no_grad():
        feature = feature_extractor(t_img).flatten()
    return feature.cpu().numpy() # 可以直接转numpy数组供后续使用

方案2:用官方特征提取接口(适配嵌套层结构)

如果模型层嵌套很深、不好截断,可以用PyTorch官方的特征提取工具:

from torchvision.models.feature_extraction import get_graph_node_names, create_feature_extractor

# 先打印所有推理阶段的节点名,找到avgpool对应的实际节点名
train_nodes, eval_nodes = get_graph_node_names(model)
print(eval_nodes)

# 替换下面的'avgpool'为你找到的实际节点名
feature_extractor = create_feature_extractor(model, return_nodes=['avgpool'])
feature_extractor.eval()

def get_vector(image_path):
    img = Image.open(image_path).convert('RGB')
    transform = transforms.Compose([
        transforms.Resize((224, 224)),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.485, 0.456, 0.406],
                            std=[0.229, 0.224, 0.225])
    ])
    t_img = transform(img).unsqueeze(0)
    with torch.no_grad():
        out = feature_extractor(t_img)
        feature = out['avgpool'].flatten()
    return feature.cpu().numpy()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:06:04