NG-DeepLearning-CNN第三周“目标检测”

这一周的内容重点较多,相对不易理解,更是包含了著名的YOLO算法。因此拿出来做个总结。 笔记参照这位大哥 https://github.com/AlbertHG/Coursera-Deep-Learning-deeplearning.ai/tree/master/04-Convolutional%20Neural%20Networks/week3

1. 问题描述:
  • 目标定位(Object localization):定位问题意味着,不仅要用算法判断图片中是不是一辆汽车,还要在图片中标记出它的位置,用边框(Bounding Box)把目标物体圈起来。这类问题中 通常只有一个较大的对象位于图片中间位置。
    在这里插入图片描述
  • 目标检测 (Object detection):图片可以含有多个对象,且单张图片中会有多个不同分类的对象。

对于目标定位和检测问题,为了定位图片中汽车的位置,可以让神经网络可以输出 ( 1 + 4 + n ) (1 + 4 + n) (1+4+n) 个数字,其中,1代表图片中有目标的概率 P c Pc Pc,4用来定位目标,可以用红框的中心点坐标 b x b_x bx b y b_y by和边界框的高和宽 b h b_h bh b w b_w bw来表示。n是待检测的类别数。「将图片左上角标记为 (0, 0),右下角标记为 (1, 1)」

综上,目标的标签 Y Y Y有如下两种形式:

[ P c b x b y b h b w c 1 c 2 c 3 ] , w h e n P c = 1 : [ 1 b x b y b h b w c 1 c 2 c 3 ] , w h e n P c = 0 : [ 0 ? ? ? ? ? ? ? ] \left[\begin{matrix}P_c\\ b_x\\ b_y\\ b_h\\ b_w\\ c_1\\ c_2\\ c_3\end{matrix}\right] ,when P_c=1:\left[\begin{matrix}1\\ b_x\\ b_y\\ b_h\\ b_w\\ c_1\\ c_2\\ c_3\end{matrix}\right] ,when P_c=0:\left[\begin{matrix}0\\ ?\\ ?\\ ?\\ ?\\ ?\\ ?\\ ?\end{matrix}\right] Pcbxbybhbwc1c2c3,whenPc=1:1bxbybhbwc1c2c3,whenPc=0:0???????
P c P_c Pc=0,表示没有检测到目标,则输出label后面的7个参数都可以忽略(用 ? 来表示)。

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

P c = 1 P_c=1 Pc=1,即 y 1 = 1 y_1=1 y1=1

L ( y ^ , y ) = ( y ^ 1 − y 1 ) 2 + ( y ^ 2 − y 2 ) 2 + ⋯ + ( y ^ 8 − y 8 ) 2 L(\hat y,y)=(\hat y_1-y_1)^2+(\hat y_2-y_2)^2+\cdots+(\hat y_8-y_8)^2 L(y^,y)=(y^1y1)2+(y^2y2)2++(y^8y8)2

损失值就是不同元素的平方和。

P c = 0 P_c=0 Pc=0,即 y 1 = 0 y_1=0 y1=0

L ( y ^ , y ) = ( y ^ 1 − y 1 ) 2 L(\hat y,y)=(\hat y_1-y_1)^2 L(y^,y)=(y^1y1)2

对于这种情况,不用考虑其它元素,只需要关注神经网络输出的准确度即可。

  • 特征点检测(Landmark detection): 神经网络可以像标识目标的中心点位置那样,通过输出图片上的特征点,来实现对目标特征的识别。在标签中,这些特征点以多个二维坐标的形式表示。
    举个例子:假设需要定位一张人脸图像,同时检测其中的64个特征点,这些点可以帮助我们定位眼睛、嘴巴等人脸特征。
    具体的做法:准备一个卷积网络和一些特征集,将人脸图片输入卷积网络,输出1或0(1表示有人脸,0表示没有人脸)并输出 ( l 1 x , l 1 y ) (l_{1x},l_{1y}) (l1x,l1y) ……直到 ( l 64 x , l 64 y ) (l_{64x},l_{64y}) (l64x,l64y)。这里用 l l l代表一个特征,此例中有129个输出单元,其中1表示图片中有人脸,128表示64个特征点的坐标,由此实现对图片的人脸检测和定位。

2. 基于滑动窗口的目标检测(Sliding Windows Detection)

构造训练集:

  1. 训练集X:将有汽车的图片进行适当的剪切,剪切成整张几乎都被汽车占据的小图或者没有汽车的小图;
  2. 训练集Y:对X中的图片进行标注,有汽车的标注1,没有汽车的标注0。

使用符合上述要求的这些训练集构建CNN模型,可使得模型有较高的识别率。接着选择大小适宜的窗口与合适的固定步幅,对测试图片进行从左到右、从上倒下的滑动遍历。每个窗口区域使用已经训练好的 CNN 模型进行识别判断。随后可以选择更大的窗口,并重复遍历+识别的操作。

滑动窗算法的优点是原理简单,且不需要人为选定目标区域(检测出目标的滑动窗即为目标区域)。但是其缺点也很明显,首先滑动窗的大小和步进长度都需要人为直观设定。滑动窗过小或过大,步进长度过大均会降低目标检测正确率。每次滑动窗区域都要进行一次CNN网络计算,如果滑动窗和步进长度较小,整个目标检测的算法运行时间会很长。所以,滑动窗算法虽然简单,但是性能不佳,不够快,不够灵活。

  • 滑动窗口的卷积实现:滑动窗算法可以使用卷积方式实现,以提高运行速度,节约重复运算成本。
    • 单个滑动窗口区域进入CNN网络模型时,包含全连接层。滑动窗口算法卷积实现的第一步就是将全连接层转变成为卷积层,如下图所示,使用与上层尺寸一致的滤波算子进行卷积运算:
      在这里插入图片描述
    • 我们无需自己去滑动窗口截取图片的一小部分然后检测,卷积可以自动实现滑动窗口。

如下图中间一行卷积的初始图,我们假设输入的图像是16 x 16 x 3的,而窗口大小是14 x 14 x 3,我们要做的是把蓝色区域输入卷积网络,生成0或1分类,接着向右滑动2个元素,形成的区域输入卷积网络,生成0或1分类,然后接着滑动,重复操作。我们在16 x 16 x 3的图像上卷积了4次,输出了4个标签,这4次卷积里很多计算是重复的。
在这里插入图片描述
而实际上,我们可以直接对这个16 x 16 x 3的图像进行卷积,如上图中间一行的卷积的整个过程,这个卷积实际上涵盖了先前提到的重复计算,其中蓝色的区域就是先前用来卷积的第一块区域,到最后它变成了2 x 2 x 4的块的左上角那一块,最后的输出为2 x 2=4个,分别对应先前输出的4个标签。

因此我们不需要把原图分成四个部分,分别用卷积去检测,而是把它们作为一张图片输入给卷积网络进行计算,其中的公有区域可以共享很多计算。

同理,当图片大小是28 x 28 x 3的时候,CNN网络得到的输出层为8 x 8 x 4,共64个窗口结果。( 28 − 14 2 + 1 = 8 \frac{28-14}{2} + 1 = 8 22814+1=8)

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

3. 边界框的预测

卷积方式实现的滑动窗口算法使得预测时计算效率大大提高。但是其存在的问题是:不能输出最精准的边界框(Bounding Box)
YOLO(You Only Look Once)算法可以解决这类问题,生成更加准确的目标区域(如下图红色窗口)。
YOLO
YOLO算法首先将原始图片分割成n x n网格,每个网格代表一块区域。为简化说明,上图中将图片分成3 x 3网格。

然后,利用卷积形式实现滑动窗口算法的思想,对该原始图片构建CNN网络,得到的的输出层维度为3 x 3 x 8。其中,3 x 3对应9个网格,每个网格的输出包含8个元素: y = [ P c b x b y b h b w c 1 c 2 c 3 ] y=\left[\begin{matrix}P_c\\ b_x\\ b_y\\ b_h\\ b_w\\ c_1\\ c_2\\ c_3\end{matrix}\right] y=Pcbxbybhbwc1c2c3

如果目标中心坐标 ( b x , b y ) (b_x,b_y) (bx,by) 不在当前网格内,则当前网格Pc=0;相反,则当前网格 P c = 1 P_c=1 Pc=1(即只看中心坐标是否在当前网格内)。判断有目标的网格中, b x , b y , b h , b w b_x,b_y,b_h,b_w bx,by,bh,bw 限定了目标区域。

值得注意的是,当前网格左上角坐标设定为 ( 0 , 0 ) (0, 0) (0,0),右下角坐标设定为 ( 1 , 1 ) (1, 1) (1,1) ( b x , b y ) (b_x,b_y) (bx,by) 表示坐标值,范围限定在 [ 0 , 1 ] [0,1] [0,1]之间,但是 b h , b w b_h,b_w bh,bw 可以大于 1。因为目标可能超出该网格,横跨多个区域。目标可以占据多个网格,但目标中心坐标必然在一个网格之内。

划分的网格可以更密一些。网格越小,则多个目标的中心坐标被划分到一个网格内的概率就越小,这恰恰是我们希望看到的。

总结: YOLO的做法和图像分类和定位算法非常像,它显式地输出边界框坐标,所以这能让神经网络输出边界框,可以具有任意宽高比,并且能输出更精确的坐标,不会受到滑动窗口分类器的步长大小限制。而且,这是一个卷积实现,你并没有在3 × 3网格上跑9次算法,而是单次卷积实现,共享了和多计算步骤,这保证了YOLO算法的高效。

4. 非极大值抑制 (Non-Max Suppression)

对于汽车目标检测的例子中,若我们将图片分成很多精细(19*19)的格子。最终预测输出的结果中,可能会有相邻的多个格子里均检测出都具有同一个对象。非极大值抑制依据各边界框和拥有最大 P c Pc Pc的边界框的交并比来作出判断。在这里插入图片描述

  • 交并比(Intersection over union): 如图所示,红色方框为真实目标区域,蓝色方框为检测目标区域。两块区域的交集为绿色部分,并集为紫色部分。蓝色方框与红色方框的接近程度可以用IoU比值来定义: I o U = I U IoU=\frac{I}{U} IoU=UI
    在这里插入图片描述
    IoU可以表示任意两块区域的接近程度。IoU值介于0~1之间,且越接近1表示两块区域越接近。一般在目标检测任务中,约定如果 I o U > = 0.5 IoU>=0.5 IoU>=0.5 ,那么就说明检测正确。当然标准越大,则对目标检测算法越严格。得到的IoU值越大越好。

在这里插入图片描述
以上图为例来说明非极大值抑制的过程:

  1. 只保留每一个概率高( P c > = 0.6 P_c>=0.6 Pc>=0.6)的格子,此处共有5个格子有高概率检测出目标,分别是0.8、0.7、0.9、0.6、0.7。
  2. 找出极大值0.9,以该格子预测出的边界框为目标,其余边界框分别与其求交并比。此处,右边概率为0.6和0.7的边界框与之交并比较大,因此将这两个格子的预测结果舍弃。
  3. 找出剩余概率中的极大值,此处为左边的0.8,用相同的方法舍弃0.7的那个预测结果。

非极大值意味着只输出概率最大的分类结果,同时抑制那些概率不是极大值,却在边界框预测结果上比较接近极大值预测结果的边界框。上述是单对象检测,对于多对象检测,输出标签中就会有多个分量。正确的做法是:对每个输出类别分别独立进行一次非极大值抑制。

5. Anchor Boxes

到目前为止,我们介绍的都是一个网格至多只能检测一个目标。那对于多个目标重叠的情况,例如一个人站在一辆车前面,该如何使用YOLO算法进行检测呢?方法是使用不同形状的Anchor Boxes。
在这里插入图片描述
如图所示,同一网格出现了两个目标:人和车。为了同时检测两个目标,我们可以设置两个Anchor Boxes,Anchor box 1检测人,Anchor box 2检测车。即每个网格多加了一层输出。原来的输出维度是 3 x 3 x 8,现在是3 x 3 x 2 x 8(也可以写成3 x 3 x 16的形式)。这里的2表示有两个Anchor Boxes,用来在一个网格中同时检测多个目标。每个Anchor box都有一个 P c P_c Pc值,若两个 P c P_c Pc值均大于某阈值,则检测到了两个目标。

对于重叠的目标,这些目标的中点有可能会落在同一个网格中,对于我们之前定义的输出: y i = [ P c   b x   b y   b h   b w   c 1   c 2   c 3 ] T y_{i} = \left[ \begin{array}{l} P_{c}\ b_{x}\ b_{y}\ b_{h}\ b_{w}\ c_{1}\ c_{2}\ c_{3} \end{array} \right]^T yi=[Pc bx by bh bw c1 c2 c3]T ,只能得到一个目标的输出。而Anchor box 则是预先定义多个不同形状的Anchor box,我们需要把预测目标对应地和各个Anchor box 关联起来,所以我们重新定义目标向量:

y i = [ 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 ⋯   ] T y_{i} = \left[ 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}\cdots\right]^T yi=[Pc bx by bh bw c1 c2 c3 Pc bx by bh bw c1 c2 c3]T

用这样的多目标向量分别对应不同的Anchor box,从而检测出多个重叠的目标。

以刚才的图为例,里面有行人和汽车,在经过了极大值抑制操作之后,最后保留了两个边界框(Bounding Box)。行人形状更接近Anchor box 1,汽车形状更接近Anchor box 2,所以我们将人和汽车分配到不同的输出位置。

如何判断边界框和哪个Anchor box匹配

  • 将边界框和Anchor box进行交并比计算,将交并比高的边界框和Anchor box组队。

当然,如果格子中只有汽车的时候,我们使用了两个Anchor box,那么此时我们的目标向量就成为: y i = [ 0   ?   ?   ?   ?   ?   ?   ?   1   b x   b y   b h   b w   0   1   0 ] T y_{i} = \left[ 0\ ?\ ?\ ?\ ?\ ?\ ?\ ?\ 1\ b_{x}\ b_{y}\ b_{h}\ b_{w}\ 0\ 1\ 0\right]^T yi=[0 ? ? ? ? ? ? ? 1 bx by bh bw 0 1 0]T, 其中,“?”代表的是该位置是什么样的参数我们都不关心。

难点问题:
如果我们使用了两个Anchor box,但是同一个格子中却有三个对象的情况,此时只能用一些额外的手段来处理;同一个格子中存在两个对象,但它们的Anchor box 形状相同,此时也需要引入一些专门处理该情况的手段。 但是以上的两种问题出现的可能性不会很大,对目标检测算法不会带来很大的影响。

Anchor box 的选择

  • 一般人工指定Anchor box 的形状,选择5~10个以覆盖到多种不同的形状,可以涵盖我们想要检测的对象的形状;
  • 高级方法:K-means 算法:将不同对象形状进行聚类,用聚类后的结果来选择一组最具代表性的Anchor box,以此来代表我们想要检测对象的形状。

6. 整套YOLO算法

将上述关于YOLO算法组件组装在一起构成YOLO对象检测算法。

假设我们要在图片中检测三种目标:行人、汽车和摩托车,同时使用两种不同的Anchor box。

  1. 构造训练集:根据工程目标,将训练集做如下规划。
  • 输入X:同样大小的完整图片;
  • 目标Y:使用 3 × 3 3\times3 3×3 网格划分,输出大小 3 × 3 × 2 × 8 3\times3\times2\times8 3×3×2×8(其中3 × 3表示3×3个网格,2是anchor box的数量,8是向量维度) ,或者 3 × 3 × 16 3\times3\times16 3×3×16
  • 对不同格子中的小图,定义目标输出向量Y,如下图示例。
    • 对于格子1的目标y就是这样的 y = [ 0   ?   ?   ?   ?   ?   ?   ?   0   ?   ?   ?   ?   ?   ?   ? ] T y = \left[ 0\ ?\ ?\ ?\ ?\ ?\ ?\ ?\ 0\ ?\ ?\ ?\ ?\ ?\ ?\ ?\right]^T y=[0 ? ? ? ? ? ? ? 0 ? ? ? ? ? ? ?]T
    • 而对于格子2的目标y则应该是这样: y = [ 0   ?   ?   ?   ?   ?   ?   ?   1   b x   b y   b h   b w   0   1   0 ] T y = \left[ 0\ ?\ ?\ ?\ ?\ ?\ ?\ ?\ 1\ b_{x}\ b_{y}\ b_{h}\ b_{w}\ 0\ 1\ 0\right]^T y=[0 ? ? ? ? ? ? ? 1 bx by bh bw 0 1 0]T
    • 训练集中,对于车子有这样一个边界框(编号3),水平方向更长一点。所以若有两个anchor boxes,anchor box 1(编号4)和anchor box 2(编号5),红框和anchor box 2的交并比更高,那么车子就和向量的下半部分相关。要注意,这里和anchor box 1有关的 P c P_c Pc是0,剩下这些分量我们就都不关心;对于anchor box 2,由于 P c P_c Pc是1,所以用( b x , b y , b h , b w b_x,b_y,b_h,b_w bx,by,bh,bw)来指定红边界框的位置。
      在这里插入图片描述
  1. 模型预测:输入与训练集中相同大小的图片,同时得到每个格子中不同的输出结果: 3 × 3 × 2 × 8 3\times3\times2\times8 3×3×2×8 。 输出的预测值,以下图为例:
  • 左上的格子(编号1)对应输出预测y(编号3)
  • 中下的格子(编号2)对应输出预测y(编号4)
    在这里插入图片描述
  1. 运行非最大值抑制(NMS)(为展示效果,换一张复杂的图):
  • step1: 假设使用了2个Anchor box,那么对于每一个网格,我们都会得到预测输出的2个bounding boxes,其中一个 P c P_c Pc比较高;
  • step2: 抛弃概率 P c P_c Pc值低的预测bounding boxes;
  • step3: 对每个对象(如行人、汽车、摩托车)分别使用NMS算法得到最终的预测边界框。
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值