我已经对 PyTorch 中的“fasterrcnn_resnet50_fpn”模型进行了微调,以实现对象检测任务,然后我想计算验证数据集上经过训练的模型的
mAP
指标。我使用了 MeanAveragePrecision
中的 torchmetrics.detection
。
使用训练好的模型进行推理的函数如下所示:
@torch.no_grad
def generate_bboxes_on_one_img(image, model, device):
model.to(device)
model.eval()
x = [image.to(device)]
pred_boxes, pred_labels, pred_scores = model(x)[0].values()
return pred_boxes, pred_labels, pred_scores
为了能够在 dataLoader 上使用前面的函数,我设置了数据集实例和 dataLoader,如下所示:
def collate_fn(batch):
return list(zip(*batch))
val_dataset = VisDroneDataset(val_images_path, val_annotations_df, transforms=val_transform)
val_data_loader = DataLoader(val_dataset, batch_size=1, shuffle=False, num_workers=0, collate_fn=collate_fn)
然后我编写了以下代码来计算每个图像的真实值和预测之间的 mAP
mAP = MeanAveragePrecision(iou_type="bbox")
mAP.to(device)
for image, target in val_data_loader:
original_boxes, original_labels, image_idx, _, _ = target[0].values()
model.eval()
x = [img.to(device) for img in image]
preds_boxes, preds_labels, preds_scores = model(x)[0].values()
image_PIL = val_dataset.get_image(image_idx)
upscaled_image, pred_boxes_upscaled, labels = get_inverse_transform(image[0],
pred_boxes,
pred_labels,
*image_PIL.size)
pred_to_mAP = [
dict(
boxes=torch.tensor(box, dtype=torch.float32),
scores=score,
labels=label
) for box, label, score in zip(pred_boxes_upscaled, pred_labels.clone().detach(), pred_scores.clone().detach())
]
gt_to_mAP = [
dict(
boxes=original_boxes,
labels=original_labels
) for box, label in zip(test_image_gt_bboxes, test_image_gt_labels)
]
mAP.update(pred_to_mAP, gt_to_mAP)
pprint(mAP.compute())
break
我收到以下错误:
ValueError: Expected argument preds and target to have the same length, but got 100 and 127
。
我不明白为什么preds和target应该具有相同的长度。
我阅读了文档,但没有多大帮助。请帮助我了解
MeanAveragePrecision
的工作原理!
错误的原因是
pred_to_mAP
的设置错误。而不是
pred_to_mAP = [
dict(
boxes=torch.tensor(box, dtype=torch.float32),
scores=score,
labels=label
) for box, label, score in zip(pred_boxes_upscaled,
pred_labels.clone().detach(),
pred_scores.clone().detach())
]
应该是
pred_to_mAP = [
dict(
boxes=torch.stack([torch.tensor(box) for box in pred_boxes_upscaled]
).astype(torch.float32).to(device),
scores=pred_scores.to(device),
labels=pred_labels.to(device)
)
]