mAP和rank1均是衡量算法搜索能力的指标。其具体的概念和算法如下所述。
mAP概念
mAP的全称是mean average precision,用于衡量算法的搜索能力。
【簡單說】 Average Precision(AP)是希望「正確的結果要優先出現」這種概念的具體衡量指標。MAP(Mean Average Precision)則是AP的延伸應用,取多次查詢之AP的均值(mean)來代表查詢(或檢索)系統的準確度。且Mean Average Precision (MAP) is a very popular performance measure in information retrieval.
如下这张图中有实际的例子来描述该公式。其图像链接如下:
http://yongyuan.name/blog/evaluation-of-information-retrieval
rank1概念
搜索结果中最靠前的一张图是正确结果的概率,一般通过实验多次来取平均值。
代码实现
下面的代码分为两个部分:1是用于计算输入到AP函数的参数的;2是计算mAP和rank1的值,因此,第二个函数才是重点。
#CMC的长度为3368*19732
CMC = zeros(nQuery, nTest);
#for循环,对每一个Query中的
parfor k = 1:nQuery
#省略号表示省略部分代码
...
% images with the same ID but different camera from the query
good_index = intersect(find(testID == queryID(k)), find(testCAM ~= queryCAM(k)))';
% images neither good nor bad in terms of bbox quality
junk_index1 = find(testID == -1);
% images with the same ID and the same camera as the query
junk_index2 = intersect(find(testID == queryID(k)), find(testCAM == queryCAM(k)));
junk_index = [junk_index1; junk_index2]';
%score is length 19732*1
score = dist(:, k);
[ap(k), CMC(k, :)] = compute_AP(good_index, junk_index, index);% compute AP for single query
...
end
FCMC = mean(CMC);
function [ap, cmc] = compute_AP(good_image, junk_image, index)
%index是排序后的索引,最后的索引代表最佳的匹配结果,长度为19372
%good_image是testID中匹配的张数
%junk_image是测试集中的干扰项,包括-1开始的,以及同ID且同CAM的
cmc = zeros(length(index), 1);
%cmc = (19732,1)
ngood = length(good_image);
old_recall = 0;
old_precision = 1.0;
ap = 0;
intersect_size = 0;
j = 0;
good_now = 0;
njunk = 0;
for n = 1:length(index)
flag = 0;
%如果find()能成功找到,isempty结果为0
%下面的意思是说,如果在goog_image中找到了
if ~isempty(find(good_image == index(n), 1))
cmc(n-njunk:end) = 1;
flag = 1; % good image
good_now = good_now+1;
end
%如果在junk_image中找到了
if ~isempty(find(junk_image == index(n), 1))
njunk = njunk + 1;
continue; % junk image
end
%每次找到了才匹配的才加1
if flag == 1%good
intersect_size = intersect_size + 1;
end
%如果找不到匹配的图,recall一直为0
recall = intersect_size/ngood;
%找不到匹配的图,precision也一直为0
%每次找到匹配的,intersect_size+1
%precision的计算方法是正确的
precision = intersect_size/(j + 1);
%找不到时ap也一直为0
%ap是一个累计的值,类似于积分值
%如果没有找到的情况下,(recall - old_recall)=0,因此,ap是不会变化的,同时,old_recall也不会变化
%但是,precision的值会越来越小
%如果找到的话,recall-old_recall的值恒等于1/ngood
%因此,用recall来控制哪一个precision是要相加的
%但是(old_precision+precision)/2的方式不理解
ap = ap + (recall - old_recall)*((old_precision+precision)/2);
%old_recall=0
old_recall = recall;
%old_precision=0
old_precision = precision;
j = j+1;
if good_now == ngood
return;
end
end
end