卷积神经网络-目标检测
目标检测是计算机视觉邻域中的一个新兴应用方向,相比前之前,它的性能也是越来越好,在构建目标检测之前,可以先了解一下目标定位。
目标定位
什么是目标定位和检测
之前所学的图片分类问题,主要是给定一张图片,将图片进行分类,如图,给定图片,判定为"Car"类
而定位分类问题,这意味着,不仅需要用算法判断图片中是不是一辆汽车,还需要在图片中标注出它的位置,如图,使用边框将汽车圈起来
而目标检测,则对应的图片中可能有多个对象需要检测并确定位置

位置分类
图片分类问题之前已经有所了解了,如输入一张图片到多层卷积神经网络,然后会输出一个特征向量,并通过softmax单元来预测图片类型,这就是图片分类的基本流程
如果还想定位图片中的洗车位置,又该怎么做呢?
可以让神经网络多输出几个单元,输出一个边界框,具体地,就是让神经网络再多输出4个数字(bx,by,bh,bw)
一般情况符号表示:
图片左上角坐标:(0,0)
图片右下角坐标:(1,1)
边框中心坐标:(bx,by)
边框高度:bh
边框宽度:bw

定义目标标签y
神经网络需要输出的是四个数字和一个分类标签即\(b_x,b_y,b_h,b_w,class\ label(1-4)\)
\(y = \begin{bmatrix} P_c \\ b_x \\ b_y \\ b_h \\ b_w \\ c_1 \\ c_2 \\ c_3 \end{bmatrix} \\ P_c:被检测对象属于某一分类的概率(背景分类除外),如果P_c为0,则没有被检测对象,其它参数无意义 \\ 如果检测到对象:b_x、b_y、b_w、b_h、c_1、c_2、c_3 \\ c_1,c_2,c_3表现该对应属于1-3中的哪一类\)

损失函数
\[ L(\hat y,y) = x = \begin{cases} (\hat y_1-y_1)^2+(\hat y_2-y_2)^2 + \cdots + (\hat y_8-y_8)^2\ 如果y_1=1 \\ (\hat y_2-y_1)^2\ 如果y_1=0 \end{cases} \]
实际应用中,可以不对\(c_1,c_2,c_3\)的softmax激活的输出使用对数似然损失,通常是地边框坐标应用平方误差或类似方法,对\(P_c\)应用Logistic Regression
特征点检测(Landmark detection)
对于人脸来说,通常可能会将眼角、眼眶、鼻梁、嘴角等作为你们俩检测的特征点;而对于人体姿态检测,则可能会定义一些关键特征点如胸部的中点、左肩、左肘、腰等,然后通过神经网络标人物姿态的关键特征点,再输出这些标注过的特征点,就相当于输出了人物的姿态动作

要明确一点:特征点一的特性必须在不同的图片中保持一致
目标检测
通过卷积网络进行目标检测,使用的是基于滑动窗口的目标检测算法
汽车检测示例
首先创建一个标签训练集

滑动窗口检测
如图,首先通过卷积网络判断图中框内是否有汽车

如果没有,则继续处理第二个图像

依次重复操作,直到遍历整个图片
然后再重复上述操作,但将边框大小调大,遍历完成后,再重复,仍然将边框调大,如此,无论汽车在图片什么位置,总会有一个窗口能检测到它
缺点:计算成本太高
因为在图片中剪切出很多小方块,卷积网络需要一个一个地处理,如果选用上海步幅很大,则显然会减少输入卷积的窗口个数,但粗粒度又可能会影响性能,反之,如果采用小粒度或小步幅,则传递给卷积网络的小窗口又会特别多,这又会造成超高的计算成本,所以在最开始的时候,通常采用更简单的分类器进行目标检测,如简单的线性分类器,而由于每个分类器计算成本都很低,所以滑动窗口目标检测算法表现较好,但卷积网络运行单个分类任务的成本却高得多,并且滑动窗口太慢,除非使用超细粒度或极小步幅,否则无法准确定位图片中的目标。
卷积的滑动窗口实现
将FC层转成卷积层
如图,假设对象检测算法输入一个14×14×3的图像,使用16个5×5的过滤器后,映射为10×10×16,然后通过2×2的最大池化操作,图像减小到5×5×16,然后添加一个连接400个单元的全连接层,接着再加一个全连接层,最终通过softmax单元输出

将全连接层转换成卷积层:

通过卷积实现滑动窗口目标检测
如图,假设输入是14×14×3,和之前一样,通过卷积网后,输出1×1×4,假设将输入处理为16×16×3,则一系列处理后输出2×2×4,相当于一次计算了四次滑动窗口的值

由于最大池化参数为2,所以相当于以大小为2的步幅在原始图片上应用神经网络

参考文献:OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks)
但这种算法仍存在一个缺点就是边界框的位置可能不够准确
边界框预测
输出正确的边框
在滑动窗口方法中,取出这些离散的位置集合,然后在它们上面运算分类器,如果滑动窗口的大小和边框大小不符合,如图,可能就无法保证边框的正确性,那么如何让这个算法输出更精准的边框呢?

YOLO 算法
如图,假设输入图像是100×100的,然后在图像上放一个网格,为实现方便,此处用3×3网格,实际上会用更加精细的网格,基本思想是使用图像分类和定位算法,然后逐一应用到9个格子上。
对于什么都没有格子,\(P_c=0\),则直接跳过,对于有目标的格子,则取目标的中点,然后将目标分配给包含对象中点的格子

对于参数的取值,通常的约定是:
\(b_x,b_y\)必须是0~1之间,而\(b_h,b_w\)则可能大于1
参考文献:You Only Look Once: Unified, Real-Time Object Detection
交并比(Intersection over union)
如何判断目标检测算法效果好坏呢?
评估目标位置
在目标检测任务中,我们希望同时能定位对象,于是,引入评估目标检测结果的函数-交并比(IoU)函数
IoU:计算两个边界框交集和并集之比,如图,\(IoU=\frac{黄色阴影面积}{绿色阴影面积}\)

一般约定 ,在计算机检测任务中,如果IoU大于或等于0.5,则证明检测正确,如果预测框和实际框完善重叠,则IoU=1。
非极大值抑制(non-max suppression)
非极大值抑制示例
假设需要在如图上检测行人和汽车,可能会在上面放19×19网格,理论上每辆车只有一个中点,所以理论上应该只有一个格子作出有车的预测,但实践中,当进行目标分类和定位算法时,对于每个格子都运算一次,因此,有的邻近的格子可能会认为中点也在该格子内

而Non-max suppression就是用来解决这个问题的
因为需要在361个格子上都运行一次,因此最后可能会对同一对象做出多次检测,而Non-max suppression做的就是清理这些检测结果,这样,每辆车只检测一次
具体的算法步骤:
- 查看检测结果,每个检测结果相关的概率\(P_c\),首先看概率最大的\(P_c\),然后认为该检测是最可靠的检测,如图用高亮标记
- 这样之后,Non-max suppression会逐一审视剩下的检测框,所有检测到的和这个最大边界框有高交并比、高度重叠的其它边界框则输出会被抑制,如图用暗色标记

non max:只输出概率最大的分类结果,但抑制很接近但不是最大的其它预测结果
非极大值抑制算法
如图,对于每个预测结果格式是\(\begin{bmatrix}p_c\\ b_x\\ b_y\\ b_h\\ b_w \end{bmatrix}\),丢弃所有\(p_c \le 0.6\)的结果,对于剩下的所有边框:选择\(p_c\)最大边框的作为输出结果,丢弃上一步后剩下的所有\(IoU \ge 0.5\)的边框

Anchor Boxes
前面的知识,都是每个格子只能检测一个对象,如果想一个格子检测出多个对象,则需要Anchor Boxes
重叠目标
如图,使用3×3的网格,则行人的中点和汽车的中点几乎在同一个地方,所以对于对应的那个格子,如果y输出和之前一样的向量,将无法输出检测结果,而是必须从两个检测结果中选择一个

而Anchor box的思路则是:
预先定义两个不同形状的anchor box,然后将预测结果和这两个anchor box关联起来,一般而言,实际情况下可能会用更多(如5个或更多)的anchor box。
所以,用的向量对应的是 \[
y=\begin{bmatrix} p_c\\ b_x\\ b_y\\b_h\\b_w\\c_1\\c_2\\c_3\\p_c\\b_x\\b_y\\b_h\\b_w\\c_1\\c_2\\c_3 \end{bmatrix}
\]
Anchor box算法
预先:
- 每个目标处于训练中
- 图片被分配到对应的包含目标中点的格子
如果是两个anchor boxes:
则对于训练图像中的每个目标被分配到包含目标中点和与目标形状IoU最高的anchor box的格子中,即目标在目标标签中的编码方式为(grid cell,anchor box)
Anchor box示例

综合:Yolo目标检测算法
训练集
输入:图片
输出:shape:3×3(假设图片分成3×3格)×2(anchor box数量)×8(向量维度:5(\(p_c\)+边框参数(\(b_x,b_y,b_w,b_h\)))+类别种数(\(c_1,c_2,c_3\))),

做出预测

输出non-max supressed结果
- 对于每个格子,会有2个预测边框,其中一个\(p_c\)很低

- 丢弃概率低的预测

- 对每个类别 ,单独运算non-max suppresion,生成最终预测结果(如有三种类别:行人、汽车、摩托车,则需要分别对其进行non-max suppression)

候选区域
Region proposal:R-CNN
R-CNN:Regions with convolutional neural networks,带区域的卷积神经网络
这个算法尝试选出一些在上面运算卷积网络分类器更有意义的区域,所以这里不再针对每个滑动窗口跑检测算法,而是只选择一些窗口,在少数窗口上运行卷积网络分类器,选出候选区域的方法是图像分割算法,

更快的算法
R-CNN:提出候选区域,然后对每个候选区域跑一次分类器,每个区域输出一个标签和一个边界框
Fast R-CNN:提出候选区域,使用卷积实现滑动窗口(使用卷积替代循环),但得到候选区域的聚类步骤仍然非常缓慢
Faster R-CNN:使用卷积网络获得候选区域