You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新手求助:如何为YOLOv4目标检测模型计算mAP、F1分数及混淆矩阵?

针对YOLOv4-GPU模型计算mAP、F1分数及混淆矩阵的实现方案

一、准备评估数据集

  • 确保验证集包含图片文件和对应的YOLO格式标注文件:每个图片对应一个同名.txt文件,每行格式为class_id x_center y_center width height(坐标已归一化)。
  • 将验证集放在指定目录(如data/validation),并在data/classes.txt中按顺序列出所有类别名称。

二、调整仓库配置参数

打开core/config.py,修改以下关键配置:

  • 设置TEST_PATH为你的验证集路径;
  • 确保CLASSES指向正确的classes.txt文件;
  • 根据GPU显存调整BATCH_SIZE(推荐8或16);
  • 设定CONF_THRESH(如0.5,过滤低置信度检测框)和IOU_THRESH(如0.5,用于NMS和指标计算)。

三、计算mAP(平均精度均值)

步骤1:导出模型检测结果

修改或编写脚本,遍历验证集图片,将检测结果保存为YOLO格式的.txt文件(存放在detections/目录):

import cv2
from core.yolov4 import YOLOv4
from core.utils import load_class_names

# 初始化模型
class_names = load_class_names("data/classes.txt")
yolo = YOLOv4(weights="data/yolov4.weights", class_names=class_names, gpu=True)

# 遍历验证集图片
validation_img_paths = ["data/validation/img1.jpg", "data/validation/img2.jpg"]  # 替换为你的图片路径列表
for img_path in validation_img_paths:
    img = cv2.imread(img_path)
    img_h, img_w = img.shape[:2]
    # 执行检测
    detections = yolo.detect(img, conf_thresh=0.5, iou_thresh=0.5)
    # 保存检测结果
    det_txt_path = f"detections/{img_path.split('/')[-1].replace('.jpg', '.txt')}"
    with open(det_txt_path, "w") as f:
        for det in detections:
            class_id = det["class_id"]
            x, y, w, h = det["bbox"]
            # 转换为YOLO归一化格式
            x_center = (x + w/2) / img_w
            y_center = (y + h/2) / img_h
            width = w / img_w
            height = h / img_h
            f.write(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n")

步骤2:计算mAP

使用YOLO标准mAP计算逻辑:

  1. 对每个类别,遍历所有标注框和检测框,按置信度排序检测框;
  2. 逐个匹配检测框与标注框(IOU>阈值则视为正确),统计TP(真阳性)、FP(假阳性);
  3. 计算每个类别的Precision-Recall曲线,通过曲线下面积得到AP;
  4. 所有类别的AP取平均值即为mAP。

可以直接复用仓库中自带的calculate_map.py(若存在),或基于上述逻辑编写脚本。

四、计算F1分数

F1分数是精确率(Precision)和召回率(Recall)的调和均值,公式为:F1 = 2*(Precision*Recall)/(Precision+Recall)

统计核心指标

  • TP:检测框与标注框IOU>阈值且类别匹配;
  • FP:无对应标注框的检测框,或类别不匹配的检测框;
  • FN:未被检测到的标注框;

基于这些指标计算:

# 假设已统计得到全局TP、FP、FN
precision = TP / (TP + FP) if (TP + FP) > 0 else 0
recall = TP / (TP + FN) if (TP + FN) > 0 else 0
f1_score = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0
print(f"F1 Score: {f1_score:.4f}")

五、生成混淆矩阵

混淆矩阵用于展示真实类别与预测类别的匹配情况,可借助sklearn实现:

from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
import os

true_labels = []
pred_labels = []
class_names = load_class_names("data/classes.txt")

# 收集真实标签和预测标签
for img_path in validation_img_paths:
    # 读取真实标签
    label_path = img_path.replace(".jpg", ".txt")
    if os.path.exists(label_path):
        with open(label_path, "r") as f:
            for line in f:
                true_labels.append(int(line.split()[0]))
    # 读取预测标签
    det_path = f"detections/{img_path.split('/')[-1].replace('.jpg', '.txt')}"
    if os.path.exists(det_path):
        with open(det_path, "r") as f:
            for line in f:
                pred_labels.append(int(line.split()[0]))
    # 补充FN:未被检测到的真实标签(需额外逻辑匹配,示例简化处理)

# 生成混淆矩阵
cm = confusion_matrix(true_labels, pred_labels, labels=range(len(class_names)))

# 可视化混淆矩阵
plt.figure(figsize=(12, 10))
plt.imshow(cm, interpolation="nearest", cmap=plt.cm.Blues)
plt.title("Confusion Matrix")
plt.colorbar()
tick_marks = range(len(class_names))
plt.xticks(tick_marks, class_names, rotation=45)
plt.yticks(tick_marks, class_names)
plt.xlabel("Predicted Class")
plt.ylabel("True Class")
plt.savefig("confusion_matrix.png")
plt.show()

六、注意事项

  • 验证集标注格式必须严格符合YOLO要求,避免坐标未归一化、类别ID错误等问题;
  • CONF_THRESH和IOU_THRESH的取值会直接影响所有指标结果,建议根据任务需求多次调试;
  • 若GPU显存不足,可减小BATCH_SIZE或降低输入图片分辨率;
  • 优先查看仓库自带的评估脚本(如eval.py),部分逻辑已封装,可直接调用。

内容的提问来源于stack exchange,提问作者Shaik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 19:45:34