PyTorch C++环境下解析TorchVision FasterRCNN GenericDict输出报错问题
libtorch部署TorchVision FasterRCNN 输出解析实现指南
常见报错触发原因
- 加载导出的TorchScript格式FasterRCNN模型完成前向推理后,未正确识别eval模式下的输出结构,遍历模型返回的元组类型输出时,误将首元素的空GenericDict识别为单图检测结果字典,对其调用
at("boxes")/at("scores")/at("labels")取值,直接触发“传入at()的参数不在映射中”的运行时报错 - 对
c10::GenericDict的操作规范不熟悉,无法正确定位承载检测结果的位置、遍历字典键值提取目标张量
eval模式下FasterRCNN导出后的固定输出结构
TorchVision官方FasterRCNN模块在eval模式导出为TorchScript后,前向传播返回的元组固定包含两个元素:
- 索引0位置:空的
c10::GenericDict,对应训练阶段的损失返回字段,eval推理模式下无损失值,字典内部无任何键值对 - 索引1位置:
c10::List类型的检测结果列表,列表长度与输入批量的图像数量一致;列表内每个元素对应当前批量中一张图像的检测结果,类型为c10::GenericDict,字典固定存储三个张量字段:boxes: 形状为[N,4]的浮点张量,存储N个检测框的x1、y1、x2、y2像素坐标labels: 形状为[N]的整型张量,存储每个检测框对应的类别索引scores: 形状为[N]的浮点张量,存储每个检测框的置信度得分
GenericDict正确访问方式与结果提取实现
核心操作逻辑:
- 不遍历元组全量元素做字典类型匹配,直接按固定索引定位结果列表,从根源上避免把首元素的空GenericDict识别为有效检测结果
- 对GenericDict调用
at()取值前,先用contains()方法校验目标键是否存在,避免空字典触发运行时异常
可直接复用的解析代码:
// 前向传播获取的输出IValue torch::jit::IValue forward_output = module.forward(preprocessed_input_tensor); // 解析返回的元组结构 auto output_tuple = forward_output.toTuple(); // 跳过索引0位置的空损失字典,直接取索引1位置的检测结果列表 auto detection_list = output_tuple->elements()[1].toList(); // 遍历批量内每张图像的检测结果 for (const auto& img_ivalue : detection_list) { auto result_dict = img_ivalue.toGenericDict(); // 前置校验目标键是否存在 if (!result_dict.contains("boxes") || !result_dict.contains("scores") || !result_dict.contains("labels")) { continue; } // 提取三类目标张量 torch::Tensor det_boxes = result_dict.at("boxes").toTensor(); torch::Tensor det_scores = result_dict.at("scores").toTensor(); torch::Tensor det_labels = result_dict.at("labels").toTensor(); // 后续可基于业务需求做置信度过滤、坐标还原等处理 }
操作注意事项
- 禁止通过遍历元组所有元素、匹配GenericDict类型的方式定位检测结果:索引0位置的空GenericDict和单图结果的GenericDict类型完全一致,仅靠类型判断无法区分二者,是当前报错的核心诱因
c10::GenericDict的键为字符串类型,调用contains()做校验时,键名拼写需与TorchVision导出的字段完全匹配(区分大小写),避免键名拼写错误导致匹配失败- 灰度图输入、HWC转CHW、设备匹配等预处理操作不会改变输出结构,只要模型是在严格eval模式下导出的TorchScript文件,上述输出结构在各稳定版libtorch中保持一致
内容的提问来源于stack exchange,提问作者fstrati70
相关产品推荐
相关产品推荐

