在看人脸识别相关的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")
结果如下:
参考:
文章来源: CMC曲线(python代码实现)