本文所用的mmyolo版本:0.3.0
背景:
首先要知道,mmyolo中在eval和test阶段进行指标计算的时候,对于COCO数据集默认用的就是mAP@0.5:0.95,即不同IoU阈值下的mAP计算,并且没有给出各类别的具体指标,如
可以看出,只给了 不同IoU下AP和AR的值,以及最后不同IoU下的mAP,当然也有针对small、medium、large下的指标,这一切都因为这是COCO数据集benchmark当时的传统。而如果我们需要训练我们自己的任务场景,比如yolov5实现xx检测,就不需要这些东西,我们需要的是:
1.各个类别的AP值
2.不一定要0.5:0.95,可能mAP@0.5就行,即固定IoU阈值为0.5下的mAP\各类别AP
因此怎么进行操作呢?首先要实现第一项:
1.各个类别的AP值
这个很简单,在config里的test_evaluator加入一个参数classwise=True
如下:
即可,因为test_evaluator一般跟val一样,因此我直接加在val里。
如果我不想改config,也可以调用tools/test.py进行测试的时候在命令后加入
--cfg-options test_evaluator.classwise=True
比如
这样就可以实现测试的时候也对各个类别进行AP计算
不管用上述哪种方式,最后都是大功告成。
注意这里各类别的AP只会显示AP@.5:.95的,因此接下来要进行第二个改动
2.各类别AP@0.5指标
为什么会出现默认计算IoU阈值0.5:0.95的指标呢?我们来看源码部分
## /opt/conda/lib/python3.8/site-packages/mmdet/evaluation/metrics/coco_metric.py
## line22
class CocoMetric(BaseMetric):
def __init__(self,
ann_file: Optional[str] = None,
metric: Union[str, List[str]] = 'bbox',
classwise: bool = False,
proposal_nums: Sequence[int] = (100, 300, 1000),
iou_thrs: Optional[Union[float, Sequence[float]]] = None,
metric_items: Optional[Sequence[str]] = None,
format_only: bool = False,
outfile_prefix: Optional[str] = None,
file_client_args: dict = dict(backend='disk'),
collect_device: str = 'cpu',
prefix: Optional[str] = None) -> None:
super().__init__(collect_device=collect_device, prefix=prefix)
# coco evaluation metrics
self.metrics = metric if isinstance(metric, list) else [metric]
allowed_metrics = ['bbox', 'segm', 'proposal', 'proposal_fast']
for metric in self.metrics:
if metric not in allowed_metrics:
raise KeyError(
"metric should be one of 'bbox', 'segm', 'proposal', "
f"'proposal_fast', but got {metric}.")
# do class wise evaluation, default False
self.classwise = classwise
# proposal_nums used to compute recall or precision.
self.proposal_nums = list(proposal_nums)
# iou_thrs used to compute recall or precision.
if iou_thrs is None:
iou_thrs = np.linspace(
.5, 0.95, int(np.round((0.95 - .5) / .05)) + 1, endpoint=True)
self.iou_thrs = iou_thrs
self.metric_items = metric_items
self.format_only = format_only
if self.format_only:
assert outfile_prefix is not None, 'outfile_prefix must be not'
'None when format_only is True, otherwise the result files will'
'be saved to a temp directory which will be cleaned up at the end.'
self.outfile_prefix = outfile_prefix
self.file_client_args = file_client_args
self.file_client = FileClient(**file_client_args)
# if ann_file is not specified,
# initialize coco api with the converted dataset
if ann_file is not None:
with self.file_client.get_local_path(ann_file) as local_path:
self._coco_api = COCO(local_path)
else:
self._coco_api = None
# handle dataset lazy init
self.cat_ids = None
self.img_ids = None
可以看到如果我们在config里规定val_evaluator为CocoMetric的时候没有传入iou_thrs
这个参数的时候,就会默认规定iou_thrs为0.5:0.95的一系列离散值,那么修改就很简单了,只要在config里加入iou_thrs
注意这里的iou_thrs必须是一个list类型,不然会报错 。
然后就可以惊喜地看到各类别的AP@0.5
大功告成