图像检索评价指标:mAP@k、mAP的计算

您所在的位置:网站首页 查世界地图一千张图的软件 图像检索评价指标:mAP@k、mAP的计算

图像检索评价指标:mAP@k、mAP的计算

2024-07-16 16:02| 来源: 网络整理| 查看: 265

mAP ,mean Average Precision,平均检索精度.是图像检索领域最最常用的评价指标。

一、mAP@k、mAP 1.1 mAP@k

很多地方喜欢用这张图来解释,确实画的很好了,不过略有瑕疵,我稍微修改了一下。这张图是求mAP@10的结果。

原图主要存在的问题就是,在前10张图片中,把所有的相似的结果都返回了。这样会给读者造成这样的困扰:没检索出来的但是又相似的图片怎么办??

改了之后,就清晰多了。我们就会发现我们这里求mAP的时候是不考虑召回率的,也就是并没有考虑那些相似的但是不在topk中的那些漏掉的图片。只考虑了topk中,相似的图片。

注:当然还有一种计算mAP的方法,就是考虑召回率的计算方法,我们这里不展开。

mAP@k,理解的话应该是m(AP@k),而不是(mAP)@k。也就是先求AP@k,再求平均。

AP@k,理解的话应该是A(P@k),而不是(AP)@k。也就是先求P@k,再求平均。

P@k = 前k个中有多少个正样本 / k,比如对于查询1的结果:P@1 = 1, P@2 = 1/2,  P@3 = 2/3...

求AP@k的时候,是求哪些P@k,然后再求平均呢?是求检索到的k张图片中,正样本位置上的P@k。比如,查询1中,返回了10张图片,但是只有5个正样本,分别在第1、3、6、9、10位。所以要求P@1,P@3,P@6, P@9,P@10这5个值,再求平均得到AP@10.

在求mAP@k的时候,k是指每次查询的时候返回k张图片。这个写@k是与后面要讲的mAP做区分用的。写论文的时候有的时候都不写@k,到底是用的mAP@k,还是mAP,自己把握去吧

【举例】

假设有3张图片,这三张图片的哈希码为:query1=[1,-1,1,1], query2=[-1,1,-1,-1],query3=[1,-1,-1,-1]。

数据库中有7张图片,对应的哈希码为:gallery=[[ 1,-1,-1,-1], [-1, 1, 1,-1], [ 1, 1, 1,-1], [-1,-1, 1, 1], [ 1, 1,-1,-1], [ 1, 1, 1,-1], [-1, 1,-1,-1]]

三张query图片的标签为:[1,0,0], [1,1,0], [0,0,1]。

7张gallery图片的标签为:[0,1,0], [1,1,0], [1,0,1], [0,0,1], [0,1,0], [0,0,1], [1,1,0]

求mAP@5.

(1)对于query1([1,-1,1,1]):

首先query1与gallery图片求距离,然后按照距离进行排序,得到最近的topk(这里设为5)张图片。

gallery汉明距离(有几位不同)排序[ 1,-1,-1,-1]22[-1, 1, 1,-1]35[ 1, 1, 1,-1]23[-1,-1, 1, 1]11[ 1, 1,-1,-1]3[ 1, 1, 1,-1]24[-1, 1,-1,-1]4

然后,看看返回的topk张图片中,哪些是正样本,哪些是负样本。query1的标签为[1,0,0],所以包含第1类的都是正样本。

返回的topk图片4图片1图片3图片6图片2标签[0,0,1][0,1,0][1,0,1][0,0,1][1,1,0]是否正样本否否是否是

最后,计算AP@5值:

(1/3 + 2/5)/2 = 0.3667

(2)对于query2([-1,1,-1,-1]):

首先query2与gallery图片求距离,然后按照距离进行排序,得到最近的topk(这里设为5)张图片。

gallery汉明距离(有几位不同)排序[ 1,-1,-1,-1]24[-1, 1, 1,-1]12[ 1, 1, 1,-1]25[-1,-1, 1, 1]3[ 1, 1,-1,-1]13[ 1, 1, 1,-1]2[-1, 1,-1,-1]01

然后,看看返回的topk张图片中,哪些是正样本,哪些是负样本。query2的标签为 [1,1,0],所以包含第1类或第2类的都是正样本。

返回的topk图片7图片2图片5图片1图片3标签[1,1,0][1,1,0][0,1,0][0,1,0][1,0,1]是否正样本是是是是是

最后,计算AP@5值:

(1/1 + 2/2 + 3/3 + 4/4 + 5/5)/5 = 1.0

(3)对于query3([1,-1,-1,-1]):

首先query3与gallery图片求距离,然后按照距离进行排序,得到最近的topk(这里设为5)张图片。

gallery汉明距离(有几位不同)排序[ 1,-1,-1,-1]01[-1, 1, 1,-1]3[ 1, 1, 1,-1]23[-1,-1, 1, 1]3[ 1, 1,-1,-1]12[ 1, 1, 1,-1]24[-1, 1,-1,-1]25

然后,看看返回的topk张图片中,哪些是正样本,哪些是负样本。query3的标签为 [0,0,1],所以包含第3类的都是正样本。

返回的topk图片1图片5图片3图片6图片7标签[0,1,0][0,1,0][1,0,1][0,0,1][1,1,0]是否正样本否否是是否

最后,计算AP@5值:

(1/3 + 2/4)/2 = 0.4165

(4)对所有的query的AP值,求平均

mAP@5 = (0.3667 + 1 + 0.4165) /3 = 0.5944

1.2 mAP与mAP@k的区别

mAP呢,就是每次查询的时候不是返回k张图片了,而是把所有的图片都按相似度进行返回。也就是k的值等于gallery数据库的大小。

【举例】

还是用上面的例子。求mAP。

(1)对于query1([1,-1,1,1]):

首先query1与gallery图片求距离,然后按照距离进行排序

gallery汉明距离(有几位不同)排序[ 1,-1,-1,-1]22[-1, 1, 1,-1]35[ 1, 1, 1,-1]23[-1,-1, 1, 1]11[ 1, 1,-1,-1]36[ 1, 1, 1,-1]24[-1, 1,-1,-1]47

然后,看看返回的topk张图片中,哪些是正样本,哪些是负样本。query1的标签为[1,0,0],所以包含第1类的都是正样本。

返回的topk图片4图片1图片3图片6图片2图片5图片7标签[0,0,1][0,1,0][1,0,1][0,0,1][1,1,0][0,1,0][1,1,0]是否正样本否否是否是否是

最后,计算AP值:

(1/3 + 2/5 + 3/7)/3 = 0.3873

(2)对于query2([-1,1,-1,-1]):

首先query2与gallery图片求距离,然后按照距离进行排序,得到最近的topk(这里设为5)张图片。

gallery汉明距离(有几位不同)排序[ 1,-1,-1,-1]24[-1, 1, 1,-1]12[ 1, 1, 1,-1]25[-1,-1, 1, 1]37[ 1, 1,-1,-1]13[ 1, 1, 1,-1]26[-1, 1,-1,-1]01

然后,看看返回的topk张图片中,哪些是正样本,哪些是负样本。query2的标签为 [1,1,0],所以包含第1类或第2类的都是正样本。

返回的topk图片7图片2图片5图片1图片3图片6图片4标签[1,1,0][1,1,0][0,1,0][0,1,0][1,0,1][0,0,1][0,0,1]是否正样本是是是是是否否

最后,计算AP值:

(1/1 + 2/2 + 3/3 + 4/4 + 5/5)/5 = 1.0

(3)对于query3([1,-1,-1,-1]):

首先query3与gallery图片求距离,然后按照距离进行排序,得到最近的topk(这里设为5)张图片。

gallery汉明距离(有几位不同)排序[ 1,-1,-1,-1]01[-1, 1, 1,-1]36[ 1, 1, 1,-1]23[-1,-1, 1, 1]37[ 1, 1,-1,-1]12[ 1, 1, 1,-1]24[-1, 1,-1,-1]25

然后,看看返回的topk张图片中,哪些是正样本,哪些是负样本。query3的标签为 [0,0,1],所以包含第3类的都是正样本。

返回的topk图片1图片5图片3图片6图片7图片2图片4标签[0,1,0][0,1,0][1,0,1][0,0,1][1,1,0][1,1,0][0,0,1]是否正样本否否是是否否是

最后,计算AP值:

(1/3 + 2/4 + 3/7)/3 = 0.4206

(4)对所有的query的AP值,求平均

mAP = (0.3873 + 1 + 0.4206) /3 = 0.6026

二、代码实现 # @file name : test2.py # @brief : # @author : liupc # @date : 2021/8/2 import numpy as np #计算汉明距离。有几位不同,距离就为几。 def CalcHammingDist(B1, B2): q = B2.shape[1] distH = 0.5 * (q - np.dot(B1, B2.transpose())) return distH #计算mAP@k的值 def CalcTopMap(qB, rB, queryL, retrievalL, topk): #qB queryBinary, query数据集,都转成了哈希码 #rB retrievalBinary,gallery数据集,都转成了哈希码 #queryL queryLabel,query数据集的标签 #retrievalL retrievalLabel,gallery数据集的标签 num_query = queryL.shape[0] #共有多少个查询 topkmap = 0 for iter in range(num_query): #对每一个查询,求其AP@k的值 #gnd:一个长度等于gallery数据集的0/1向量,1表示为正样本(即至少包含query的一个标签),0表示负样本(即,不包含query的标签)。 gnd = (np.dot(queryL[iter, :], retrievalL.transpose()) > 0).astype(np.float32) hamm = CalcHammingDist(qB[iter, :], rB) #计算第iter张query图片与gallery数据集的汉明距离 ind = np.argsort(hamm) #对汉明距离进行排序,返回下标,表示最相似的图片列表 gnd = gnd[ind] #最相似的图片是否为正样本的列表 tgnd = gnd[0:topk] #只看前topk个结果 tsum = np.sum(tgnd).astype(int) #前topk个中有多少个预测对了 if tsum == 0: continue count = np.linspace(1, tsum, tsum) tindex = np.asarray(np.where(tgnd == 1)) + 1.0 topkmap_ = np.mean(count / (tindex)) topkmap += topkmap_ topkmap = topkmap / num_query return topkmap #计算mAP的值 def CalcMap(qB, rB, queryL, retrievalL): #qB queryBinary, query数据集,都转成了哈希码 #rB retrievalBinary,gallery数据集,都转成了哈希码 #queryL queryLabel,query数据集的标签 #retrievalL retrievalLabel,gallery数据集的标签 num_query = queryL.shape[0] map = 0 # print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++') for iter in range(num_query): gnd = (np.dot(queryL[iter, :], retrievalL.transpose()) > 0).astype(np.float32) tsum = np.sum(gnd).astype(int) if tsum == 0: continue hamm = CalcHammingDist(qB[iter, :], rB) ind = np.argsort(hamm) gnd = gnd[ind] count = np.linspace(1, tsum, tsum) tindex = np.asarray(np.where(gnd == 1)) + 1.0 map_ = np.mean(count / (tindex)) # print(map_) map = map + map_ map = map / num_query return map #计算topk准确率 def CalcTopAcc(qB, rB, queryL, retrievalL, topk): # qB: {-1,+1}^{mxq} # rB: {-1,+1}^{nxq} # queryL: {0,1}^{mxl} # retrievalL: {0,1}^{nxl} num_query = queryL.shape[0] topkacc = 0 # print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++') for iter in range(num_query): # gnd:一个长度等于gallery数据集的0/1向量,1表示为正样本(即至少包含query的一个标签),0表示负样本(即,不包含query的标签)。 gnd = (np.dot(queryL[iter, :], retrievalL.transpose()) > 0).astype(np.float32) hamm = CalcHammingDist(qB[iter, :], rB) #计算第iter张query图片与gallery数据集的汉明距离 ind = np.argsort(hamm) #对汉明距离进行排序,返回下标,表示最相似的图片列表 gnd = gnd[ind] #最相似的图片是否为正样本的列表 tgnd = gnd[0:topk] #只看前topk个结果 tsum = np.sum(tgnd) #前topk个中有多少个预测对了 if tsum == 0: continue topkacc += tsum / topk topkacc = topkacc / num_query return topkacc if __name__=='__main__': queryBinary = np.array([[1,-1,1,1],[-1,1,-1,-1],[1,-1,-1,-1]]) galleryBinary = np.array([[ 1,-1,-1,-1], [-1, 1, 1,-1], [ 1, 1, 1,-1], [-1,-1, 1, 1], [ 1, 1,-1,-1], [ 1, 1, 1,-1], [-1, 1,-1,-1]]) queryLabel = np.array([[1,0,0], [1,1,0], [0,0,1]], dtype=np.int64) galleryLabel = np.array([[0,1,0], [1,1,0], [1,0,1], [0,0,1], [0,1,0], [0,0,1], [1,1,0]], dtype=np.int64) topk = 5 topkmap = CalcTopMap(queryBinary, galleryBinary, queryLabel, galleryLabel, topk) print("map@{}为:{}".format(topk, topkmap)) map = CalcMap(queryBinary, galleryBinary, queryLabel, galleryLabel) print("map为:{}".format(map)) topkacc = CalcTopAcc(queryBinary, galleryBinary, queryLabel, galleryLabel, topk) print("acc@{}为:{}".format(topk, topkacc))

运行结果:

三、代码详解

参考:https://yongyuan.name/blog/evaluation-of-information-retrieval.html

           https://zhuanlan.zhihu.com/p/51955362



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3