2020-9-7 吴恩达DL学习-C4 卷积神经网络-第三周 目标检测(3.5 Bounding Box预测--YOLO算法,通过卷积实现,速度快)

274 篇文章 24 订阅
233 篇文章 0 订阅

1.视频网站:mooc慕课https://mooc.study.163.com/university/deeplearning_ai#/c
2.详细笔记网站(中文):http://www.ai-start.com/dl2017/
3.github课件+作业+答案:https://github.com/stormstone/deeplearning.ai

3.5 Bounding Box预测 Bounding box predictions

在上一节课中,你们学到了滑动窗口法的卷积实现,这个算法效率更高,但仍然存在问题,不能输出最精准的边界框。在这节课中,我们看看如何得到更精准的边界框。
在这里插入图片描述

在上图中滑动窗口法中,你取这些离散的位置集合,然后在它们上运行分类器,在这种情况下,这些边界框没有一个能完美匹配汽车位置,也许这个框(编号1)是最匹配的了。

还有图中红色方框所示看起来这个真实值,最完美的边界框甚至不是方形,长宽比有点向水平方向延伸,有没有办法让这个算法输出更精准的边界框呢?

其中一个能得到更精准边界框的算法是YOLO算法,YOLO(You only look once)意思是你只看一次,这是由Joseph Redmon,Santosh Divvala,Ross Girshick和Ali Farhadi提出的算法。
在这里插入图片描述

如上图,你的输入图像是100×100的。
在这里插入图片描述

然后在图像上放一个网格。为了介绍起来简单一些,我用3×3网格,实际实现时会用更精细的网格,可能是19×19。

基本思路是使用图像分类和定位算法,前几节课绍过的。然后将算法应用到9个格子上。基本思路是,采用图像分类和定位算法,本周第一节课中介绍过的,逐一应用在图像的9个格子中。
在这里插入图片描述

更具体一点,你需要如上图这样定义训练标签,所以对于9个格子中的每一个指定一个标签 y y y y y y是8维的,和你之前看到的一样, y = [ p c b x b y b h b w c 1 c 2 c 3 ] y= \begin{bmatrix} p_c \\ b_x \\ b_y \\b_h \\b_w \\c_1 \\c_2 \\c_3 \\ \end{bmatrix} y=pcbxbybhbwc1c2c3

  • p c p_c pc等于0或1取决于这个格子中是否有图像。
  • 然后 b x b_x bx b y b_y by b h b_h bh b w b_w bw作用就是,如果那个格子里有对象,那么就给出边界框坐标。
  • 然后 c 1 c_1 c1 c 2 c_2 c2 c 3 c_3 c3就是你想要识别的三个类别,背景类别不算,所以你尝试在背景类别中识别行人、汽车和摩托车,那么 c 1 c_1 c1 c 2 c_2 c2 c 3 c_3 c3可以是行人、汽车和摩托车类别。

这张图里有9个格子,所以对于每个格子都有这么一个向量。
在这里插入图片描述

我们看看左上方格子,里面什么也没有,所以左上格子的标签向量 y y y y = [ 0 ? ? ? ? ? ? ? ] y= \begin{bmatrix} 0 \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ \end{bmatrix} y=0???????。然后第一排中间格子的输出标签也是一样,第一排第三个格子,还有其他什么也没有的格子都一样。

现在第二排第一个格子呢?
讲的更具体一点,这张图有两个对象。YOLO算法做的就是,取两个对象的中点,然后将这个对象分配给包含对象中点的格子。
在这里插入图片描述

所以左边的汽车就分配到第二排第一个格子上;然后这辆Condor黄色中点在这里,分配给第二排第三个格子。即使中心格子(第二排第二个格子)同时有两辆车的一部分,我们就假装中心格子没有任何我们感兴趣的对象。所以对于中心格子,分类标签 y y y和第一排没有对象的向量类似,即 y = [ 0 ? ? ? ? ? ? ? ] y= \begin{bmatrix} 0 \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ \end{bmatrix} y=0???????

而对于第二排第一个格子,目标标签就是这样的,这里有一个对象, p c = 1 p_c=1 pc=1,然后你写出 b x b_x bx b y b_y by b h b_h bh b w b_w bw来指定边界框位置,然后还有类别1是行人,那么 c 1 = 0 c_1=0 c1=0,类别2是汽车,所以 c 2 = 1 c_2=1 c2=1,类别3是摩托车,则数值 c 3 = 0 c_3=0 c3=0,即 y = [ 1 b x b y b h b w 0 1 0 ] y= \begin{bmatrix} 1 \\ b_x \\ b_y \\ b_h \\ b_w \\ 0 \\ 1 \\ 0 \\ \end{bmatrix} y=1bxbybhbw010

第二排第三个格子也是类似的。

所以对于这里9个格子中任何一个,你都会得到一个8维输出向量。因为是3×3的网格,9个格子总的输出尺寸是3×3×8,所以目标输出是3×3×8。
在这里插入图片描述

在这个例子中,左上格子是1×1×8,对应的是9个格子中左上格子的输出向量。
对于3×3中每一个格子而言,每个都对应一个8维输出目标向量。如果格子中没有对象的话,其中一些值可以是不用关注。

总的目标输出,这个图片的输出标签尺寸就是3×3×8。
在这里插入图片描述

如果你现在要训练一个输入为100×100×3的NN,如上图,左边是输入图像,然后你有一个普通的CNN,卷积层,最大池化层等等。选择卷积层和最大池化层,这样最后就映射到一个3×3×8输出尺寸。所以你要做的是,有一个输入图像 x x x,然后你有这些3×3×8的目标标签 y y y。当你用反向传播训练NN时,将任意输入 x x x映射到这类输出向量 y y y

这个算法的优点在于NN可以输出精确的边界框 b x b_x bx b y b_y by b h b_h bh b w b_w bw

所以测试的时候,你做的是喂入输入图像 x x x,然后跑正向传播,直到你得到这个输出 y y y。然后对于3×3位置对应的9个输出,我们在输出中展示过的,你就可以读出

  • p c p_c pc是1或0,你就知道9个位置之一有个对象。
  • 如果那里有个对象,那个对象是什么 c 1 c_1 c1 c 2 c_2 c2 c 3 c_3 c3
  • 还有格子中这个对象的边界框是什么。

只要每个格子中对象数目没有超过1个,这个算法应该是没问题的。一个格子中存在多个对象的问题,我们稍后再讨论。

我们这里用的是比较小的3×3网格,实践中你可能会使用更精细的19×19网格,所以输出就是19×19×8。这样的网格精细得多,那么多个对象分配到同一个格子得概率就小得多。

重申一下,把对象分配到一个格子的过程是,你观察对象的中点,然后将这个对象分配到其中点所在的格子,所以即使对象可以横跨多个格子,也只会被分配到9个格子其中之一,就是3×3网络的其中一个格子,或者19×19网络的其中一个格子。在19×19网格中,两个对象的中点处于同一个格子的概率就会更低。

注意

  • 首先,这和图像分类和定位算法非常像,我们在本周第一节课讲过的,就是它显式地输出边界框坐标,所以这能让NN输出边界框,可以具有任意宽高比,并且能输出更精确的坐标,不会受到滑动窗口分类器的步长大小限制。
  • 其次,这是一个卷积实现,你并没有在3×3网格上跑9次算法。或者,如果你用的是19×19的网格,19平方是361次,所以你不需要让同一个算法跑361次。相反,这是单次卷积实现,但你使用了一个CNN,有很多共享计算步骤,在处理你的3×3或者19×19的网格计算中很多计算步骤是共享的,所以这个算法效率很高。

事实上YOLO算法有一个好处,也是它受欢迎的原因,因为这是一个卷积实现,它的运行速度非常快,可以达到实时识别。

在结束之前我还想给你们分享一个小细节,如何编码这些边界框 b x b_x bx b y b_y by b h b_h bh b w b_w bw呢?

本例中有两辆车,我们有个3×3网格,我们以第二排第三个格子的车为例,因为格子里有个对象,所以目标标签就是 y y y

  • p c = 1 p_c=1 pc=1
  • 然后 b x b_x bx b y b_y by b h b_h bh b w b_w bw
  • 然后 c 1 = 0 c_1=0 c1=0 c 2 = 1 c_2=1 c2=1 c 3 = 0 c_3=0 c3=0,即 y = [ 1 b x b y b h b w 0 1 0 ] y= \begin{bmatrix} 1 \\ b_x \\ b_y \\ b_h \\ b_w \\ 0 \\ 1 \\ 0 \\ \end{bmatrix} y=1bxbybhbw010

你怎么指定这个边界框呢?
在这里插入图片描述

在YOLO算法中,对于这个方框(第二排第三个),我们约定左上这个点是(0,0),然后右下这个点是(1,1)。要指定橙色中点的位置

  • b x b_x bx大概是0.4,因为它的位置大概是水平长度的0.4,
  • b y b_y by大概是0.3,
  • 边界框的高度用格子总体宽度的比例表示,这个红框的宽度可能是底部蓝线的90%,所以 b h b_h bh是0.9,
  • 它的高度也许是格子总体高度的一半,这样的话 b w b_w bw就是0.5。

换句话说, b x b_x bx b y b_y by b h b_h bh b w b_w bw单位是相对于格子尺寸的比例,所以 b x b_x bx b y b_y by必须在0和1之间,因为从定义上看,橙色点位于对象分配到格子的范围内,如果它不在0和1之间,在方块外,那么这个对象就应该分配到另一个格子上。这个值( b w b_w bw b h b_h bh)可能会大于1,特别是如果有一辆汽车的边界框是第二排第一个格子这样的,那么边界框的宽度和高度有可能大于1。

指定边界框的方式有很多,但这种约定是比较合理的。

如果你去读YOLO的研究论文,YOLO的研究工作有其他参数化的方式,可能效果会更好,我这里就只给出了一个合理的约定,用起来应该没问题。不过还有其他更复杂的参数化方式,涉及到sigmoid函数,确保这个值( b x b_x bx b y b_y by)介于0和1之间,然后使用指数参数化来确保这些( b w b_w bw b h b_h bh)都是非负数,因为0.9和0.5,这个必须大于等于0。还有其他更高级的参数化方式,可能效果要更好一点,但我这里讲的办法应该是管用的。

这就是YOLO算法,你只看一次算法,在接下来的几节课中,我会告诉你一些其他的思路可以让这个算法做的更好。在此期间,如果你感兴趣,也可以看看YOLO的论文。

不过看这些论文之前,先给你们提个醒,YOLO论文是相对难度较高的论文之一,我记得我第一次读这篇论文的时候,我真的很难搞清楚到底是怎么实现的,我最后问了一些我认识的研究员,看看他们能不能给我讲清楚,即使是他们,也很难理解这篇论文的一些细节。

所以如果你看论文的时候,发现看不懂,这是没问题的,我希望这种场合出现的概率要更低才好,但实际上,即使是资深研究员也有读不懂研究论文的时候,必须去读源代码,或者联系作者之类的才能弄清楚这些算法的细节。

但你们不要被我吓到,你们可以自己看看这些论文,如果你们感兴趣的话,但这篇论文相对较难。现在你们了解了YOLO算法的基础,我们继续讨论别的让这个算法效果更好的研究。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值