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

自定义Detectron2实例分割模型转框架后推理无检测结果问题

解决Detectron2模型转OpenVINO/TorchScript后无检测结果的思路

1. 对齐输入预处理逻辑

原生DefaultPredictor会自动完成图像归一化、尺寸调整、通道转换等预处理,导出后的模型需要完全复现这些步骤,否则会导致特征不匹配:

  • 确认均值/方差与训练一致:Detectron2默认用[103.53, 116.28, 123.675](BGR顺序),如果自定义过,导出后必须同步处理
  • 保持尺寸调整逻辑:原生用ResizeShortestEdge,不要随意改成固定尺寸
  • 通道顺序:原生是BGR,避免误转成RGB

手动复现预处理的示例代码:

from detectron2.data.transforms import ResizeShortestEdge, apply_transform_gens
import torch

# 加载配置
cfg = get_cfg()
cfg.merge_from_file(config_path)
# 复用原生推理的预处理配置
transform_gen = ResizeShortestEdge(
    [cfg.INPUT.MIN_SIZE_TEST, cfg.INPUT.MIN_SIZE_TEST], cfg.INPUT.MAX_SIZE_TEST
)
# 处理图像
image_transformed = apply_transform_gens([transform_gen], im)[0]
# 转换为模型输入格式:CHW Tensor,减去均值/除以方差
input_tensor = torch.as_tensor(image_transformed.astype("float32").transpose(2, 0, 1))
input_tensor -= torch.tensor(cfg.MODEL.PIXEL_MEAN).view(3, 1, 1)
input_tensor /= torch.tensor(cfg.MODEL.PIXEL_STD).view(3, 1, 1)
# 添加batch维度
sample_input = input_tensor.unsqueeze(0)

2. 同步导出与推理的模型配置

导出时必须确保模型的关键参数和原生推理完全一致:

  • 用OpenVINO转换前,先正确加载配置再构建模型:
    cfg = get_cfg()
    cfg.merge_from_file(config_path)
    cfg.MODEL.WEIGHTS = weights_path
    cfg.MODEL.ROI_HEADS.NUM_CLASSES = 1
    cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.7
    cfg.MODEL.DEVICE='cpu'
    
    model = build_model(cfg)
    DetectionCheckpointer(model).load(cfg.MODEL.WEIGHTS)
    model.eval()
    
  • 用官方导出工具时,在命令行追加自定义配置:
    python ../detectron2-main/tools/deploy/export_model.py \
      --config-file ../detectron2-main/configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml \
      --output torchscript_model \
      --format torchscript \
      --sample-image ../data/test.JPG \
      --export-method tracing \
      MODEL.DEVICE cpu \
      MODEL.WEIGHTS ../model/custom_trained_model.pth \
      MODEL.ROI_HEADS.NUM_CLASSES 1 \
      MODEL.ROI_HEADS.SCORE_THRESH_TEST 0.7
    

3. 补全后处理步骤

原生DefaultPredictor会自动执行阈值过滤、mask resize等后处理,但导出模型(尤其是用do_postprocess=False时)仅返回原始输出,需要手动补全:

from detectron2.structures import Boxes, Instances, BitMasks

# 以OpenVINO输出为例,假设输出顺序为boxes, classes, masks, scores, image_size
boxes = torch.tensor(results[0])
scores = torch.tensor(results[3])
masks = torch.tensor(results[2])
image_size = tuple(results[4])

# 过滤低置信度实例
keep = scores > cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST
boxes = boxes[keep]
scores = scores[keep]
masks = masks[keep]

# 构建Instances对象并调整mask尺寸
instances = Instances(image_size)
instances.pred_boxes = Boxes(boxes)
instances.scores = scores
instances.pred_classes = torch.tensor(results[1])[keep]
instances.pred_masks = BitMasks(masks).resize(image_size).tensor

4. 验证导出样本的有效性

导出TorchScript/OpenVINO时使用的sample_input必须是包含目标实例的有效图像,如果用无目标图像做tracing,模型可能会被错误优化掉检测分支。同时要确保样本的形状、数据类型和原生推理完全一致。

5. 对比导出前后的原始输出

在导出前先获取原生模型的原始输出,再和导出后的模型输出对比,定位问题环节:

# 原生模型原始输出(关闭后处理)
inputs = [{"image": sample_input}]
native_raw_output = model.inference(inputs, do_postprocess=False)[0]

# 导出模型的输出
ov_raw_output = compiled_model(sample_input)

# 对比box数值差异
print(torch.tensor(ov_raw_output[0]) - native_raw_output[0])

如果数值差异大,说明导出过程存在配置或精度问题;如果数值一致但后处理无结果,说明是阈值或后处理逻辑问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:02:20