在看人脸识别相关的paper时,常会遇到有的文献除了ROC曲线外,也会将CMC曲线作为他们的实验性能指标。那么,怎么理解CMC曲线呢?我在网上查阅了一些资料,为了方便理解,举例如下:
假如我们训练好了一个3分类的模型,分别为类别c1,c2,c3。每个样本输入模型后会得到对应的3个匹配分数,匹配分数最高的那个类别即是预测的类别数。
针对单样本:
现在我们手头仅有一个属于类别c1的样本,我们将该样本输入模型,得到的匹配分数如下:
c1:0.9
c2:0.8
c3:0.7
很好,我们可以看见类别c1匹配分数最高,即该样本真实类别与预测类别相同,即rank1(第一次即命中)=100%,如果第一次就命中,那么后面的rank2与rank3也为100%。
如果匹配分数如下:
c1:0.8
c2:0.9
c3:0.7
现在匹配分数最高的类别c2并不是该样本的真实类别,所以rank1=0%,次之的c1才是该样本的真实类别,所以rank2(第二次命中) = 100%,自然rank3 = 100%。
针对多样本:
现在我们手头有一个属于类别c1的样本s1和一个属于类别c2的样本s2,我们将这两个样本输入模型,得到匹配分数如下:
s1:
c1:0.9
c2:0.8
c3:0.7
s2:
c1:0.7
c2:0.8
c3:0.9
可见,针对样本s1,rank1 = 100,rank2 = 100%,rank3 = 100%;针对样本s2,rank1 = 0%,rank2 = 100%,rank3 = 100%。所以总的rank1 = 50%,rank2 = 100%,rank3 = 100%。
下面附带自己平时项目中用python编的cmc代码,假如已经训练好了一个模型预测48类,测试集为288个样本,该测试集对应的one-hot标签部分图如下:
纵坐标(部分显示)0到47代表48类,横坐标0到287代表288个测试样本。
1代表该样本属于这个类,0代表不属于这个类,如第一个测试样本(第一行)属于第8类。
以下为用python编写的画cmc曲线的代码:
# CMC曲线
# 需要提供predict_label和test_y这两个变量
# 需要安装numpy和matplotlib这两个包
test_cmc = [] #保存accuracy,记录rank1到rank48的准确率
sort_index = np.argsort(-predict_label,axis=1)#predict_label为模型预测得到的匹配分数矩阵;降序排序,返回匹配分数值从大到小的索引值
actual_index = np.argmax(test_y,1) #test_y为测试样本的真实标签矩阵;返回一列真实标签相对应的最大值的索引值
predict_index = np.argmax(predict_label,1)#返回一列预测标签相对应的最大值的索引值
temp = np.cast['float32'](np.equal(actual_index,predict_index)) #一列相似值,1代表相同,0代表不同
test_cmc.append(np.mean(temp))#rank1
#rank2到rank48
for i in range(sort_index.shape[1]-1):
for j in range(len(temp)):
if temp[j]==0:
predict_index[j] = sort_index[j][i+1]
temp = np.cast['float32'](np.equal(actual_index,predict_index))
test_cmc.append(np.mean(temp))
#创建绘图对象
plt.figure()
x = np.arange(0,sort_index.shape[1])
plt.plot(x,test_cmc,color="red",linewidth=2)
plt.xlabel("Rank")
plt.ylabel("Matching Rate")
plt.legend()
plt.title("CMC Curve")
结果如下:
参考: