yolov5训练后模型的map如何计算代码
时间: 2024-04-30 21:19:52 浏览: 171
在 YOLOv5 中,使用的是 mAP(mean Average Precision)指标来衡量模型的性能。计算 mAP 的代码如下:
```python
from utils.general import plot_results, check_file
def test(cfg, data, batch_size=16, img_size=640, iou_thres=0.65, conf_thres=0.25, save_json=False, single_cls=False, augment=False, verbose=False, model=None):
# 加载模型
model = model.to(device).eval()
# 加载数据集
dataloader = create_dataloader(data, img_size=img_size, batch_size=batch_size, stride=int(cfg.stride), pad=cfg.pad, rect=cfg.rect, augment=augment, cache=cfg.cache_images, single_cls=single_cls, pad_method=cfg.pad_method, hyp=hyp, rank=rank, world_size=world_size)
# 初始化变量
seen = 0
pred = []
tbar = tqdm(dataloader, desc=f'Caching images')
for i, (imgs, targets, paths, shapes) in enumerate(tbar):
# 将数据传输到 GPU 上
imgs = imgs.to(device, non_blocking=True)
# 前向传播
with torch.no_grad():
outputs = model(imgs)
# 后处理
outputs = non_max_suppression(outputs, conf_thres=conf_thres, iou_thres=iou_thres, multi_label=False)
# 更新变量
seen += imgs.shape[0]
# 处理预测结果
for si, pred_i in enumerate(outputs):
# 如果没有预测结果,则跳过
if pred_i is None:
continue
# 反归一化预测框坐标
pred_i[:, :4] = scale_coords(imgs.shape[2:], pred_i[:, :4], shapes[si]).round()
# 将预测结果转换为 COCO 格式
for xi, x in enumerate(pred_i):
# 如果没有预测结果,则跳过
if x is None:
continue
# 将预测结果转换为 COCO 格式
box = x[:4].tolist()
score = float(x[4])
label = int(x[5])
image_id = int(Path(paths[si]).stem.split('_')[-1])
pred.append({'image_id': image_id,
'category_id': label,
'bbox': [round(float(x), 3) for x in box],
'score': round(score, 5)})
# 保存预测结果
if save_json and rank in [-1, 0]:
pred_path = 'predictions.json'
with open(pred_path, 'w') as file:
json.dump(pred, file)
# 计算 mAP
if rank in [-1, 0]:
# 如果是多进程,则需要将预测结果合并
if world_size > 1:
pred = comm.gather(pred, dst=0)
if rank == 0:
pred = list(itertools.chain(*pred))
# 计算 mAP
with open(data) as f:
data_dict = yaml.load(f, Loader=yaml.SafeLoader) # config dict
names = ['data/coco.names']
nc = 80
if single_cls:
nc = 1
names = ['data/single.names']
if len(pred):
# 将预测结果转换为 COCO 格式
pred = {x['image_id']: pred_i for x in pred for pred_i in x['instances']}
gt = json.load(open(data_dict['val'].get('ann').rstrip('.json') + '_instances.json', 'r'))
# 计算 AP
ap, p, r, f1, ap_class = ap_per_class(pred, gt, iou_thres=iou_thres, conf_thres=conf_thres, use_07_metric=False)
# 输出 mAP
mp, mr, map50, map = np.mean(p), np.mean(r), ap_class[0], np.mean(ap)
nt = np.bincount(gt['labels'], minlength=nc)
if np.bincount(ap_class) > 1:
print(f"mAP{'@[IoU=0.50:0.95]' * (iou_thres > 0.5)}: {map * 100:.2f}%")
print(f"mAP{'@[IoU=0.50]' * (iou_thres > 0.5)}: {map50 * 100:.2f}%")
print(f"mAP{'@[IoU=0.75]' * (iou_thres > 0.75)}: {ap_class.mean() * 100:.2f}%")
print(f"mAP{'@[IoU=0.50:0.95]' * (iou_thres > 0.5)}, medium: {np.median(ap) * 100:.2f}%")
print(f"Recall: {mr * 100:.2f}%")
print(f"Precision: {mp * 100:.2f}%")
print(f"F1-score: {f1.mean() * 100:.2f}%")
print(f"Unique classes detected: {len(ap_class)}")
else:
print('No detections found by YOLOv5, mAP cannot be calculated.')
```
其中,`ap_per_class()` 函数用于计算每个类别的 AP 值。
阅读全文