3D目标检测实战 | 图解KITTI数据集评价指标AP R40(附Python实现)
该文本详细介绍了机器学习中的核心概念及其应用:
准确率(Precision) 和 召回率(Recall) 是评估分类模型性能的基本指标:
- 准确率 = 真阳性 (TP) / (真阳性 + 假阳性 (FP))
- 召回率 = 真阳性 (TP) / (真阳性 + 假阴性 (FN))
P-R曲线(Precision-Recall Curve) 用于展示模型在不同阈值下的性能:- 将预测置信度从高到低排序后依次选择阈值
- 计算每个阈值下的精确度和召回率
- 示例图展示了P-R曲线及其应用场景
平均准确率(Average Precision, AP) 通过积分或离散化求和计算模型性能:- R{11} 和 R{40} 是常用的评估标准
- 插值函数用于处理离散化的精确度值
- KITTI数据集采用AP\mid{R{40}}^{}进行实验评估
实际案例 在KITTI数据集中展示了如何计算AP数值:- 使用IoU判断检测框是否为正样本
- 均匀采样置信度阈值并计算精确度和召回率
- 提供了2D、BEV和3D检测框在不同难度下的实验结果
目录
- 1 准确率和召回率
- 2 P-R曲线的绘制
- 3 AP R11与AP R40标准
- 4 实际案例
1 准确率和召回率
首先给出TP、FP、FN、TN的概念
-
真正正确识别
True PositiveTP
属于该分类任务中被正确识别的对象数目,并等于满足IoU阈值以上的检测框数量 -
假阳性
False PositiveFP
被预测为正(某类)但实际类别为负(另一类)的样本数量,相当于IoU小于等于阈值的检测框的数量。 -
真正例
True NegativeTN
被预测为不包含该类别的样本中真实也不包含该类别的数量 -
假阴性
False NegativeFN
被预测为不属于某类别的样本中真实属于该类别的数量(即未在真实标签中对应检测到该类别)。
基于上述概念给出准确率和召回率的计算方法
- 准确率
Precision
P=\frac{TP}{TP+FP}
- 召回率
Recall
R=\frac{TP}{TP+FN}
准确度P又被称作准确性指标Q(仅用于分类任务),它表现在预测结果中真实正样本的比例;而召回能力R也被视为全面识别能力(仅用于分类任务),它表现在所有真实正样本中被成功识别的比例。

查准率高且查全率高

查准率高但查全率低

查准率低但查全率高
2 P-R曲线的绘制
该性能也被称为准确率-召回率性能 ,其别名还包括查准率-查全率性能 ,在信息检索及Web推荐系统中具有重要应用价值。该指标的核心体现在通过绘制P-R曲线 来评估模型的表现效果 ,其中P-R曲线 是一种关键工具 ,它通过展示不同阈值下的模型准确率与召回率变化关系 ,帮助我们全面了解模型的整体性能表现
P-R曲线绘制过程如下:首先对所有样本按照预测出的概率或信心评分进行降序排列;接着逐步降低置信度门槛,并将所有满足条件的样本标记为正类;随后依次计算并记录不同置信度水平下的真实正例数量(TP)、假阳性的数量(FN)以及假阴性的数量(FP);基于上述统计结果分别计算出准确率和召回率;最后通过调整不同的置信度水平并重复上述操作即可完成P-R曲线的绘制
以一个实例说明绘制过程
假设共有10个样本,在其中正样本与负样本各占5个;为了确保后续计算的准确性,请先根据预测置信度由高至低对这些样本进行排序;随后将按照一定的顺序逐一计算出每个分类任务的准确率与召回率。

将形成的(Precision, Recall)坐标对画到坐标系上可得

随着样本增加,折现会趋于曲线
3 AP R11与AP R40标准
由P-R曲线所包围区域的面积被称为平均准确率(Average Precision, AP) ,它表示为评估模型整体性能表现的重要指标。

在面积计算方面,在工程应用中常采用积分法来进行处理。然而由于不同曲线形态的特点不同,在实际应用中该方法在计算资源上的消耗较高;另一种方法则是将区域进行离散化分割后进行求和运算,在具体实施过程中则需将曲线下方区域分割成若干个小矩形,并通过累加这些小矩形的面积来估算总面积

具体的公式为
AP\mid_{R}^{}=\frac{1}{\left| R \right|}\sum_{r\in R}{\rho _{\mathrm{inter}}\left( r \right)}
其中R=\left\{ r_1,r_2,\cdots ,r_n \right\}是等间隔的召回率点,R_{11}和R_{40}分别指
R_{11}=\left\{ 0,\frac{1}{10},\frac{2}{10},\cdots ,1 \right\} \\ R_{40}=\left\{ \frac{1}{40},\frac{2}{40},\frac{3}{40},\cdots ,1 \right\}
类似于将召回率划分为\left| R \right|个矩形,在每个区间内的高度代表P-R曲线上该召回率点处的精确度。然而这一挑战源于原始数据曲线本质上是离散的特性;因此我们引入了精确度插值函数来解决这一问题
\rho _{\mathrm{inter}}\left( r \right) =\max _{r':r'>r}\rho \left( r' \right)
即取召回率达到r'的位置之后的所有准确率中的最大值作为该点的插值准确率。这等价于将P-R曲线转化为阶梯矩形形式(如图中以蓝色曲线表示),随后按照相应的公式进行计算即可。

R_{40}一定程度上削弱了R_{11}在准确率很低时,AP结果仍然很高的情况,举例而言
在该场景中设定20个参考标注Ground Truth(Ground Truth),并且该算法仅输出一个检测结果图像,并满足与参考标注图像IoU值超过预设阈值的条件,则称此检测结果为真阳性(TP)样本。基于此置信水平进行评估时可得出:计算得出精确率为1.0;其召回率为总数中真实存在的样本数占比即Recall=\frac{1}{20}=5%
在计算过程中发现AP\mid_{R_{11}}^{}=\frac{1}{11}=0.0909时需要注意的一点是:其中对应的召回点为R_{11}中的第0个元素。这一精度值显著高于现有单目3D检测方法的性能指标,在实际应用中显失合理

- 计算AP\mid_{R_{40}}^{}=\frac{1+1}{40}=0.05,这里的1对应R_{40}中召回点\frac{1}{40}和\frac{2}{40}
已有KITTI官方机构亦认可了AP\mid_{R_{40}}^{}指标,并随后通常也会开展实验评估工作。
以下是KITTI数据集AP检测的实例
Car AP@0.70, 0.70, 0.70:
bbox AP:90.7769, 89.7942, 88.8813
bev AP:90.0097, 87.9282, 86.4528
3d AP:88.6137, 78.6245, 77.2243
aos AP:90.75, 89.66, 88.66
Car AP_R40@0.70, 0.70, 0.70:
bbox AP:95.5825, 94.0067, 91.5784
bev AP:92.4184, 88.5586, 87.6479
3d AP:90.5534, 81.6116, 78.6108
aos AP:95.55, 93.85, 91.33
解释如下:
第一行 Car AP@0.70, 0.70, 0.70
在本研究中,“Car”被定义为类别标识符,“AP”则代表基于“AP R11”标准计算得到的平均准确率指标。具体而言,在这一评估体系中包含了三个关键指标:2D检测框、BEV检测框以及3D检测框的性能评估均采用了相同的评估标准(IoU),其数值设定为0.70。根据这一设定标准,在IoU值达到该阈值时才被判定为有效匹配或正样本识别结果。
第三段:第三行为一种独立的三维物体检测模式,在不同难度等级下(如遮挡严重)的表现数据分别为Easy、Moderate和Hard等级对应的准确率数值
aos定义为平均朝向相似度(average orientation similarity) ,用于评估预测结果方向与真实目标框方向的一致性程度如何
4 实际案例
在KITTI数据集中,按以下步骤计算AP数值
请计算交并比(IoU),具体原理可参考3D目标检测实战 | 详解2D/3D检测框交并比IoU计算(附Python实现)
frame_overlaps, parted_overlaps, gt_num, dt_num = iou(gt_annos, dt_annos, method, num_parts)
基于IoU阈值为0的标准生成置信度列表,在所有候选框中筛选出满足IoU条件的部分,并将其标记为正样本;最后收集这些候选框的置信分数。
rets = compute(frame_overlaps[i], gt_data_list[i], dt_data_list[i],
ignored_gts[i], ignored_dts[i], min_overlap=min_overlap, thresh=0.0)
_, _, _, _, scores_i = rets
对置信度列表均匀采样41个点,得到40个召回点对应的置信度阈值
thresholds = getThresholds(np.array(scores), valid_gt_num)
def getThresholds(scores: np.ndarray, num_gt, num_sample_pts=41):
scores.sort()
scores = scores[::-1]
current_recall = 0
thresholds = []
for i, score in enumerate(scores):
l_recall = (i + 1) / num_gt
if i < (len(scores) - 1):
r_recall = (i + 2) / num_gt
else:
r_recall = l_recall
if (((r_recall - current_recall) < (current_recall - l_recall))
and (i < (len(scores) - 1))):
continue
thresholds.append(score)
current_recall += 1 / (num_sample_pts - 1.0)
return thresholds
遍历每个阈值,计算该阈值下的TP、FP和FN,从而计算准确率和召回率
for i in range(len(thresholds)):
recall[m, l, k, i] = pr[i, 0] / (pr[i, 0] + pr[i, 2])
precision[m, l, k, i] = pr[i, 0] / (pr[i, 0] + pr[i, 1])
if compute_aos:
aos[m, l, k, i] = pr[i, 3] / (pr[i, 0] + pr[i, 1])
取PR曲线外接矩形
for i in range(len(thresholds)):
precision[m, l, k, i] = np.max(precision[m, l, k, i:], axis=-1)
recall[m, l, k, i] = np.max(recall[m, l, k, i:], axis=-1)
if compute_aos:
aos[m, l, k, i] = np.max(aos[m, l, k, i:], axis=-1)
计算AP
def mAP(prec):
sums = 0
for i in range(0, prec.shape[-1], 4):
sums = sums + prec[..., i]
return sums / 11
def mAPR40(prec):
sums = 0
for i in range(1, prec.shape[-1]):
sums = sums + prec[..., i]
return sums / 40

本文完整工程代码请通过下方名片联系博主获取
🔥 更多精彩专栏 :
👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇
