使用fastai实现DeepFashion目标检测时预测报错的解决方法
fastai RetinaNet目标检测预测报错解决及正确实现
问题根源
直接调用learn.predict()不适用于fastai的RetinaNet目标检测任务——这个方法是为分类类任务设计的,没法处理目标检测需要的「边界框+多标签」输出格式,才会触发clip_remove_empty()缺少bbox和label参数的报错。
正确的预测实现方式
1. 快速查看样本预测结果(可视化)
用learn.show_results()可以直接从训练/验证集选样本,自动可视化预测的边界框和标签,适合快速验证模型效果:
# 查看验证集前4个样本的预测结果,可调整max_n和figsize learn.show_results(max_n=4, figsize=(15,15))
2. 单张自定义图像的预测流程
如果要对自己的单张图片做预测并解析结果,需要手动完成预处理、推理、后处理三步:
步骤1:图像预处理
把图像转换成模型能接受的格式,同时应用训练时定义的变换:
from fastai.vision.core import PILImage # 加载图像 img = PILImage.create('./000032.jpg') # 应用训练时的item变换(和你datablock里的item_tfms保持一致) img_transformed = item_tfms(img) # 转成批量格式(模型只接受批量输入) xb = img_transformed.unsqueeze(0).to(dls.device)
步骤2:模型推理与结果解析
RetinaNet输出的是原始预测值,需要解码成边界框和分类分数,再用非极大值抑制(NMS)去掉重复框:
from fastai.vision.all import * # 获取模型原始输出 raw_output = learn.model(xb) # 解码边界框和分类分数,scales和ratios要和训练时一致 bboxes, scores = retinanet_decode(raw_output, scales=scales, ratios=ratios, nms_thresh=0.5) # 过滤低置信度的框,这里设为0.3,可根据情况调整 conf_threshold = 0.3 valid_mask = scores.max(dim=1)[0] > conf_threshold valid_bboxes = bboxes[valid_mask] valid_scores = scores[valid_mask] # 获取预测的标签索引 pred_label_ids = valid_scores.argmax(dim=1) # 把边界框转换回图像原始尺寸 original_size = img.size valid_bboxes = TensorBBox(valid_bboxes).scale((original_size[1], original_size[0]))
步骤3:可视化预测结果
把预测的边界框和标签画在原图上:
# 绘制结果,labels用数据集的词汇表转换为可读标签 img.show(bboxes=valid_bboxes, labels=[dls.vocab[idx] for idx in pred_label_ids])
3. 批量处理验证集数据
如果要对整个验证集做预测并评估,用learn.get_preds():
# 获取验证集的预测结果和真实标签 preds, targets = learn.get_preds(ds_idx=1) # 解码所有预测框 all_bboxes, all_scores = retinanet_decode(preds, scales=scales, ratios=ratios, nms_thresh=0.5) # 后续可计算mAP等评估指标
注意事项
- 必须保证
scales和ratios和训练代码里的完全一致,否则解码出的边界框会出错 - 边界框格式默认是
(xmin, ymin, xmax, ymax),和fastai的TensorBBox要求一致 - NMS阈值
nms_thresh和置信度阈值conf_threshold可以根据模型效果调整,阈值过高会漏检,过低会有冗余框
内容的提问来源于stack exchange,提问作者AynonT
相关产品推荐
相关产品推荐

