头图

深度学习教程 | CNN应用:目标检测

ShowMeAI

收藏ShowMeAI查看更多精彩内容


第4门课 卷积神经网络,第3周:目标检测

本系列为吴恩达老师《深度学习专项课程(Deep Learning Specialization)》学习与总结整理所得,对应的课程视频可以在这里查看。

引言

ShowMeAI前一篇文章 经典CNN网络实例详解 中我们对以下内容进行了介绍:

  • 经典CNN结构

    • LeNet-5
    • AlexNet
    • VGG
  • ResNet(Residual Network,残差网络)
  • Inception Neural Network
  • 1x1卷积
  • 迁移学习
  • 数据扩增
  • 手工工程与计算机现状

目标检测

本篇主要介绍计算机视觉中最典型的应用之一目标检测,目标检测任务是对输入图像进行分类的同时,检测图像中是否包含某些目标,并对他们准确定位并标识。

1.目标定位

目标定位 Object Localization

我们在前面的内容中,主要给大家介绍图像识别(分类)相关的知识,除了图像识别,我们还有「目标定位」和「目标检测」任务,如下图所示。

定位分类问题不仅要求判断出图片中物体的种类,还要在图片中标记出它的具体位置,用边框(Bounding Box,或者称包围盒)把物体圈起来。如图中间所示。

目标定位

我们稍微说明一下定位分类和目标检测任务的差别:通常在定位分类问题中,只有一个较大的对象位于图片中间位置;而在目标检测问题中,图片可以含有多个对象,甚至单张图片中会有多个不同分类的对象。

定位分类任务中的「分类」部分大家已经非常熟悉了,使用如下的卷积神经网络即可完成。

目标定位

原始图片经过若干卷积神经网络层次后,Softmax层输出分类(上图维度是\( 4 \times 1\) )向量,分别是pedestrain,car,motorcycle和background四类。

对于目标定位问题,其模型如下所示:

目标定位

为了定位图片中汽车的位置,可以让神经网络多输出 4 个数字,标记为 \( b_x\) 、\( b_y\) 、\( b_h\) 、\( b_w\) (注意上图中\( P_c\) 是一个表示目标物是否存在的01取值标签)。将图片左上角标记为 \( (0, 0)\) ,右下角标记为 \( (1, 1)\) ,则有:

  • 橙色方框的中心点:\( (b_x, b_y)\)
  • 边界框的高度:\( b_h\)
  • 边界框的宽度:\( b_w\)

因此,训练集不仅包含对象分类标签,还包含表示边界框的四个数字。定义目标标签 \( Y\) 如下:

$$ \left[\begin{matrix}P_c\\ b_x\\ b_y\\ b_h\\ b_w\\ c_1\\ c_2\\ c_3\end{matrix}\right] $$

则有:

$$ P_c=1, Y = \left[\begin{matrix}1\\ b_x\\ b_y\\ b_h\\ b_w\\ c_1\\ c_2\\ c_3\end{matrix}\right] $$

其中,\( c_n\) 表示存在第 \( n\) 个种类的概率;如果 \( P_c=0\) ,表示没有检测到目标,则输出标签后面的 7 个参数都是无效的,可以忽略(用 ? 来表示)。

$$ P_c=0, Y = \left[\begin{matrix}0\\ ?\\ ?\\ ?\\ ?\\ ?\\ ?\\ ?\end{matrix}\right] $$

`

损失函数可以表示为 \( L(\hat{y}, y)\) ,如果使用平方误差形式,对于不同的 \( P_c\) 有不同的损失函数(注意下标 \( i\) 指标签的第 \( i\) 个值):

  • \( P_c=1\) ,即\( y_1=1\) :\( L(\hat{y},y)=(\hat{y}_1-y_1)^2+(\hat{y}_2-y_2)^2+\cdots+(\hat{y}_8-y_8)^2\)
  • \( P_c=0\) ,即\( y_1=0\) :\( L(\hat{y},y)=(\hat{y}_1-y_1)^2\)

除了使用平方误差,也可以使用逻辑回归损失函数,类标签 \( c_1\) ,\( c_2\) ,\( c_3\) 也可以通过 Softmax 输出。相比较而言,平方误差已经能够取得比较好的效果。

2.特征点检测

特征点检测 Landmark Detection

神经网络可以像标识目标的中心点位置那样,通过输出图片上的特征点,来实现对目标特征的识别。在标签中,这些特征点以多个二维坐标的形式表示。

通过检测人脸特征点可以进行情绪分类与判断,或者应用于 AR 领域等等。也可以透过检测姿态特征点来进行人体姿态检测。例如人脸识别,可以对人脸部分特征点坐标进行定位检测,并标记出来,如下图所示:

特征点检测

上图中的网络模型共检测人脸上\( 64\) 处特征点,加上是否为人脸的标志位,输出标签共有\( 64x2+1=129\) 个值。检测人脸特征点有一些典型的场景应用,比如可以进行情绪分类与判断,或者应用于AR领域等。

除了人脸特征点检测之外,可以对其进行拓展,基于特征点连接检测人体姿势动作,如下图所示:

特征点检测

3.目标检测

目标检测 Object Detection

目标检测问题中,我们要对图片中的多个对象进行识别和位置检测,一种直观能想到的实现方法是基于滑动窗口的目标检测(Sliding Windows Detection)算法。该算法的步骤如下:

目标检测

  • ① 训练集上搜集相应的各种目标图片和非目标图片,样本图片要求尺寸较小,相应目标居于图片中心位置并基本占据整张图片。
  • ② 使用训练集构建 CNN 模型,使得模型有较高的识别率。
  • ③ 选择大小适宜的窗口与合适的固定步幅,对测试图片进行从左到右、从上倒下的滑动遍历。每个窗口区域使用已经训练好的 CNN 模型进行识别判断。若判断有目标,则此窗口即为目标区域;若判断没有目标,则此窗口为非目标区域。
  • ④ 可以选择更大的窗口,然后重复第三步的操作。

滑动窗口目标检测的优点

  • 原理简单,且不需要人为选定目标区域。

滑动窗口目标检测的缺点

  • 需要人为直观设定滑动窗口的大小和步幅。滑动窗口过小或过大,步幅过大均会降低目标检测的正确率。
  • 每次滑动都要进行一次 CNN 网络计算,如果滑动窗口和步幅较小,计算成本往往很大。

综上,滑动窗口目标检测算法虽然简单,但是性能不佳,效率较低。

4.基于卷积的滑动窗口实现

卷积的滑动窗口实现 Convolutional Implementation of Sliding Windows

滑动窗口目标检测算法可以借助卷积方式实现,以提高运行速度,节约重复运算成本。

我们需要先对CNN网络结构做一些调整,以便对进入网络的「单个滑动窗口区域」更快捷计算,具体做法是把全连接层转变成为卷积层,如下图所示:

基于卷积的滑动窗口实现

我们可以看到,使用与上层尺寸一致的滤波算子进行卷积运算,构建的卷积层就可以替代掉原来的全连接层。最终得到的输出层维度是\( 1 \times 1 \times 4\) ,代表4类输出值。

对于待检测图片,可使用该网络参数和结构进行运算。例如\( 16 \times 16 \times 3\) 的图片,步进长度为2,CNN网络得到的输出层为\( 2 \times 2 \times 4\) 。其中,\( 2 \times 2\) 表示共有4个窗口结果。

基于卷积的滑动窗口实现

对于更复杂的\( 28 \times 28 \times 3\) 的图片,CNN网络得到的输出层为\( 8 \times 8 \times 4\) ,共64个窗口结果。

基于卷积的滑动窗口实现

前面提到的滑动窗口目标检测算法需要反复进行CNN正向计算。例如\( 16 \times 16 \times 3\) 的图片需进行4次,\( 28 \times 28 \times 3\) 的图片需进行\( 64\) 次。

利用卷积操作替代后,不管原始图片有多大,只需要进行一次CNN正向计算,因为其中共享了很多重复计算部分,这大大节约了运算成本。

注意,窗口步进长度与选择的MAX POOL大小有关。如果需要步进长度为4,只需设置MAX POOL为\( 4 \times 4\) 即可。

相关论文:Sermanet et al., 2014. OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks

5.边框预测

Bounding Box预测 Bounding Box Predictions

滑动窗口目标检测算法中,边框的位置可能无法完美覆盖目标(如下图蓝框),或者大小不合适,或者最准确的边框并非正方形,而是长方形。

边框预测

YOLO(You Only Look Once)算法可以用于得到更精确的边框。YOLO 算法将原始图片划分为 \( n \times n\) 网格,并将目标定位一节中提到的图像分类和目标定位算法,逐一应用在每个网格中,每个网格都有标签如:

$$ \left[\begin{matrix}P_c\\ b_x\\ b_y\\ b_h\\ b_w\\ c_1\\ c_2\\ c_3\end{matrix}\right] $$

若某个目标的中点落在某个网格,则该网格负责检测该对象。如果目标中心坐标不在当前网格内,则当前网格\( P_c=0\) ;相反,则当前网格\( P_c=1\) (即只看中心坐标是否在当前网格内)。判断有目标的网格中,限定了目标区域。

边框预测

如上面的示例中,如果将输入的图片划分为 \( 3 \times 3\) 的网格、需要检测的目标有 3 类,则每一网格部分图片的标签会是一个 8 维的列矩阵,最终输出的就是大小为 \( 3 \times 3 \times 8\) 的结果。要得到这个结果,就要训练一个输入大小为 \( 100 \times 100 \times 3\) ,输出大小为 \( 3 \times 3 \times 8\) 的 CNN。在实践中,可能使用更为精细的 \( 19 \times 19\) 网格,则两个目标的中点在同一个网格的概率更小。

YOLO 算法的优点

  • 和图像分类和目标定位算法类似,显式输出边框坐标和大小,不会受到滑窗分类器的步长大小限制。
  • 仍然只进行一次 CNN 正向计算,效率很高,甚至可以达到实时识别。

如何编码边框 \( b_x\) 、\( b_y\) 、\( b_h\) 、\( b_w\) ?YOLO 算法设 \( b_x\) 、\( b_y\) 、\( b_h\) 、\( b_w\) 的值是相对于网格长的比例。则 \( b_x\) 、\( b_y\) 在 0 到 1 之间,而 \( b_h\) 、\( b_w\) 可以大于 1。当然,也有其他参数化的形式,且效果可能更好。这里只是给出一个通用的表示方法。

相关论文:Redmon et al., 2015. You Only Look Once: Unified, Real-Time Object Detection。Ng 认为该论文较难理解。

6.交互比

交并比 Intersection over Union

交互比(IoU, Intersection Over Union)函数用于评价对象检测算法,它计算预测边框和实际边框交集(\( I\) )与并集(\( U\) )之比。

交互比IoU

如上图右侧所示,橙色方框为真实目标区域,蓝色方框为检测目标区域。两块区域的交集为绿色部分,并集为紫色部分。蓝色方框与橙色方框的接近程度可以用IoU比值来定义:

$$ IoU=\frac{I}{U} $$

\( IoU\) 的值在 0~1 之间,且越接近 1 表示目标的定位越准确。\( IoU \ge 0.5\) 时,一般可以认为预测边框是正确的,当然也可以更加严格地要求一个更高的阈值。

7.非极大值抑制

非极大值抑制 Non-max suppression

YOLO 算法中,可能有很多网格检测到同一目标。如下图所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZRO3ZyqS-1649926014941)(http://image.showmeai.tech/de...)]

非极大值抑制(Non-max Suppression)可以解决上述问题。它的做法很简单:

非极大值抑制NMS

  • 上图中每个网格的\( P_c\) 值可以求出,\( P_c\) 值反映了该网格包含目标中心坐标的可信度。
  • 首先选取\( P_c\) 最大值对应的网格和区域,然后计算该区域与所有其它区域的IoU,剔除掉IoU大于阈值(例如0.5)的所有网格及区域。这样就能保证同一目标只有一个网格与之对应,且该网格\( P_c\) 最大,最可信。
  • 接着,再从剩下的网格中选取\( P_c\) 最大的网格,重复上一步的操作。
  • 最后,就能使得每个目标都仅由一个网格和区域对应。如下图所示:

总结非极大值抑制NMS的步骤如下

  • ① 将包含目标中心坐标的可信度 \( P_c\) 小于阈值(例如 0.6)的网格丢弃;
  • ② 选取拥有最大 \( P_c\) 的网格;
  • ③ 分别计算该网格和其他所有网格的 IoU,将 IoU 超过预设阈值的网格丢弃;
  • ④ 重复第 2~3 步,直到不存在未处理的网格。

当然,上面提到的步骤适用于单类别目标检测。如果要进行多个类别目标检测,对于每个类别,应该单独做一次非极大值抑制。

8.Anchor Boxes

Anchor Boxes

到目前为止,我们讨论的情况都是一个网格只检测一个对象。如果要将算法运用在多目标检测上(如下图一个人站在一辆车前面),怎么做呢?这里需要用到 Anchor Boxes。

以下图为例,同一网格出现了两个目标:人和车。为了同时检测两个目标,我们可以设置两个Anchor Boxes:Anchor box 1检测人,Anchor box 2检测车。

Anchor Boxes

对应到网络中,则每个网格多加了一层输出:原来的输出维度是\( 3 \times 3 \times 8\) ,现在是\( 3 \times 3 \times 2 \times 8\) (也可以写成\( 3 \times 3 \times 16\) 的形式)。这里的2表示有两个Anchor Boxes,用来在一个网格中同时检测多个目标。每个Anchor box都有一个\( P_c\) 值,若两个\( P_c\) 值均大于某阈值,则检测到了两个目标。

标签\( y\) 形态为

$$ y=\left [ \begin{matrix} Pc \\ bx \\ by \\ bh \\ bw \\ c1 \\ c2 \\ c3 \\ Pc \\ bx \\ by \\ bh \\ bw \\ c1 \\ c2 \\ c3 \end{matrix} \right] $$

在使用YOLO算法时,只需对每个Anchor box使用上一节的非最大值抑制即可。Anchor Boxes之间并行实现。当然,Anchor Boxes 也有局限性,对于同一网格有三个及以上目标,或者两个目标的 Anchor Box 高度重合的情况处理不好

怎么选择Anchor Boxes

  • 一般手工指定Anchor Boxes形状,可以选择5到10个Anchor Box形状,覆盖到想要检测的对象的各种形状
  • 更高级的是使用k均值算法(更详细算法介绍可以阅读ShowMeAI文章 图解机器学习 | 聚类算法详解),将两类对象形状聚类,选择最具有代表性的一组Anchor Box

9.YOLO 算法

YOLO 算法 Putting it Together: YOLO Algorithm

汇总上面学习到的知识,就得到YOLO算法的流程,算是对前几节内容的回顾。网络结构如下图所示,包含了两个Anchor Boxes。

YOLO 算法

  • ① 对每个网格,预测得到2个bounding box
  • ② 剔除掉概率低的预测结果
  • ③ 对每个类别应用非极大值抑制NMS得到最终结果

10.R-CNN

候选区域  Region Proposals

前面介绍的滑动窗口目标检测算法对一些明显没有目标的区域也进行了扫描(如下图最左下角位置),这降低了算法的运行效率。
为了解决这个问题,R-CNN(Region CNN,带区域的 CNN)被提出。通过对输入图片运行图像分割算法,在不同的色块上找出候选区域(Region Proposal),然后只在这些区域上运行分类器。

R-CNN

R-CNN

R-CNN 的缺点是运行速度很慢,所以有一系列后续研究工作改进。例如 Fast R-CNN(与基于卷积的滑动窗口实现相似,但得到候选区域的聚类步骤依然很慢)、Faster R-CNN(使用卷积对图片进行分割)。不过大多数时候还是比 YOLO 算法慢。RCNN系列的算法也叫做2-stage目标检测算法(因为会先产出后候选框,再预测和调整),YOLO系列的算法叫做1-stage目标检测方法。

相关论文:

R-CNN:Girshik et al., 2013. Rich feature hierarchies for accurate object detection and semantic segmentation

Fast R-CNN:Girshik, 2015. Fast R-CNN

Faster R-CNN:Ren et al., 2016. Faster R-CNN: Towards real-time object detection with region proposal networks

参考资料

ShowMeAI系列教程推荐

推荐文章

阅读 851

ShowMeAI研究中心
为AI硬核资料库(cool)而生!公众号/GitHub:ShowMeAI-Hub
22 声望
10 粉丝
0 条评论
22 声望
10 粉丝
文章目录
宣传栏