VOC AP计算方法和检测框置信度阈值取值的影响
VOC AP计算方法
首先明确几个定义
预测(detection) | 真实(GroundTrue) | |
---|---|---|
TP(True Positive) | 真 | 真 |
FP(False Positive) | 真 | 假 |
TN(True Negative) | 假 | 假 |
FN(False Negative) | 假 | 真 |
记忆小技巧:例如True Positive,前一个单词表示预测和真实是否一致,后一个单词表示预测结果是什么类型;
True/False是一类表示绝对的词语,只能用来表示事实,这里用来表示预测事件的正确与否;
Positive/Negative 用来表示模型、算法或器材得到的结论(预测结果),因为存在模型和器材的不可靠因素,所以只能用Positive/Negative词语来表示可能性;这样理解的记忆,就再不会搞混了。
由于目标检测得到的都是被认为是真的检测框,所以不计算TN和FN.
- 假设目标检测置信度按照从高到低排列,如下表所示:
检测编号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | … |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
IOU>0.5 | T | F | T | F | T | T | T | F | F | T | T | F | T | F | T | |||
tp(遇T增1) | 1 | 1 | 2 | 2 | 3 | 4 | 5 | 5 | 5 | 6 | 7 | 7 | 8 | 8 | 9 | |||
fp(遇F增1) | 0 | 1 | 1 | 2 | 2 | 2 | 2 | 3 | 4 | 4 | 4 | 5 | 5 | 6 | 6 |
假设用置信度阈值筛选了15个bbox(降低阈值,可以筛选更多,之后分析)
以总共15个bbox进行计算ap,其中总的GTbbox=9,虚警个数6个;下面计算n不同是的recall和precision
n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
recall:tp/9 | 1/9 | 1/9 | 2/9 | 2/9 | 3/9 | 4/9 | 5/9 | 5/9 | 5/9 | 6/9 | 7/9 | 7/9 | 8/9 | 8/9 | 9/9 |
precision: tp/(tp+fp) | 1/1 | 1/2 | 2/3 | 2/4 | 3/5 | 4/6 | 5/7 | 5/8 | 5/9 | 6/10 | 7/11 | 7/12 | 8/13 | 8/14 | 9/15 |
检测框置信度阈值对AP的影响
结论:从图像上看,降低阈值后使precision逐渐降为0,也就是当recall=1,precision会有更多个点.
VOC2007计算AP时是取11个固定recall值对应的最大的precision值,然后取平均,所以降低置信度阈值增加的点不会影响AP的值(前提是:recall已经为1,增加的点都是虚警点).
这时我们也就能明白,为什么计算AP时用一个较小的置信度阈值,就是为了确保recall能够等于1,确保没有漏检,后续增加的虚警都是不影响最终计算的AP值的.
Faster RCNN mAP计算代码
splitlines = [x.strip().split(' ') for x in lines]
image_ids = [x[0] for x in splitlines]
confidence = np.array([float(x[1]) for x in splitlines])
BB = np.array([[float(z) for z in x[2:]] for x in splitlines])