分类、目标检测、实例分割的评估指标

发布于:2025-09-06 ⋅ 阅读:(11) ⋅ 点赞:(0)

图像分类的评估指标

混淆矩阵(Confusion Matrix)

混淆矩阵是分类问题中用于评估模型性能的表格,它将模型的预测结果真实标签进行对比,并分为四种不同的情况,从而清晰地显示出模型在哪些地方产生了“混淆”。

以二分类问题为例,目标类别为正类,另一个称为负类。
在这里插入图片描述

  1. 二分类问题,混淆矩阵是一个 2x2 的矩阵。包含四个元素:
  • 真正例(TP): 模型正确地将 正类 预测为 正类 的样本数。
  • 真负例(TN): 模型正确地将 负类 预测为 负类 的样本数。
  • 假正例(FP): 模型错误地将 负类 预测为 正类 的样本数。
  • 假负例(FN): 模型错误地将 正类 预测为 负类 的样本数
    第一个字母表示是否预测准确,第二个字母表示预测结果。
  1. 多分类问题,混淆矩阵是一个 N x N 的矩阵(N为类别数)。
    :通常代表真实标签;
    :通常代表预测标签;
    对角线上的单元格:表示预测正确的样本数(即TP for each class);
    非对角线上的单元格:表示模型混淆的地方。每一行的非对角线元素代表该类的假负例(误判为其他类)。每一列的非对角线元素代表该类的假正例(其他类误判为此类)。
    通过观察多分类混淆矩阵,可以清晰地看出:哪些类别容易被模型混淆;模型在每个类别上的表现如何。

准确率(Accuracy)

准确率是所有样本中,被正确预测的比例。
Accuracy=TP+TNTP+TN+FP+FNAccuracy = \frac{TP+TN}{TP + TN + FP + FN}Accuracy=TP+TN+FP+FNTP+TN
在数据不平衡时,准确率会失效。

精确率/查准率(Precision)

在预测为正类的样本中,实际为正类的比例。精确率更关注“误报”。
Precision=TPTP+FPPrecision = \frac{TP}{TP + FP}Precision=TP+FPTP

召回率/查全率(Recall)

所有真实的正类样本中,成功被预测为正类的比例。召回率更关注“漏报”。
Recall=TPTP+FNRecall = \frac{TP}{TP + FN}Recall=TP+FNTP

F1-score

查准率和查全率是一对矛盾的度量。一般来说:

  • 查准率(precision)高时,查全率(Recall)往往偏低;
  • 查全率(Recall)高时,查准率(precision)往往偏低。

F1−scoreF_1{-score}F1score 是 Precision 和 Recall 的调和平均数,是精确率和召回率的综合平衡指标。当精确率和召回率一个很高一个很低时,F1−scoreF_1{-score}F1score 会很低,只有当两者都较高时,F1−scoreF_1{-score}F1score 才会高。
F1−scoreF_1{-score}F1score 的公式为:
F1−score=2×Precision×Recallprecision+RecallF_{1}{-score} = \frac{2 \times Precision \times Recall}{precision + Recall}F1score=precision+Recall2×Precision×Recall

Fβ−ScoreF_β{-Score}FβScore 是比 F1−scoreF_1{-score}F1score 更通用的形式。有时候精确率和召回率的重要性并不对等。例如,在垃圾邮件检测中更看重精确率(不希望把正常邮件误判为垃圾邮件);而在疾病诊断中更看重召回率(不希望把病人漏诊)

Fβ−ScoreF_β{-Score}FβScore公式为:
Fβ−score=(1+β2)×Precision×Recallβ2×precision+RecallF_{\beta}{-score} = \frac{(1+\beta^2) \times Precision \times Recall}{\beta^2 \times precision + Recall}Fβscore=β2×precision+Recall(1+β2)×Precision×Recall
其中,β\betaβ 是用于平衡 Precision 和 Recall 的权重参数。

  • β=1\beta = 1β=1 时,即F1−scoreF_1{-score}F1score,Precision 和 Recall 有相等的权重。
  • β>1\beta > 1β>1 时,更注重 Recall,比如F2−scoreF_2{-score}F2score,recall 的重要性是 precision 的2倍。
  • β<1\beta < 1β<1 时,更注重 Precision,比如F0.5−scoreF_{0.5}{-score}F0.5score,precision 的重要性是 recall 的2倍。

PR曲线和AP

PR曲线是一条以召回率(Recall) 为横轴、精确率(Precision) 为纵轴绘制而成的曲线。它形象地展示了当模型判断正样本的阈值(Threshold) 发生变化时,精确率和召回率之间的权衡关系。
在这里插入图片描述

  • PR曲线的横轴表示召回率(Recall),纵轴表示精确度(Precision)。
  • PR曲线上的每个点对应于模型在特定阈值下的精确度和召回率。
  • PR曲线上的点越靠近右上角,表示模型在较高Recall的同时保持较高Precision,所以,曲线越靠近右上角(坐标点 (1, 1)),模型性能越好
  • ROC曲线的性能基线是一条大致水平的直线,其精确率约等于数据集中正样本的比例,相当于一个“无用的猜测器”。

绘制PR曲线的过程可以概括为以下几步:

  1. 获取预测概率
    使用训练好的模型在测试集上进行预测,输出每个样本属于正类的概率得分。

  2. 设定阈值列表
    将阈值从高到低进行变化(例如,从0.95, 0.9, 0.85, …, 到0.05)。

  3. 计算每个阈值下的(R, P)点
    对于每一个阈值,将所有概率大于该阈值的样本预测为正类,其余为负类。根据预测结果和真实标签,计算召回率(R)和精确率(P)。

  4. 描点连线
    将每个阈值下计算出的(Recall, Precision)点标注在坐标系中,并按阈值变化顺序连接起来,就形成了PR曲线。

PR曲线聚焦于正类的表现,特别是正类与判断错误的正类(FP) 的关系。PR曲线是数据极度不平衡时的首选工具!当负样本(背景/负类)数量远多于正样本时,ROC曲线可能会显得过于乐观,而PR曲线能暴露模型真实的性能缺陷,是评估模型对正类识别能力的强大工具。因此在欺诈检测、医学诊断、罕见物体检测等正样本稀少的场景中,PR曲线比ROC曲线提供的信息更有价值

AP:
PR曲线衍生出的核心量化指标。定义为PR曲线下的面积
AP是一个介于0到1之间的单一数值,越接近1表示模型的综合性能越好

ROC曲线和AUC

ROC曲线,全称为受试者工作特征曲线,是一种用于评估二分类模型性能的图形化工具。它与PR曲线类似,同样通过变化分类阈值来描绘模型在不同决策标准下的性能表现。
在这里插入图片描述

  • 纵轴表示真正例率(TPR):所有真实的正样本中,被模型正确预测为正的比例。 其实就是召回率(Recall)。它衡量了模型的捕捉能力
    TPR=TPTP+FNTPR = \frac{TP}{TP+FN}TPR=TP+FNTP

  • 横轴表示假正例率(FPR):所有真实的负样本中,被模型错误预测为正的比例。 它衡量了模型误报的代价。
    FPR=FPFP+TNFPR = \frac{FP}{FP+TN}FPR=FP+TNFP

  • ROC曲线越接近左上角,模型性能越好。 表示模型在保持较低假正例率的同时,能够达到较高的真正例率。

  • 从(0,0)到(1,1)的对角线是模型的“性能基线”,代表一个没有任何判别能力的模型(随机猜),其“猜中”正样本的概率和“猜错”负样本的概率相等。任何有意义的模型的ROC曲线都应该远高于对角线。位于对角线下方的模型是性能较差的模型,表示模型的性能比随机猜测还要差。

绘制ROC曲线的过程与PR曲线非常相似:

  1. 获取预测概率
    模型对测试集每个样本输出其为正类的概率。

  2. 设定阈值列表
    将阈值从高到低进行变化(例如,从1.0到0.0)。

  3. 计算每个阈值下的(FPR, TPR)点
    对于每一个阈值,将所有概率大于该阈值的样本预测为正类,其余为负类。根据预测结果和真实标签,计算此时的FPR和TPR。

  4. 描点连线
    将每个阈值下计算出的(FPR, TPR)点标注在坐标系中,并按顺序连接起来,就形成了ROC曲线。
    关键点
    (1)当阈值设定为最高(1.0)时,没有样本被预测为正类。此时 TP=0, FP=0,所以 TPR=0, FPR=0。对应ROC曲线的左下角(0,0)。
    (2)当阈值设定为最低(0.0)时,所有样本都被预测为正类。此时 FN=0, TN=0,所以 TPR=1, FPR=1。对应ROC曲线的右上角(1,1)。

AUC
ROC曲线的核心量化指标,定义为ROC曲线下的面积
AUC的取值范围在 0 到 1 之间,越接近1表示模型性能越好。AUC 为 0.5 时,表示模型性能等同于随机猜测。

目标检测的评估指标

基石:交并比(IOU)

IOU是衡量两个边界框重叠程度的指标。是几乎所有目标检测评估指标的基础。
含义:IOU指的是预测框与真实框之间的IOU。
范围:0到1,IOU 越大,说明预测框定位越准确。
阈值:通常设定一个IOU阈值(如 threshold = 0.5)来判断预测框是“正确”还是“错误”的。

  • TPTPTP:预测框的类别正确且 IOUIOUIOU ≥ 阈值。
  • FPFPFP:预测框的类别错误或 IOUIOUIOU< 阈值。
  • FNFNFN:没有被检测出来的真实目标(漏检)。

预测框的总数=TP+FP预测框的总数 = TP + FP预测框的总数=TP+FP
真实框的总数=TP+FN真实框的总数 = TP + FN真实框的总数=TP+FN

若存在一个真实框匹配到多个预测框的情况,或者一个预测框匹配到多个真实框,选择 IOU 最大的匹配(一对一匹配)。

核心指标:mAP

目标检测任务相较于图像分类任务更复杂,因为需要同时处理多个子任务:

  • 是否检测出图像中的所有目标(Recall)
  • 预测框的位置是否准确(IOU)
  • 目标的类别是否判断正确(分类置信度)

在目标检测任务中,AP(Average Precision)和 mAP(mean Average Precision)是一个综合指标,可以同时评价以上三个方面。它是目标检测任务最核心的评价指标。

  1. AP:衡量单个类别目标检测性能的指标,定义为该类别下的 PR 曲线下的面积。在实际计算中(如COCO数据集的评估方式),通常会对PR曲线进行插值和平滑,然后求平均。
  2. mAP:衡量多类别检测性能的指标,定义为所有类别的 AP 的平均值。是衡量模型在所有类别上整体性能的黄金标准。
    mAP=1N∑i=1NAPimAP = \frac{1}{N} \sum_{i=1}^{N} AP_imAP=N1i=1NAPi 其中,NNN为类别数。
  • mAP@0.5:当IOU阈值设定为0.5时计算出的mAP。是最常用的指标,有时直接简写为mAP。
  • mAP@.5:.95(或写作mAP@[.5:.95]):COCO的核心指标。它在IOU阈值从0.5到0.95(步长0.05) 共10个等级上分别计算mAP,然后再求所有mAP值的平均值。该指标较为严格,同时对定位精度和分类精度都有很高的要求。

mAP的计算节点:在验证阶段,从网络中得到预测结果,经过NMS后处理删掉冗余框之后,计算 mAP。

mAP的计算过程

  1. 输入准备:获取模型的预测结果和数据集的真实标签。

  2. 对于每一个类别(例如‘猫’,‘狗’),单独进行计算。

  3. 计算当前类别的AP

  • (1)匹配预测与真实框:使用IOU判断预测框属于 TPTPTPFPFPFPFNFNFN。一个预测框只能匹配一个真实框。

  • (2)按置信度(类别置信度)排序:将所有预测框按置信度从高到低排序。

  • (3)计算累积的Precision和Recall:遍历排序后的预测列表,计算每个置信度下的P和R。

  • (4)绘制PR曲线并计算AP(PR曲线下的面积)。

  1. 计算mAP:对所有类别的AP值取平均。

实例分割的评估指标

实例分割的最重要、最主流的评价指标依然是 mAP ,其计算流程与目标检测任务的计算流程一致,区别在于 :

  • 目标检测:使用的是2个矩形定位框之间的 IOU (Bounding Box IOU)
  • 实例分割:使用的是2个mask之间的 IOU (Mask IOU)

基石:Mask IOU

Mask IOU 是计算两个分割掩码(预测掩码和真实掩码)相似度的指标。
含义:预测掩码与真实掩码的交集像素数除以并集像素数
与BBox IOU的区别:BBox IOU只计算矩形框的重叠面积,而Mask IOU计算的是像素级轮廓的重叠,要求高得多,更能反映分割的精确度。

核心指标:基于Mask的mAP

实例分割通过基于Mask的mAP对模型性能进行评估,计算过程与目标检测一致。
设定一个 Mask IOU的阈值(通常也是0.5)来判断一个预测是正确还是错误。

  • TPTPTP:预测掩码的类别正确且与某个真实掩码的 Mask IOU ≥ 阈值。
  • FPFPFP
    (1)预测掩码的类别错误;
    (2)预测掩码的类别正确,但与所有真实掩码的 Mask IOU < 阈值;
    (3)预测掩码与同一个真实掩码重复匹配(即同一个真实物体被分割出多个实例)。
  • FNFNFN:没有被任何预测掩码匹配到的真实掩码(漏分割)

COCO评估标准:mAP@[.5:.95]
与目标检测一样,COCO数据集的评估标准是实例分割领域的黄金标准。

  • mAP@[.5:.95]:在Mask IOU阈值从0.5到0.95(步长0.05) 共10个等级上分别计算mAP,然后求平均值。这是最主要的评判指标,因为它对分割的精度要求极高。
  • mAP@0.5:固定IOU阈值为0.5时的mAP。这是一个相对宽松的指标。
  • mAP@0.75:固定IOU阈值为0.75时的mAP。这是一个非常严格的指标。

COCO还会根据物体的大小 reporting 不同尺度的AP:

  • APSAP_SAPS:对小尺度物体(area < 32²)的AP。
  • APmAP_mAPm:对中尺度物体(32² < area < 96²)的AP。
  • APlAP_lAPl:对大尺度物体(area > 96²)的AP。

其他指标

每秒帧数(FPS)

含义:模型每秒可以处理多少张图像。
重要性:衡量模型的检测速度,对于实时应用(如自动驾驶等)至关重要。FPS越高,速度越快。
FPS=处理的图像总数耗费的总推理时间(秒)FPS = \frac{处理的图像总数}{耗费的总推理时间(秒)}FPS=耗费的总推理时间(秒)处理的图像总数

PyTorch 框架测量 FPS 的通用代码模板:

input_tensor = torch.randn(1, 3, 224, 224).to(device) # 创建一个随机输入张量 (Batch Size, Channels, Height, Width)

# 2. 预热(Warm-up)
# GPU有初始化的开销,前几次推理较慢。预热几次让GPU达到稳定状态。
print("Warming up...")
with torch.no_grad():
    for _ in range(50):
        _ = model(input_tensor)
torch.cuda.synchronize() # 等待CUDA操作完成,这对精确计时很重要

# 3. 正式计时
num_iterations = 1000  # 重复次数,越大结果越稳定
total_time = 0

print(f"Measuring FPS for {num_iterations} iterations...")
with torch.no_grad():
    for i in range(num_iterations):
        start_time = time.perf_counter() # 高精度计时开始

        output = model(input_tensor)
        torch.cuda.synchronize() # 等待CUDA操作完成

        end_time = time.perf_counter() # 高精度计时结束
        total_time += (end_time - start_time)

# 4. 计算FPS
average_inference_time = total_time / num_iterations
fps = 1 / average_inference_time

print(f"Average inference time: {average_inference_time * 1000:.2f} ms")
print(f"FPS: {fps:.2f}")
  • torch.cuda.synchronize():在GPU上计时至关重要。因为PyTorch和CUDA操作是异步的(命令发出去就返回,不等待计算完成)。这个函数会阻塞代码,直到GPU上所有操作都完成,从而获得精确的推理时间。
  • Warm-up:GPU在刚开始运算时有一个“热身”阶段,前几次推理会较慢。预热几次后再计时,结果更稳定准确。
  • Batch Size:代码例子中 batch_size=1。FPS会随着Batch Size的增加而增加(因为GPU并行处理),但并非线性增长。汇报FPS时通常需要注明Batch Size。

浮点运算次数(FLOPs)

含义:完成一次前向推理所需的浮点运算次数。
重要性:衡量模型的计算复杂度。FLOPs 可以帮助评估模型的计算开销,FLOPs越小,模型理论上计算速度越快。FLOPs是一个重要指标,但不能完全等同于实际运行速度。
工具:thop 是一个用于计算深度学习模型浮点运算次数(FLOPs)和参数量的Python库,专为 PyTorch 框架设计。通过这个工具,开发者可以轻松分析和评估模型的计算复杂度,从而优化模型性能。

import torch
from thop import profile

model = YourModel()
input = torch.randn(1, 3, 224, 224) # (batch_size, channels, H, W)
flops, params = profile(model, inputs=(input, ))
print(f"FLOPs: {flops / 1e9:.2f} GFLOPs")

网站公告

今日签到

点亮在社区的每一天
去签到