最近看了一些有关于图像实例检索的论文,文中使用mAP作为模型的评价指标,关于图像检索中的mAP的原理请看这里。
http://yongyuan.name/blog/evaluation-of-information-retrieval.html
计算mAP值的过程本质上是求PR曲线面积的过程。我们以上述引用中的第一个AP值的计算为例
其中
P的分别是[1,2/3,3/6,4/9,5/10]
R值分别是[1/5,2/5,3/5/,4/5,1]
AP的计算结果是:
(1+2/3+3/6+4/9+5/10)/ 5
除以5就是乘1/5,就是R的每段间隔,离散的曲线计算面积的近似方式。如下图
相关论文中是不是这么计算的呢,研究了一下一篇论文中mAP的计算方式,其mAP的计算文件在这里:
https://github.com/filipradenovic/cnnimageretrieval-pytorch/blob/master/cirtorch/utils/evaluate.py
这里面有三个函数,compute_ap() ,compute_map(),compute_map_and_print(),compute_map_and_print()是一些和其他相关的计算和输出,不需要看。这里compute_map()是计算mAP和top n的准确率,返回值共有四个,分别是map,aps是一个列表,记录每一个检索结果的ap值,pres是总的精确度,pr也是一个列表,记录每一个检索top n的准确度。这里主要关注的是compute_ap() 函数,因为求mAP就是对ap的结果求平均值。
函数原型是:返回值是ap
def compute_ap(ranks,nres):
假设输入一张图片,数据库中有3个图像与之匹配,按照相似度高低进行排序,得到的位置是第1位,第3位,第6位是这三幅图像,匹配正确。
但是在这个程序设计中,待检索图像在当前数据库中,那么本身的相似度肯定是最高的,排在第0位,ranks=[0,1,3,6]
。nres=4。表示数据库中与待检索图像的属于同一类的个数。按照图像检索ap的计算 方式, 得到ap=(1+1+3/4+4/7)/4=0.830357143.但是这种计算方式ap值偏大,自己检索到自己不应该算到里面 ,于是正确的计算方式应该是ap=(1+2/3+3/6)/3=0.7222222。在测试的时候计算之后发现与代码中计算结果不一致。代码中的求取方式是[(1+1+3/4+4/7)/4+(1+2/3+3/6)/3]/2。不是求平均值。
ap += (precision_0 + precision_1) * recall_step / 2.
总之,mAp值还是偏高啊,或许自己没有搞明白,没有研究更多的代码,不知道在图像实例检索的代码中mAP都是这样算的吗?下面给出一个使用计算ap值的例子。
import numpy as np
def compute_ap(ranks, nres):
"""
Computes average precision for given ranked indexes.
Arguments
---------
ranks : zerro-based ranks of positive images
nres : number of positive images
Returns
-------
ap : average precision
"""
# number of images ranked by the system
nimgranks = len(ranks)
# accumulate trapezoids in PR-plot
ap = 0
recall_step = 1. / nres
for j in np.arange(nimgranks):
rank = ranks[j]
if rank == 0:
precision_0 = 1.
else:
precision_0 = float(j) / rank
precision_1 = float(j + 1) / (rank + 1)
ap += (precision_0 + precision_1) * recall_step / 2.
return ap
ranks=np.array([0,1,3,6])
ners=4
result=compute_ap(ranks,ners)
print(result)
修改一点可以进行正常的计算