理解yolo系列目标检测算法

在计算机视觉任务中,如果说做的最成熟的是图像识别领域,那么紧随其后的应该就是目标检测了。笔者接触目标检测也有一段时间了,用mobilenet_ssd算法做过手机端的实时目标检测,也用faster-rcnn做过服务器端的二维码检测,尽管一直都知道yolo的效果也很不错,但没抽出时间细细研究,最近刚好闲出空来,就把yolo系列算法论文细读了一遍,在思考的过程中,也使我对之前的知识点有了新的体会,这里一并记录下来,也希望能对读者有所帮助。

1. 目标检测算法发展史

这几年目标检测方面的文章很多,如果只是单纯地研究其中的某几个算法的话,可能会“一叶障目,不见泰山”,庆幸有网友整理了下面这张非常棒的图,按时间顺序罗列了比较经典的检测算法(附录中有列原图链接)。
理解yolo系列目标检测算法
说说对已经看过的算法的体会吧,

1) R-CNN,它的全称是"region based CNN",显然,从名字可以看出,这种算法的CNN网络的输入是region。其实,最直接的想法应该是,从输入图像中选取所有尺度的regions,然后分别送到CNN网络中进行训练和测试,这种想法存在的问题是,不同尺度的regions,数量会达到指数级别,所以这种想法是行不通的。R-CNN则是在此基础上进行创新,使用了"selective search"的方法预筛选2k个最可能的regions,然后使用CNN网络提取特征,显然,一般来说,对于一幅图像,2k个目标是足够了的,从而使得CNN做目标检测成为了可能;

2) Fast R-CNN,从名字来看,它比R-CNN更快,快在哪里呢?并不是因为它把2k个regions减少了,而是因为它一次输入一整张图像,相对于R-CNN,它的计算量是原来的1/2k,所以名字上多了一个’Fast’;

3) Faster R-CNN,从名字来看,它比Fast R-CNN更快,那么它又是从什么角度做的优化呢?特征提取网络不变,只是把“ selective search”替换成了RPN。因为“ selective search”非常耗时,而RPN的小网络会比较快,虽然交替训练会直觉上比较困难,但是做inference的时候,整个网络的耗时,相对于改进前提升了10倍以上,所以作者称之“Faster”也当之无愧了,具体的对比数据参见下表,
理解yolo系列目标检测算法
  这里顺便提及一下,R-CNN系列算法都属于“two-stage”的目标检测算法,为什么呢?其实,这里指的stage分别是 region proposals 和 prediction,显然,上面的3个方法都是要先生成proposals,然后预测这些proposals对应的边界框和目标类别,所以称之为“two-stage”。而Yolo和ssd算法因为不需要预先生成" region proposals",所以我们称之为“one-stage”的目标检测算法。

2. yolo-v1

2.1 动机

尽管R-CNN系列算法每一版本的优化效果很明显,但是即便是Faster R-CNN也很难满足pc实时性的要求,为了提升算法inference速度,对Faster R-CNN继续改进已经很难了,必须开发一种全新的检测框架。

2.2 优点

a) “end-to-end”:输入一副原始图像,单一网络直接inference出目标位置;

b) Fast,可以满足pc上的实时性要求;

c) 效果鲁棒,从自然图像迁移到艺术等其他领域的图像时,效果也很好。

2.3 inference过程

yolo-v1把输入图像划分成了SxS 的网格,显然,每个网格代表了一个图像块,它的作用有两个:(1) 预测一个目标类别标签,(2) 预测出以当前网格为中心的所有可能的bounding boxes和这些boxes对应的打分。显然,前者关注的是当前网格对应的物体的标签,后者关注的是当前网格对应的所有可能物体的位置。为了得到当前网格对应的物体的位置,每个网格的信息会预测出B个bounding boxes。以下图为例进行解释,狗的“center”点落在了第5行第2列的格子上,那么在inference过程中,该网格则负责预测出狗的边框位置,自行车和汽车同理。这里顺便提及一下,如果有一只猫依偎在狗的身旁(这里假设是这样,现实中不太可能哈 ?),且猫的"center"点恰好也在这个网格中,那么yolo-v1只会预测出其中的一个目标,而忽略另外一者,这种情况被称为“dense object detection”。
理解yolo系列目标检测算法
  理解了上面的例子,yolo-v1的整个inference过程就很好理解了,引用一下论文中给出的网络结构图,
理解yolo系列目标检测算法
给定任意一副输入图像,网络会先缩放到448x448的尺寸大小,然后经过中间的特征提取之后,最终得到7x7x30 的特征图,特征图的空间维度为7x7,每个像素对应着原图中的局部感受野,等价于将原图切分成了7x7的网格图,通道维度为什么是30呢?上文中提到,每个网格的信息会预测出B个bounding boxes,论文中取B=2,pascal voc检测数据集的类别数为20,所以通道维度为2*(4+1) + 20 = 30。
  在inference阶段,每个网格会预测出B个bounding boxes,然后经过两步后处理得到最终的检测框,步骤一:设置阈值,只保留类概率高于阈值的bounding boxes,步骤二:nms去除重复的bounding boxes。

参考资料:

https://medium.com/@jonathan_hui/real-time-object-detection-with-yolo-yolov2-28b1b93e2088

https://towardsdatascience.com/r-cnn-fast-r-cnn-faster-r-cnn-yolo-object-detection-algorithms-36d53571365e

https://github.com/hoya012/deep_learning_object_detection