前言
对于目标检测算法来说,最终模型的评价至关重要。本文将针对SSD检测框架,简要叙述如何在模型的测试阶段,针对标注好的测试集,得到mAP,每一类的AP,以及画出P-R曲线。这里博主不再赘述mAP的概念及其计算公式,只说怎么修改caffe-ssd的代码。
模型测试
SSD算法的模型测试主要有两种方式,一种是训练中每间隔一定的迭代次数进行测试,一种是在模型训练结束后,针对某个caffemodel进行测试。第一种很简单,可以直接在solver.prototxt中指定test_interval
等参数即可。
第二种也很容易,只需要准备好如下文件即可:train.prototxt,test.prototxt,solver.prototxt,test.sh,训练好的caffemodel以及标注的测试集lmdb。
博主选择在其他地方单独开了一个文件夹,因此需要修改以上文件里面的路径信息,为了直观,我都是用绝对路径。首先是脚本文件test.sh,这个很好写,类似下面就行:
/home/mx/paper-use/caffe/build/tools/caffe train \
--solver='solver.prototxt' \
--weights='KITTI_SSD_300x300_ft_iter_61000.caffemodel' \
--gpu 0 2>&1 | tee test_result.log
然后是solver.prototxt文件,大致不变,需要指定训练和测试的网络文件,然后把最大迭代次数max_iter
设置为0,把test_iter
设置为测试图片数量除以测试的batchsize,这样就可以直接进入测试阶段。
模型测试中会用到train.prototxt和test.prototxt文件,其中需要修改的地方只是所有的路径,列举如下:
# train.prototxt
data_param {
source: "/home/mx/paper-use/caffe/examples/KITTI/KITTI_trainval_lmdb"
batch_size: 1 # 根据显卡调整,越大越好
backend: LMDB
}
label_map_file: "/home/mx/paper-use/caffe/data/KITTI/labelmap_kitti.prototxt"
# test.prototxt
data_param {
source: "/home/mx/paper-use/caffe/examples/KITTI/KITTI_test_lmdb"
batch_size: 1
backend: LMDB
}
annotated_data_param {
batch_sampler {
}
label_map_file: "/home/mx/paper-use/caffe/data/KITTI/labelmap_kitti.prototxt"
}
save_output_param {
output_directory: "/home/mx/paper-use/test-kitti-model/main"
output_name_prefix: "comp4_det_test_"
output_format: "VOC"
label_map_file: "/home/mx/paper-use/caffe/data/KITTI/labelmap_kitti.prototxt"
name_size_file: "/home/mx/paper-use/caffe/data/KITTI/test_name_size.txt"
num_test_image: 899 # 测试图片的数量
}
name_size_file: "/home/mx/paper-use/caffe/data/KITTI/test_name_size.txt"
最后直接执行./test.sh
命令来执行测试过程,打印的重要信息如下所示:
I0127 20:25:05.363581 9889 solver.cpp:332] Iteration 0, loss = 1.2211
I0127 20:25:05.363626 9889 solver.cpp:433] Iteration 0, Testing net (#0)
I0127 20:25:05.376278 9889 net.cpp:693] Ignoring source layer mbox_loss
I0127 20:25:16.671056 9889 solver.cpp:553] Test net output #0: detection_eval = 0.774722
I0127 20:25:16.671093 9889 solver.cpp:337] Optimization Done.
I0127 20:25:16.671098 9889 caffe.cpp:254] Optimization Done.
detection_eval就是mAP,表明本次训练的KITTI模型,其mAP是77.4%。
输出详细的AP信息
刚才简单回顾了SSD模型的测试过程,可知模型的测试阶段,solver.cpp一般只会打印mAP信息,但是我们还想知道每一类的AP信息,而且如果能画出P-R曲线就更好了,这都有利于分析模型好坏。
事实上,在仔细看过solver.cpp的源代码后,可发现如下语句:
...
if (param_.show_per_class_result()) {
LOG(INFO) << "class" << label << ": " << APs[label];
}
...
什么意思?这就是说,只要在solver.prototxt中加入如下命令,同时令ap_version: "11point"
,就能在终端中打印每一类的AP信息。
show_per_class_result: true
于是做了实验,发现果然打印了每一类的检测精度:
I0127 20:43:58.062511 13937 solver.cpp:332] Iteration 0, loss = 1.22286
I0127 20:43:58.062556 13937 solver.cpp:433] Iteration 0, Testing net (#0)
I0127 20:43:58.074950 13937 net.cpp:693] Ignoring source layer mbox_loss
I0127 20:44:09.344396