SSD(single-shot multibox detector)源码学习笔记
SSD是Wei Liu等人去年提出来的一个object detection框架,在PascalVOC上mAP可以超过著名的Faster RCNN,同时速度可以做到实时,简直强无敌。之前用别人的MXNet代码跑过实验,最近需要改进一下算法,所以去翻了一下原作者用Caffe实现的代码。
在看代码之前先简述一下SSD的做法:图片被送进网络之后先生成一系列feature map,传统一点的框架会在feature map(或者原图)上进行region proposal提取出可能有物体的部分然后进行分类,这一步可能非常费时,所以SSD就放弃了region proposal,而选择直接生成一系列defaul box(或者叫prior box),然后将这些default box回归到正确的位置上去,整个过程通过网络的一次前向传播就可以完成,非常方便,如下图所示。思路类似的算法还有YOLO,不过精度比SSD差了不少。
图1
原作者的代码分散在很多地方,包括 include/caffe/
目录下面的 annotated_data_layer.hpp
、 detection_evaluate_layer.hpp
、 detection_output_layer.hpp
、 multibox_loss_layer.hpp
、 prior_box_layer.hpp
,以及对应的 src/caffe/layers/
目录下面的cpp和cu文件,另外还有 src/caffe/utlis/
目录下面的 bbox_util.cpp
。从名字就可以看出来, annotated_data_layer
是提供数据的、 detection_evaluate_layer
是验证模型效果用的、 detection_output_layer
是输出检测结果用的、 multibox_loss_layer
是loss、 prior_box_layer
是计算prior bbox的。其中跟训练有关的是 annotated_data_layer
、 multibox_loss_layer
、 prior_box_layer
,我就重点看这三个。
annotated_data_layer
这部分代码没有太多好说的,就是把图片读出来(包含一些data augmentation),同时把每张图里的groundtruth bbox读出来传给下一层,没做什么特殊处理。
prior_box_layer
这一层完成的是给定一系列feature map后如何在上面生成prior box。SSD的做法很有意思,对于输入大小是 W×H 的feature map,生成的prior box中心就是 W×H 个,均匀分布在整张图上,像下图中演示的一样。在每个中心上,可以生成多个不同长宽比的prior box,如[1/3, 1/2, 1, 2, 3]。所以在一个feature map上可以生成的prior box总数是 W×<