1. 引言
我们在训练某些数据集的时候,某些数据集的mAP50已经到达90%以上了,对于我们来说这是非常难提升的,因此,我们可以采用mAP75来作为一个指标。
此外,网上目前基本还没有YOLOv8如何添加mAP75的方法,或者说有收费的,因此,这里展示一下自己添加YOLOv8添加mAP75的方法。
另外感谢各位大佬在评论区提醒,改正,有需要啥改进的也请各位大佬提出来好修改
2. 方法
2.1 val.py
首先是get_desc(self)方法,需要格式化输出mAP75
def get_desc(self):
"""Return a formatted string summarizing class metrics of YOLO model."""
# 为了生成一个表格标题行,用于描述YOLO模型在每个类别上的性能指标,
# 包括图像数量、实例数量、Precision、Recall、mAP50(在50% IoU 阈值下的平均精度)、
# mAP50-95(在50%-95% IoU 阈值范围内的平均精度)等。
# 生成的字符串将用于美观地显示这些指标的表格标题。
# return ('%22s' + '%11s' * 6) % ('Class', 'Images', 'Instances', 'Box(P', 'R', 'mAP50', 'mAP50-95)')
return ('%22s' + '%11s' * 7) % ('Class', 'Images', 'Instances', 'Box(P', 'R', 'mAP50', 'mAP75', 'mAP50-95)')
然后是eval_json(self, stats)方法,如下图需要获取mAP75
eval_json(self, stats)方法全部代码如下
def eval_json(self, stats):
"""Evaluates YOLO output in JSON format and returns performance statistics."""
if self.args.save_json and self.is_coco and len(self.jdict):
anno_json = self.data['path'] / 'annotations/instances_val2017.json' # annotations
pred_json = self.save_dir / 'predictions.json' # predictions
LOGGER.info(f'\nEvaluating pycocotools mAP using {pred_json} and {anno_json}...')
try: # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocoEvalDemo.ipynb
check_requirements('pycocotools>=2.0.6')
from pycocotools.coco import COCO # noqa
from pycocotools.cocoeval import COCOeval # noqa
for x in anno_json, pred_json:
assert x.is_file(), f'{x} file not found'
anno = COCO(str(anno_json)) # init annotations api
pred = anno.loadRes(str(pred_json)) # init predictions api (must pass string, not Path)
eval = COCOeval(anno, pred, 'bbox')
if self.is_coco:
eval.params.imgIds = [int(Path(x).stem) for x in self.dataloader.dataset.im_files] # images to eval
eval.evaluate()
eval.accumulate()
eval.summarize()
# -1: mAP50-95; -2:mAP75; -3: mAP50
stats[self.metrics.keys[-1]], stats[self.metrics.keys[-2]], stats[self.metrics.keys[-3]] = eval.stats[:2] # update mAP50-95 and mAP50
except Exception as e:
LOGGER.warning(f'pycocotools unable to run: {e}')
return stats
2.2 metrics.py
2.2.1 mean_results
首先是mean_results方法,需要添加如下,map75 yolov8已经帮我们定义好了,可以直接用。
2.2.2 mean_results
def mean_results(self):
"""Mean of results, return mp, mr, map50, map."""
return [self.mp, self.mr, self.map50, self.map75, self.map]
这个地方不是很确定,没有理解这个w的含义,因此,这里我现在填的的0.1(和mAP0.5一样的)。后面那个0.9是因为平均了9个值吗(我猜的,求大佬指导)
def fitness(self):
"""Model fitness as a weighted combination of metrics."""
w = [0.0, 0.0, 0.1, 0.1, 0.9] # weights for [P, R, mAP@0.5, mAP@0.5:0.95]
return (np.array(self.mean_results()) * w).sum()
2.2.3 keys(self)
第三个地方keys(self)添加’metrics/mAP75(B)’
def keys(self):
"""Returns a list of keys for accessing specific metrics."""
return ['metrics/precision(B)', 'metrics/recall(B)', 'metrics/mAP50(B)', 'metrics/mAP75(B)', 'metrics/mAP50-95(B)']
评论区提醒,下面也需要修改
@property
def keys(self):
"""Returns list of evaluation metric keys."""
return [
'metrics/precision(B)', 'metrics/recall(B)', 'metrics/mAP50(B)', 'metrics/mAP75(B)', 'metrics/mAP50-95(B)',
'metrics/precision(P)', 'metrics/recall(P)', 'metrics/mAP50(P)', 'metrics/mAP75(P)', 'metrics/mAP50-95(P)']
以及下面
@property
def keys(self):
"""Returns a list of keys for accessing metrics."""
return [
'metrics/precision(B)', 'metrics/recall(B)', 'metrics/mAP50(B)', 'metrics/mAP75(B)', 'metrics/mAP50-95(B)',
'metrics/precision(M)', 'metrics/recall(M)', 'metrics/mAP50(M)', 'metrics/mAP75(M)', 'metrics/mAP50-95(M)']
3 训练测试
如下图训练过程
训练结束的result.csv文件:看起来也没有问题