0%

卷积神经网络-目标检测

卷积神经网络-目标检测

目标检测是计算机视觉邻域中的一个新兴应用方向,相比前之前,它的性能也是越来越好,在构建目标检测之前,可以先了解一下目标定位。

目标定位

什么是目标定位和检测

之前所学的图片分类问题,主要是给定一张图片,将图片进行分类,如图,给定图片,判定为"Car"类

而定位分类问题,这意味着,不仅需要用算法判断图片中是不是一辆汽车,还需要在图片中标注出它的位置,如图,使用边框将汽车圈起来

而目标检测,则对应的图片中可能有多个对象需要检测并确定位置

image-20201228113741768
image-20201228113741768

位置分类

图片分类问题之前已经有所了解了,如输入一张图片到多层卷积神经网络,然后会输出一个特征向量,并通过softmax单元来预测图片类型,这就是图片分类的基本流程

如果还想定位图片中的洗车位置,又该怎么做呢?

可以让神经网络多输出几个单元,输出一个边界框,具体地,就是让神经网络再多输出4个数字(bx,by,bh,bw)

一般情况符号表示:

图片左上角坐标:(0,0)

图片右下角坐标:(1,1)

边框中心坐标:(bx,by)

边框高度:bh

边框宽度:bw

image-20201228123954111
image-20201228123954111

定义目标标签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中的哪一类\)

image-20201228124818356
image-20201228124818356

损失函数

\[ 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)

对于人脸来说,通常可能会将眼角、眼眶、鼻梁、嘴角等作为你们俩检测的特征点;而对于人体姿态检测,则可能会定义一些关键特征点如胸部的中点、左肩、左肘、腰等,然后通过神经网络标人物姿态的关键特征点,再输出这些标注过的特征点,就相当于输出了人物的姿态动作

image-20201228133314846
image-20201228133314846

要明确一点:特征点一的特性必须在不同的图片中保持一致

目标检测

通过卷积网络进行目标检测,使用的是基于滑动窗口的目标检测算法

汽车检测示例

首先创建一个标签训练集

image-20201228140303024
image-20201228140303024

滑动窗口检测

如图,首先通过卷积网络判断图中框内是否有汽车

image-20201228140413919
image-20201228140413919

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

image-20201228140512762
image-20201228140512762

依次重复操作,直到遍历整个图片

然后再重复上述操作,但将边框大小调大,遍历完成后,再重复,仍然将边框调大,如此,无论汽车在图片什么位置,总会有一个窗口能检测到它

缺点:计算成本太高

因为在图片中剪切出很多小方块,卷积网络需要一个一个地处理,如果选用上海步幅很大,则显然会减少输入卷积的窗口个数,但粗粒度又可能会影响性能,反之,如果采用小粒度或小步幅,则传递给卷积网络的小窗口又会特别多,这又会造成超高的计算成本,所以在最开始的时候,通常采用更简单的分类器进行目标检测,如简单的线性分类器,而由于每个分类器计算成本都很低,所以滑动窗口目标检测算法表现较好,但卷积网络运行单个分类任务的成本却高得多,并且滑动窗口太慢,除非使用超细粒度或极小步幅,否则无法准确定位图片中的目标。

卷积的滑动窗口实现

将FC层转成卷积层

如图,假设对象检测算法输入一个14×14×3的图像,使用16个5×5的过滤器后,映射为10×10×16,然后通过2×2的最大池化操作,图像减小到5×5×16,然后添加一个连接400个单元的全连接层,接着再加一个全连接层,最终通过softmax单元输出

image-20201228142154833
image-20201228142154833

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

image-20201228142510296
image-20201228142510296

通过卷积实现滑动窗口目标检测

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

image-20201228143559460
image-20201228143559460

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

image-20201228143859644
image-20201228143859644

参考文献:OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks)

但这种算法仍存在一个缺点就是边界框的位置可能不够准确

边界框预测

输出正确的边框

在滑动窗口方法中,取出这些离散的位置集合,然后在它们上面运算分类器,如果滑动窗口的大小和边框大小不符合,如图,可能就无法保证边框的正确性,那么如何让这个算法输出更精准的边框呢?

image-20201228144404612
image-20201228144404612

YOLO 算法

如图,假设输入图像是100×100的,然后在图像上放一个网格,为实现方便,此处用3×3网格,实际上会用更加精细的网格,基本思想是使用图像分类和定位算法,然后逐一应用到9个格子上。

对于什么都没有格子,\(P_c=0\),则直接跳过,对于有目标的格子,则取目标的中点,然后将目标分配给包含对象中点的格子

image-20201228150026755
image-20201228150026755

对于参数的取值,通常的约定是:

\(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{黄色阴影面积}{绿色阴影面积}\)

image-20201228150827635
image-20201228150827635

一般约定 ,在计算机检测任务中,如果IoU大于或等于0.5,则证明检测正确,如果预测框和实际框完善重叠,则IoU=1。

非极大值抑制(non-max suppression)

非极大值抑制示例

假设需要在如图上检测行人和汽车,可能会在上面放19×19网格,理论上每辆车只有一个中点,所以理论上应该只有一个格子作出有车的预测,但实践中,当进行目标分类和定位算法时,对于每个格子都运算一次,因此,有的邻近的格子可能会认为中点也在该格子内

image-20201229100808790
image-20201229100808790

而Non-max suppression就是用来解决这个问题的

因为需要在361个格子上都运行一次,因此最后可能会对同一对象做出多次检测,而Non-max suppression做的就是清理这些检测结果,这样,每辆车只检测一次

具体的算法步骤:

  1. 查看检测结果,每个检测结果相关的概率\(P_c\),首先看概率最大的\(P_c\),然后认为该检测是最可靠的检测,如图用高亮标记
  2. 这样之后,Non-max suppression会逐一审视剩下的检测框,所有检测到的和这个最大边界框有高交并比、高度重叠的其它边界框则输出会被抑制,如图用暗色标记
image-20201229101702105
image-20201229101702105

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\)的边框

image-20201229102537025
image-20201229102537025

Anchor Boxes

前面的知识,都是每个格子只能检测一个对象,如果想一个格子检测出多个对象,则需要Anchor Boxes

重叠目标

如图,使用3×3的网格,则行人的中点和汽车的中点几乎在同一个地方,所以对于对应的那个格子,如果y输出和之前一样的向量,将无法输出检测结果,而是必须从两个检测结果中选择一个

image-20201229103401743
image-20201229103401743

而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} \] image-20201229104032246

Anchor box算法

预先:

  • 每个目标处于训练中
  • 图片被分配到对应的包含目标中点的格子

如果是两个anchor boxes:

则对于训练图像中的每个目标被分配到包含目标中点和与目标形状IoU最高的anchor box的格子中,即目标在目标标签中的编码方式为(grid cell,anchor box)

Anchor box示例

image-20201229105105568
image-20201229105105568

综合: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\))),

image-20201229105955274
image-20201229105955274

做出预测

image-20201229110321783
image-20201229110321783

输出non-max supressed结果

  • 对于每个格子,会有2个预测边框,其中一个\(p_c\)很低
image-20201229110512960
image-20201229110512960
  • 丢弃概率低的预测
image-20201229110558587
image-20201229110558587
  • 对每个类别 ,单独运算non-max suppresion,生成最终预测结果(如有三种类别:行人、汽车、摩托车,则需要分别对其进行non-max suppression)
image-20201229110735645
image-20201229110735645

候选区域

Region proposal:R-CNN

R-CNN:Regions with convolutional neural networks,带区域的卷积神经网络

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

image-20201229142922008
image-20201229142922008

更快的算法

R-CNN:提出候选区域,然后对每个候选区域跑一次分类器,每个区域输出一个标签和一个边界框

Fast R-CNN:提出候选区域,使用卷积实现滑动窗口(使用卷积替代循环),但得到候选区域的聚类步骤仍然非常缓慢

Faster R-CNN:使用卷积网络获得候选区域