最近正在学习caffe,发现上手还是比较容易的,很快就可以训练出自己的网络啦。可是当我想绘制ROC曲线来评价一下结果的时候,却发现在找不到一个明确的办法。在各大论坛逛了一圈也问了一圈,依旧是得不到解答,于是只好自己拼凑思路找办法了。
首先要搞清楚画ROC曲线需要什么数据!
这篇文章讲的很清楚啦,要画ROC曲线,需要一组FPR/TPR的值。而我们通过训练出来的分类器进行测试的时候,只能得到一组FPR/TPR值。为了得到一组FPR/TPR的值,我们需要让分类器给出一组概率输出,即让分类器对于每一个测试数据,输出它属于每个类别的概率而不是最终的判断结果。
那如何得到概率输出呢?那就要看这里啦!shelhamer告诉我们,只要将输入的前向传输结果输出,就可以得到概率输出了:
import caffe
net = caffe.Net('/path/to/model_def.prototxt','/path/to/model/weights')
out = net.forward()
当然,前提是你的deploy.prototxt的最后一层得是softmax层。我之前训练的CNN网络并没有这一层,果断加之:
layer{
name:"prob"
type:"Softmax"
bottom:"ip2"
top:"prob"
}
这里的ip2就是我的最后一层全链接层啦。加上这一层之后就可以得到概率输出了,这里我参考了这位好心博主的代码(这位博主在我学习caffe的过程中为我解答了很多问题,评论区都还能看到)
def get_predicted_output(deploy_prototxt_filename, caffemodel_filename, input, net = None):
'''''
Get the predicted output, i.e. perform a forward pass
'''
if net is None:
net = caffe.Net(deploy_prototxt_filename,
caffemodel_filename,caffe.TEST)
out = net.forward(data=input)
return out[net.outputs[0]]
def get_predicted_outputs(deploy_prototxt_filename,caffemodel_filename, inputs):
'''''
Get several predicted outputs
'''
outputs = []
net = caffe.Net(deploy_prototxt_filename,caffemodel_filename, caffe.TEST)
for input in inputs:
outputs.append(copy.deepcopy(get_predicted_output
(deploy_prototxt_filename, caffemodel_filename, input, net)))
return outputs
outprob=[]
for temp in outputs:
outprob.append(temp[0][0])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
这样得到的数组就是各个输入属于类别0的概率了。
概率输出有了,接下来就是要获取多组FPR/TPR值了。这里 详细介绍了一个函数sklearn.metrics.roc_curve,可以用它来获取我们需要的值。还给了使用例子:
>>> import numpy as np
>>> from sklearn import metrics
>>> y = np.array([1, 1, 2, 2])
>>> scores = np.array([0.1, 0.4, 0.35, 0.8])
>>> fpr, tpr, thresholds = metrics.roc_curve(y, scores, pos_label=2)
>>> fpr
array([ 0. , 0.5, 0.5, 1. ])
>>> tpr
array([ 0.5, 0.5, 1. , 1. ])
>>> thresholds
array([ 0.8 , 0.4 , 0.35, 0.1 ])
这里y是输入对应的标签组成的数组,caffe中的二分类标签通常是0和1,所以我用的时候这就是0和1组成的数组。score就是上面我们得到的概率输出数组。pos_label是正类别的标签,我用的是0。
一切准备就绪,接下来就是画图啦!导入matplotlib包,然后就尽情地画吧!
import matplotlib.pyplot as plt
plt.plot(fpr,tpr)
plt.savefig("ROC curve")
plt.show()
这里给出的是最简单的画图功能,想要画得更精细一些就去学学matplotlib的其他功能吧!
最后!画出ROC曲线当然就可以算AUC值啦,函数在这里!
最后的最后!拼出这一套方法的我,已经累瘫在实验室。如果哪位大佬有更好更简单的办法,请一定告知我!