了解一个架构或者算法,首先明确输入和输出。虽然输入和输出是算法定义的一部分,但是很遗憾,经常看到一些报告会忽略这个问题,分析思路是输入,详细过程和输出。可能导致的一个问题是陷入到详细过程的细节中不能自拔。回顾分类过程,一种常见的结构是网络结构高层为全连接层加上Softmax层,输入一张图片和对应标签,全连接层得到特征的向量化表示,Softmax层后得到一个预测结果,通过预测结果和标签对比,得到反馈信号进行反向传播,得到网络结构的参数更新量,下一张图片喂给模型,过程类似,以此类推,参数的更新效应是累计的,所以需要一张一张图片喂给模型。从优化角度或者站在全局的角度,Loss函数是基于所有样本定义的一个巨大的网络参数搜索空间,优化的过程是通过SGD等方法尽可能找到全局最优的过程,而训练过程,或者Pipeline驱动了寻优的进行。

回到检测过程,检测是定位和分类的和。如何定位?坐标或者说bounding box,小方块。那一个直接的思路就来了,把图片分成好多个小方块,分别对小方块进行分类。当然可以的,但是缺点也是很多的,比如说物体尺度的问题,物体有大有小;随之带来的问题是,计算消耗的问题(括号中内容可以不看,针对这个问题,假设是基于卷积的分类网络,原始方法是一个个拿出小方块,喂给分类网络,改进方法是对原图中的多个小方块同时进行分类,核心是通过卷积操作,在卷积分类网络的最后一层输出所有小方块的预测结果,非常棒的想法,前提是卷积分类网络,代表工作学名OverFeat);等等。不过,不失为一种解决问题的方法,稍微学术点的叫法是基于滑动窗口的目标检测。实际上,比较后来的方法,这种方法最大的优点之一在于不需要打位置标签,检测的位置标签非常昂贵,这也从侧面反映出这种方法在定位上精确不会很高,实在太粗糙,几乎没有任何物体位置的先验信息可以使用,注意这里是几乎没有。

能否按照分类的思路构造定位的过程?还是需要输入和输出的定义。定位是用bbox标出物体在图片中的位置。位置是从坐标来表示,如何唯一表示一个bbox?四个角的坐标可以,中心点的坐标加上bbox的宽高可以,对角线坐标可以。那么,输出就确定了,就是物体坐标,而且是多个坐标。整个Pipeline是输入一张图片,通过网络结构,输出图片中物体的坐标。这个过程在监督体系下,显然需要一个监督信号,也就是标签或者ground truth。类比分类问题,标签应该也是坐标了。输入确定了。如何构造反馈过程?比较预测的坐标和ground truth之间的距离就OK了,这个是一个显然的回归过程。这样,问题就清楚了。检测最终还是要回到分类和回归上。在分类问题中,我们存在特征提取的问题,分类网络到底提取了什么特征?其实,在检测问题中,这个问题应该依然存在。

到这里,可以设计一个最简单的检测网络了。假设已经有一个分类网络了,在全连接层后加上一个回归层,Softmax层输出一个信号,回归层输出四个信号(比如bbox用物体中心点坐标,长,宽表示)。或者换种角度理解,一个网络结构,对应两个任务,一个分类,一个回归,且任务之间具有相关性。

当训练完成后,给网络输入一张图片,就可以输出图片中物体的位置和类别,是不是非常棒!

类比人脸关键点检测,人体姿态检测,对任务轮廓的把握就基本上清晰了。

沿着OverFeat的思路,上文提到没有先验信息,导致位置预测不准确。怎么添加先验信息?一种最强先验莫过于在训练集中给出每个物体的ground truth。当给出ground truth的时候,直接回到上文对输入和输出讨论的一段内容。实际上,这个工作是YOLO早期的想法。此处提一个问题,为啥YOLO需要划分Cell?(相信可以很快得到答案),另一个延伸问题是,撇开OverFeat的框架,撇开Cell,结合ground truth,定位的事情能不能做?

接下来的讨论是在YOLO早期工作的基础上展开的。按照OverFeat的想法,每个小方块代表一个候选物体,候选位置。稍后的博文中,候选的概念可能会经常看到。现在添加了ground truth,如果还要按照这个路子走,至少考虑两个问题。第一,满足每个小方块与一个物体有关。第二,利用好这部分先验信息。针对问题以,ground truth的midpoint落在哪个Cell,就与哪个Cell绑定;问题二上文已经讨论过。

这个路子还是很僵硬,不灵活。假设一个Cell中落入两个物体呢?YOLO的解决方案是添加几个不同尺度的anchor,想要把ground truth分开,midpoint的限制条件不够就添加限制条件,同时与原有体系兼容。这样,和原始的滑窗方法相比,原始的方式可以认为是固定大小和尺度的一种anchor,这种方式是固定大小和尺度的几种anchor,几种不同的尺度就不仅解决了一个Cell落入两个物体的问题,同时解决了多尺度检测的问题。此处,再次提出上文的一个问题,能不能撇开Cell的概念,直接谈多尺度anchor?但是考虑这个问题时,不能忽略利用卷积实现共享计算的问题,而实时性正是YOLO的卖点所在。

上周研讨班的讨论内容,拖到这周才去整理思路,懒。YOLO还有v2和v3的改进版,尚没有跟进。CVPR一波未平,ECCV一波又起,还不讨论ICML,NIPS,ICLR等。针对同样的任务,数据增强,网络结构,损失函数等改进众多,文章根本读不完。所以,关键的是把握脉络和发展方向,保持自己的思考。不能仅仅停留在怎么做的层面上,当然调参这件事,怎么做确实很重要,但是个人认为不具备太强的学习价值,各种做法的背后的原因和理解才是相对有价值的东西。