第三周 目标检测(Object detection)

3.1 目标定位(Object localization)

定位分类问题:不仅要用算法判断图片中是不是一辆汽车,还要在图片中标记出它的位置,用边框或红色方框把汽车圈起来,“定位”的意思是判断汽车在图片中的具体位置

定位分类问题通常只有一个较大的对象位于图片中间位置,对它进行识别和定位。对象检测问题中图片可以含有多个对象,甚至单张图片中会有多个不同分类的对象

构建汽车自动驾驶系统,对象可能包括以下几类:行人、汽车、摩托车和背景

定位图片中汽车的位置:让神经网络输出一个边界框,标记为bxb_{x},byb_{y},bhb_{h}bwb_{w},是被检测对象的边界框的参数化表示

红色方框的中心点表示为(bxb_{x},byb_{y}),边界框的高度为bhb_{h},宽度为bwb_{w}。训练集不仅包含神经网络要预测的对象分类标签,还要包含表示边界框的这四个数字,接着采用监督学习算法,输出一个分类标签,还有四个参数值,从而给出检测对象的边框位置

如何为监督学习任务定义目标标签 yy

目标标签yy的定义:y=[pcbxbybhbwc1c2c3]y= \begin{bmatrix} p_{c} \\ b_{x} \\ b_{y}\\ b_{h}\\ b_{w} \\ c_{1}\\ c_{2}\\ c_{3} \end{bmatrix}

pcp_{c}表示是否含有对象,如果对象属于前三类(行人、汽车、摩托车),则pc=1p_{c}= 1,如果是背景,则pc=0p_{c} =0pcp_{c}表示被检测对象属于某一分类的概率,背景分类除外

如果检测到对象,就输出被检测对象的边界框参数bxb_{x}byb_{y}bhb_{h}bwb_{w}pc=1p_{c}=1,同时输出c1c_{1}c2c_{2}c3c_{3},表示该对象属于行人,汽车还是摩托车

如果图片中没有检测对象:

pc=0p_{c} =0yy的其它参数全部写成问号,表示“毫无意义”的参数

神经网络的损失函数,如果采用平方误差策略:

L(y^,y)=(y1^y1)2+(y2^y2)2++(y8^y8)2L\left(\hat{y},y \right) = \left( \hat{y_1} - y_{1} \right)^{2} + \left(\hat{y_2} - y_{2}\right)^{2} + \ldots+\left( \hat{y_8} - y_{8}\right)^{2}

损失值等于每个元素相应差值的平方和

如果图片中存在定位对象,y1=pc=1y_{1} =p_{c}=1,损失值是不同元素的平方和

y1=pc=0y_{1}= p_{c} = 0,损失值是(y1^y1)2\left(\hat{y_1} - y_{1}\right)^{2},只需要关注神经网络输出pcp_{c}的准确度

这里用平方误差简化了描述过程。实际应用中可以不对c1c_{1}c2c_{2}c3c_{3}softmax激活函数应用对数损失函数,并输出其中一个元素值,通常做法是对边界框坐标应用平方差,对pcp_{c}应用逻辑回归函数,甚至采用平方预测误差

3.2 特征点检测(Landmark detection)

仅对目标的关键特征点坐标进行定位,这些关键点被称为landmarks

选定特征点个数,并生成包含特征点的标签训练集,利用神经网络输出脸部关键特征点的位置

具体做法:准备一个卷积网络和一些特征集,将人脸图片输入卷积网络,输出1表示有人脸,0表示没有人脸,然后输出(l1xl_{1x}l1yl_{1y})……直到(l64xl_{64x}l64yl_{64y}),ll代表一个特征,即该网络模型共检测人脸上64处特征点,加上是否为face的标志位,输出label共有64x2+1=129个值,即有129个输出单元,由此实现对图片的人脸检测和定位

检测人体姿势动作:

特征点的特性在所有图片中必须保持一致

3.3 目标检测(Object detection)

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

构建汽车检测算法步骤:

  1. 首先创建一个标签训练集,xxyy表示适当剪切的汽车图片样本,一开始可以使用适当剪切的图片,就是整张图片xx几乎都被汽车占据,使汽车居于中间位置,并基本占据整张图片

  2. 开始训练卷积网络,输入这些适当剪切过的图片(编号6),卷积网络输出yy,0或1表示图片中有汽车或没有汽车

训练完这个卷积网络,用它来实现滑动窗口目标检测,具体步骤如下:

1.首先选定一个特定大小的窗口,将红色小方块输入卷积神经网络,卷积网络开始判断红色方框内有没有汽车

2.滑动窗口目标检测算法继续处理第二个图像,红色方框稍向右滑动之后的区域,并输入给卷积网络,再次运行卷积网络,然后处理第三个图像,依次重复操作,直到这个窗口滑过图像的每一个角落

思路是以固定步幅移动窗口,遍历图像的每个区域,把这些剪切后的小图像输入卷积网络,对每个位置按0或1进行分类

3.重复上述操作,选择一个更大的窗口,截取更大的区域,并输入给卷积神经网络处理,输出0或1

4.再以某个固定步幅滑动窗口,重复以上操作,遍历整个图像,输出结果

5.第三次重复操作,选用更大的窗口

这样不论汽车在图片的什么位置,总有一个窗口可以检测到

这种算法叫作滑动窗口目标检测:以某个步幅滑动这些方框窗口遍历整张图片,对这些方形区域进行分类,判断里面有没有汽车

滑动窗口目标检测算法缺点:计算成本

  • 如果选用的步幅很大,会减少输入卷积网络的窗口个数,粗糙间隔尺寸可能会影响性能

  • 如果采用小粒度或小步幅,传递给卷积网络的小窗口会特别多,这意味着超高的计算成本

3.4 卷积的滑动窗口实现(Convolutional implementation of sliding windows)

把神经网络的全连接层转化成卷积层

前几层和之前的一样,下一层全连接层用5×5×16的过滤器来实现,数量是400个(编号1),输入图像大小为5×5×16,输出维度是1×1×400,这400个节点中每个节点都是上一层5×5×16激活值经过某个任意线性函数的输出结果

再添加另外一个卷积层(编号2),用1×1卷积,假设有400个1×1的过滤器,在这400个过滤器的作用下,下一层的维度是1×1×400,是上个网络中的这一全连接层经由1×1过滤器的处理,得到一个softmax激活值,通过卷积网络,最终得到1×1×4的输出层,而不是这4个数字(编号3)

以上就是用卷积层代替全连接层的过程,结果这几个单元集变成了1×1×400和1×1×4的维度

通过卷积实现滑动窗口对象检测算法

假设向滑动窗口卷积网络输入14×14×3的图片,神经网络最后的输出层,即softmax单元的输出是1×1×4

假设测试集图片是16×16×3,给输入图片加上黄色条块,在最初的滑动窗口算法中,把蓝色区域输入卷积网络(红色笔标记)生成0或1分类。接着滑动窗口,步幅为2个像素,向右滑动2个像素,将绿框区域输入给卷积网络,运行整个卷积网络,得到另外一个标签0或1。继续将这个橘色区域输入给卷积网络,卷积后得到另一个标签,最后对右下方的紫色区域进行最后一次卷积操作。在这个16×16×3的小图像上滑动窗口,卷积网络运行了4次,于是输出了了4个标签

这4次卷积操作中很多计算都是重复的。执行滑动窗口的卷积时使得卷积网络在这4次前向传播过程中共享很多计算,尤其是在编号1,卷积网络运行同样的参数,使用相同的5×5×16过滤器进行卷积操作,得到12×12×16的输出层。然后执行同样的最大池化(编号2),输出结果6×6×16。照旧应用400个5×5的过滤器(编号3),得到一个2×2×400的输出层,现在输出层为2×2×400,应用1×1过滤器(编号4)得到另一个2×2×400的输出层。再做一次全连接的操作(编号5),最终得到2×2×4的输出层,在输出层4个子方块中,蓝色的是图像左上部分14×14的输出(红色箭头标识),右上角方块是图像右上部分(绿色箭头标识)的对应输出,左下角方块是输入层左下角(橘色箭头标识),右下角是卷积网络处理输入层右下角14×14区域(紫色箭头标识)的结果

具体的计算步骤:以绿色方块为例,假设剪切出这块区域(编号1),传递给卷积网络,第一层的激活值就是这块区域(编号2),最大池化后的下一层的激活值是这块区域(编号3),这块区域对应着后面几层输出的右上角方块(编号4,5,6)

该卷积操作的原理是不需要把输入图像分割成四个子集,分别执行前向传播,而是把它们作为一张图片输入给卷积网络进行计算,其中的公共区域可以共享很多计算

假如对一个28×28×3的图片应用滑动窗口操作,以14×14区域滑动窗口,以大小为2的步幅不断地向右移动窗口,直到第8个单元格,得到输出层的第一行。然后向图片下方移动,最终输出8×8×4的结果

总结滑动窗口的实现过程:

在图片上剪切出一块区域,假设大小是14×14,把它输入到卷积网络。继续输入下一块区域,大小同样是14×14,重复操作,直到某个区域识别到汽车

但是不能依靠连续的卷积操作来识别图片中的汽车,可以对大小为28×28的整张图片进行卷积操作,一次得到所有预测值,如果足够幸运,神经网络便可以识别出汽车的位置

在卷积层上应用滑动窗口算法提高了整个算法的效率,缺点是边界框的位置可能不够准确

3.5 Bounding Box预测(Bounding box predictions)

滑动窗口法的卷积实现算法效率很高,但不能输出最精准的边界框

输入图像是100×100的,用3×3网格,实际实现时会用更精细的网格(19×19)。使用图像分类和定位算法

编号1什么也没有,左上格子的标签向量yy[0 ? ? ? ? ? ? ?]\begin{bmatrix}0\ ?\ ?\ ?\ ?\ ?\ ?\ ? \end{bmatrix}。其他什么也没有的格子都一样

图中有两个对象,YOLO算法做的是取两个对象的中点,将对象分配给包含对象中点的格子。即使中心格子(编号5)同时有两辆车的一部分,分类标签yy也为y=[0 ? ? ? ? ? ? ?]y= \begin{bmatrix}0\ ?\ ?\ ?\ ?\ ?\ ?\ ? \end{bmatrix}。编号4目标标签y=[1 bx by bh bw 0 1 0]y= \begin{bmatrix} 1\ b_{x}\ b_{y}\ b_{h}\ b_{w}\ 0\ 1\ 0 \end{bmatrix},编号6类似

3×3中9个格子都对应一个8维输出目标向量yy,其中一些值可以是dont care-s(即?)所以总的目标输出尺寸就是3×3×8

如果要训练一个输入为100×100×3的神经网络,输入图像通过普通的卷积网络,卷积层,最大池化层等等,最后映射到一个3×3×8输出尺寸。然后用反向传播训练神经网络,将任意输入xx映射到输出向量yy

这个算法的优点在于神经网络可以输出精确的边界框,测试的时候有要做的是喂入输入图像xx,然后跑正向传播,直到得到输出yy。然后3×3位置对应的9个输出,只要每个格子中对象数目没有超过1个,这个算法应该是没问题的。但实践中会使用更精细的19×19网格,输出就是19×19×8,多个对象分配到同一个格子得概率就小得多

即使对象可以横跨多个格子,也只会被分配到9个格子其中之一,或者19×19网络的其中一个格子。在19×19网格中,两个对象的中点(图中蓝色点所示)处于同一个格子的概率就会更低。

优点:

  • 显式地输出边界框坐标,可以具有任意宽高比,并且能输出更精确的坐标,不会受到滑动窗口分类器的步长大小限制

  • 并没有在3×3网格上跑9次算法,而是单次卷积实现,但在处理这3×3计算中很多计算步骤是共享的,所以这个算法效率很高

  • 因为是卷积实现,运行速度非常快,可以达到实时识别

如何编码这些边界框bxb_{x}byb_{y}bhb_{h}bwb_{w}

YOLO算法中,编号1约定左上点是(0,0)(0,0),右下点是(1,1)(1,1),橙色中点的位置bxb_{x}大概是0.4,byb_{y}大概是0.3,bwb_{w}是0.9,bhb_{h}是0.5。bxb_{x}byb_{y}bhb_{h}bwb_{w}单位是相对于格子尺寸的比例,所以bxb_{x}byb_{y}必须在0和1之间,因为从定义上看,橙色点位于对象分配到格子的范围内,如果它不在0和1之间,即它在方块外,那么这个对象就应该分配到另一个格子上。这个值(bhb_{h}bwb_{w})可能会大于1,特别是如果有一辆汽车的边界框是这样的(编号3所示),那么边界框的宽度和高度有可能大于1

3.6 交并比(Intersection over union)

并交比函数可以用来评价对象检测算法

交并比(loU)函数是计算两个边界框交集和并集之比。两个边界框的并集是两个边界框绿色阴影区域,而交集是这个橙色阴影区域,交并比就是交集的大小(橙色阴影面积)除以绿色阴影的并集面积

一般约定,在计算机检测任务中,如果loU≥0.5,就说检测正确,如果预测器和实际边界框完美重叠,loU就是1,因为交集就等于并集

3.7 非极大值抑制(Non-max suppression)

对象检测中的一个问题是算法可能对同一个对象做出多次检测,非极大值抑制可以确保算法对每个对象只检测一次

实践中当运行对象分类和定位算法时,对于每个格子都运行一次,编号1、2、3可能会认为这辆车中点应该在格子内部

这个算法做的是:

1.首先看哪个检测结果相关的概率pcp_{c}(实际上是pcp_{c}乘以c1c_{1}c2c_{2}c3c_{3})概率最大,右边车辆中是0.9,即最可靠的检测,用高亮标记,之后非极大值抑制逐一审视剩下的矩形,所有和这个最大的边框有很高交并比,高度重叠的其他边界框输出就会被抑制

2.逐一审视剩下的矩形,找出概率pcp_{c}最高的一个,在这种情况下是0.8,就认为检测出一辆车(左边车辆),然后非极大值抑制算法就会去掉其他loU值很高的矩形。现在每个矩形都会被高亮显示或者变暗,如果直接抛弃变暗的矩形,就剩下高亮显示的那些是最后得到的两个预测结果

非最大值意味着只输出概率最大的分类结果,但抑制很接近,不是最大的其他预测结果

算法的细节:

首先在19×19网格上执行算法,会得到19×19×8的输出尺寸。简化成只做汽车检测,会得到输出预测概率(pcp_{c})和边界框参数(bxb_{x}byb_{y}bhb_{h}bwb_{w}

1.将所有的预测值pcp_{c}小于或等于某个阈值,如pc0.6p_{c}\le 0.6的边界框去掉

2.剩下的边界框就一直选择概率pcp_{c}最高的边界框,把它输出成预测结果,取一个边界框,让它高亮显示,就可以确定输出有一辆车的预测

3.去掉所有剩下的边界框

如果同时检测三个对象,比如说行人、汽车、摩托,输出向量就会有三个额外的分量。正确的做法是独立进行三次非极大值抑制,对每个输出类别都做一次

3.8 Anchor Boxes

对象检测存在的一个问题是每个格子只能检测出一个对象,如果想让一个格子检测出多个对象,可以使用anchor box

行人的中点和汽车的中点都落入到同一个格子中

anchor box的思路是:预先定义两个不同形状的anchor box,把预测结果和这两个anchor box关联起来

定义类别标签:

y=[pcbxbybhbwc1c2c3pcbxbybhbwc1c2c3]Ty= \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}^{T}

前面的pc,bx,by,bh,bw,c1,c2,c3p_{c},b_{x},b_{y},b_{h},b_{w},c_{1},c_{2},c_{3}(绿色方框标记的参数)是和anchor box 1关联的8个参数,后面的8个参数(橙色方框标记的元素)是和anchor box 2相关联

行人:pc=1,bx,by,bh,bw,c1=1,c2=0,c3=0p_{c}= 1,b_{x},b_{y},b_{h},b_{w},c_{1} = 1,c_{2} = 0,c_{3} = 0

车子的边界框更像anchor box 2,(pc=1,bx,by,bh,bw,c1=0,c2=1,c3=0p_{c}= 1,b_{x},b_{y},b_{h},b_{w},c_{1} = 0,c_{2} = 1,c_{3} = 0)

现在每个对象都分配到对象中点所在的格子中,以及分配到和对象形状交并比最高的anchor box中。然后观察哪个anchor box和实际边界框(编号1,红色框)的交并比更高

编号1对应同时有车和行人,编号3对应只有车:

:

anchor box是为了处理两个对象出现在同一个格子的情况,实践中这种情况很少发生,特别用的是19×19网格

怎么选择anchor box:

  • 一般手工指定anchor box形状,可以选择5到10个anchor box形状,覆盖到想要检测的对象的各种形状

  • 更高级的是使用k-平均算法,将两类对象形状聚类,选择最具有代表性的一组anchor box

3.9 YOLO 算法(Putting it together: YOLO algorithm)

假设要在图片中检测行人、汽车,同时使用两种不同的Anchor box

训练集:

  • 输入X:同样大小的完整图片

  • 目标Y:使用3×33\times3网格划分,输出大小3×3×2×83\times3\times2\times8,或者3×3×163\times3\times16

  • 对不同格子中的小图,定义目标输出向量Y

编号2目标向量y=[0???????1bxbybhbw010]Ty =\begin{bmatrix} 0 & ? & ? & ? & ? & ? & ? & ? & 1 & b_{x} & b_{y} & b_{h} &b_{w} & 0 & 1 & 0 \end{bmatrix}^{T},假设训练集中对于车子有一个边界框(编号3),水平方向更长一点,红框和anchor box 2的交并比更高,车子和向量的下半部分相关

模型预测:

输入与训练集中相同大小的图片,然后训练一个卷积网络,遍历9个格子,得到每个格子中不同的输出结果:3×3×2×83\times3\times2\times8

运行非最大值抑制(NMS):

  1. 假设使用了2个Anchor box,每一个网格都会得到预测输出的2个bounding boxes,其中一个PcP_{c}比较高

  2. 抛弃概率PcP_{c}值低的预测bounding boxes

  3. 对每个对象分别使用NMS算法得到最终的预测边界框

如果有三个对象检测类别,希望检测行人,汽车和摩托车:对于每个类别单独运行非极大值抑制,处理预测结果所属类别的边界框,用非极大值抑制来处理行人类别、车子类别、摩托车类别,运行三次来得到最终的预测结果

3.10 候选区域(选修)(Region proposals (Optional))

滑动窗法会对原始图片的每个区域都进行扫描,即使是一些空白的或明显没有目标的区域,这样会降低算法运行效率,耗费时间

R-CNN算法,即带区域的卷积网络,或者带区域的CNN。这个算法尝试选出一些区域,在少数窗口上运行卷积网络分类器

选出候选区域的方法是运行图像分割算法,找出各个尺度的色块,然后在色块上运行分类器,即首先得到候选区域,然后再分类

R-CNN算法很慢,基本的R-CNN算法是使用某种算法求出候选区域,然后对每个候选区域运行一下分类器,每个区域会输出一个标签,有没有车子、行人、摩托车?并输出一个边界框,就能在确实存在对象的区域得到一个精确的边界框

R-CNN算法不会直接信任输入的边界框,也会输出一个边界框bxb_{x}byb_{y}bhb_{h}bwb_{w},这样得到的边界框比较精确,比单纯使用图像分割算法给出的色块边界要好

Fast R-CNN算法基本上是R-CNN算法,最初的算法是逐一对区域分类,快速R-CNN用的是滑动窗法的一个卷积实现,和3.4 卷积的滑动窗口实现的相似,显著提升了R-CNN的速度,问题是得到候选区域的聚类步骤仍然非常缓慢

更快的R-CNN算法(Faster R-CNN),使用的是卷积神经网络,而不是更传统的分割算法来获得候选区域色块,比Fast R-CNN算法快得多

不过大多数更快R-CNN的算法实现还是比YOLO算法慢很多

Last updated

Was this helpful?