吴恩达深度学习课程之第四门课 卷积神经网络 第三周 目标检测

本文参考黄海广主编针对吴恩达深度学习课程DeepLearning.ai 《深度学习课程 笔记 (V5.1 )》 

第三周 目标检测

3.1 目标定位(Object localization)

我们学习的主要内容是对象检测,它是计算机视觉领域中一个新兴的应用方向,相比前两年,它的性能越来越好。在构建对象检测之前,我们先了解一下对象定位。

图片分类任务我们已经熟悉了,就是算法遍历图片,判断其中的对象是不是汽车,这就是图片分类。

学习构建神经网络的另一个问题,即定位分类问题。这意味着,我们不仅要用算法判断图片中是不是一辆汽车,还要在图片中标记出它的位置,用边框或红色方框把汽车圈起来,这就是定位分类问题。其中“定位”的意思是判断汽车在图片中的具体位置。比如,你正在做一个自动驾驶程序,程序不但要检测其它车辆,还要检测其它对象,如行人、摩托车等等。

我们要研究的分类定位问题,通常只有一个较大的对象位于图片中间位置,我们要对它进行识别和定位。而在对象检测问题中,图片可以含有多个对象,甚至单张图片中会有个不同分类的对象。因此,图片分类的思路可以帮助学习分类定位,而对象定位的思路又有助于学习对象检测,我们先从分类和定位开始讲起。

图片分类问题你已经并不陌生了,例如,输入一张图片到多层卷积神经网络。这就是卷积神经网络,它会输出一个特征向量并反馈给 softmax 单元来预测图片类型

如果你正在构建汽车自动驾驶系统,那么对象可能包括以下几类:行人、汽车、摩托车和背景,这意味着图片中不含有前三种对象,也就是说图片中没有行人、汽车和摩托车,输出结果会是背景对象,这四个分类就是 softmax 函数可能输出的结果。

这就是标准的分类过程,如果你还想定位图片中汽车的位置,该怎么做呢?我们可以让神经网络多输出几个单元,输出一个边界框。具体说就是让神经网络再多输出 4 个数字,标记为bx,by,bh和bw, 这四个数字是被检测对象的边界框的参数化表示。

下面我再具体讲讲如何为监督学习任务定义目标标签 y。

 

 

为了让大家了解对象定位的细节,这里我用平方误差简化了描述过程。实际应用中,你可以不对c1 、c2 、c3 和 softmax 激活函数应用对数损失函数,并输出其中一个元素值,通常做法是对边界框坐标应用平方差或类似方法,对pc 应用逻辑回归函数,甚至采用平方预测误差也是可以的。

以上就是利用神经网络解决对象分类和定位问题的详细过程,结果证明,利用神经网络输出批量实数来识别图片中的对象是个非常有用的算法。

3.2 特征点检测(Landmark detection)

我们讲了如何利用神经网络进行对象定位,即通过输出四个参数值bx、by、bh和bw 给出图片中对象的边by界框。更概括地说,神经网络可以通过输出图片上特征点的(x,y) 坐标来实现对目标特征的识别。

假设你正在构建一个人脸识别应用,出于某种原因,你希望算法可以给出眼角的具体位置。眼角坐标为(x,𝑦),你可以让神经网络的最后一层多输出两个数字lx 和ly ,作为眼角的坐标值。如果你想知道两只眼睛的四个眼角的具体位置,那么从左到右,依次用四个特征点来表示这四个眼角。对神经网络稍做些修改,输出第一个特征点(l 1x ,l1y ),第二个特征点(l2x ,l2y ),依此类推,这四个脸部特征点的位置就可以通过神经网络输出了。

也许除了这四个特征点,你还想得到更多的特征点输出值,这些(图中眼眶上的红色特征点)都是眼睛的特征点,你还可以根据嘴部的关键点输出值来确定嘴的形状,从而判断人物是在微笑还是皱眉,也可以提取鼻子周围的关键特征点。为了便于说明,你可以设定特征点的个数,假设脸部有 64 个特征点,有些点甚至可以帮助你定义脸部轮廓或下颌轮廓。选定特征点个数,并生成包含这些特征点的标签训练集,然后利用神经网络输出脸部关键特征点的位置。

最后一个例子,如果你对人体姿态检测感兴趣,你还可以定义一些关键特征点,如胸部的中点,左肩,左肘,腰等等。然后通过神经网络标注人物姿态的关键特征点,再输出这些标注过的特征点,就相当于输出了人物的姿态动作。当然,要实现这个功能,你需要设定这些关键特征点,从胸部中心点(l1x, l1y)一直往下,直到(l32x,l32y)。

一旦了解如何用二维坐标系定义人物姿态,操作起来就相当简单了,批量添加输出单元,用以输出要识别的各个特征点的(𝑦,𝑧)坐标值。要明确一点,特征点 1 的特性在所有图片中必须保持一致,就好比,特征点 1 始终是右眼的外眼角,特征点 2 是右眼的内眼角,特征点3 是左眼内眼角,特征点 4 是左眼外眼角等等。所以标签在所有图片中必须保持一致,假如你雇用他人或自己标记了一个足够大的数据集,那么神经网络便可以输出上述所有特征点,你可以利用它们实现其他有趣的效果,比如判断人物的动作姿态,识别图片中的人物表情等等。

3.3 目标检测(Object detection

学过了对象定位和特征点检测,今天我们来构建一个对象检测算法。这节课,我们将学习如何通过卷积网络进行对象检测,采用的是基于滑动窗口的目标检测算法

假如你想构建一个汽车检测算法,步骤是:

首先创建一个标签训练集,适当剪切的汽车图片样本。出于我们对这个训练集的期望,你一开始可以使用适当剪切的图片,就是整张图片x几乎都被汽车占据。有了这个标签训练集,你就可以开始训练卷积网络了,输入这些适当剪切过的图片(编号 6),卷积网络输出y,0 或 1 表示图片中有汽车或没有汽车。训练完这个卷积网络,就可以用它来实现滑动窗口目标检测,具体步骤如下:

假设这是一张测试图片,首先选定一个特定大小的窗口,比如图片下方这个窗口,将这个红色小方块输入卷积神经网络,卷积网络开始进行预测,即判断红色方框内有没有汽车。

滑动窗口目标检测算法接下来会继续处理第二个图像,即红色方框稍向右滑动之后的区域,并输入给卷积网络,因此输入给卷积网络的只有红色方框内的区域,再次运行卷积网络,然后处理第三个图像,依次重复操作,直到这个窗口滑过图像的每一个角落。为了滑动得更快,我这里选用的步幅比较大,思路是以固定步幅移动窗口,遍历图像的每个区域,把这些剪切后的小图像输入卷积网络,对每个位置按 0 1 进行分类,这就是所谓的图像滑动窗口操作。

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

滑动窗口目标检测算法也有很明显的缺点,就是计算成本,因为你在图片中剪切出太多小方块,卷积网络要一个个地处理。如果你选用的步幅很大,显然会减少输入卷积网络的窗口个数,但是粗糙间隔尺寸可能会影响性能。反之,如果采用小粒度或小步幅,传递给卷积网络的小窗口会特别多,这意味着超高的计算成本。

所以在神经网络兴起之前,人们通常采用更简单的分类器进行对象检测,比如通过采用手工处理工程特征的简单的线性分类器来执行对象检测。至于误差,因为每个分类器的计算成本都很低,它只是一个线性函数,所以滑动窗口目标检测算法表现良好,是个不错的算法。然而,卷积网络运行单个分类人物的成本却高得多,像这样滑动窗口太慢。除非采用超细粒度或极小步幅,否则无法准确定位图片中的对象。

庆幸的是,计算成本问题已经有了很好的解决方案,大大提高了卷积层上应用滑动窗口目标检测器的效率,关于它的具体实现,我们下节课再讲。

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

我们学习了如何通过卷积网络实现滑动窗口对象检测算法,但效率很低。这节课我们讲讲如何在卷积层上应用这个算法。为了构建滑动窗口的卷积应用,首先要知道如何把神经网络的全连接层转化成卷积层。我们先讲解这部分内容,下一张幻灯片,我们将按照这个思路来演示卷积的应用过程。

假设对象检测算法输入一个 14×14×3 的图像,图像很小,不过演示起来方便。在这里过滤器大小为 5×5,数量是 16,14×14×3 的图像在过滤器处理之后映射为 10×10×16。然后通过参数为 2×2 的最大池化操作,图像减小到 5×5×16。然后添加一个连接 400 个单元的全连接层,接着再添加一个全连接层,最后通过 softmax 单元输出y。为了跟下图区分开,我先做一点改动,用 4 个数字来表示y,它们分别对应 softmax 单元所输出的 4 个分类出现的概率。这 4 个分类可以是行人、汽车、摩托车和背景或其它对象。

现在我要演示的就是如何把这些全连接层转化为卷积层,画一个这样的卷积网络,它的前几层和之前的一样,而对于下一层,也就是这个全连接层,我们可以用 5×5 的过滤器来实现,数量是 400 个(编号 1 所示),输入图像大小为 5×5×16,用 5×5 的过滤器对它进行卷积操作,过滤器实际上是 5×5×16,因为在卷积过程中,过滤器会遍历这 16 个通道,所以这两处的通道数量必须保持一致,输出结果为 1×1。假设应用 400 个这样的 5×5×16 过滤器,输出维度就是 1×1×400,我们不再把它看作一个含有 400 个节点的集合,而是一个 1×1×400输出层。从数学角度看,它和全连接层是一样的,因为这 400 个节点中每个节点都有一个5×5×16 维度的过滤器,所以每个值都是上一层这些 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,把它输入到卷积网络。继续输入下一块区域,大小同样是 14×14,重复操作,直到某个区域识别到汽车。但是正如在前一页所看到的,我们不能依靠连续的卷积操作来识别图片中的汽车,比如,们可以对大小为 28×28 的整张图片进行卷积操作,一次得到所有预测值,如果足够幸运,神经网络便可以识别出汽车的位置。

以上就是在卷积层上应用滑动窗口算法的内容,它提高了整个算法的效率。不过这种算法仍然存在一个缺点,就是边界框的位置可能不够准确。下节课,我们将学习如何解决这个问题。

3.5 Bounding Box 预测(Bounding box predictions )

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

在滑动窗口法中,你取这些离散的位置集合,然后在它们上运行分类器,在这种情况下,这些边界框没有一个能完美匹配汽车位置,也许这个框(编号 1)是最匹配的了。还有看起来这个真实值,最完美的边界框甚至不是方形,稍微有点长方形(红色方框所示),长宽比有点向水平方向延伸,有没有办法让这个算法输出更精准的边界框呢?

其中一个能得到更精准边界框的算法是 YOLO 算法,YOLO(You only look once)意思是你只看一次

重申一下,把对象分配到一个格子的过程是,你观察对象的中点,然后将这个对象分配到其中点所在的格子,所以即使对象可以横跨多个格子,也只会被分配到 9 个格子其中之

  • 就是 3×3 网络的其中一个格子,或者 19×19 网络的其中一个格子。在 19×19 网格中,两个对象的中点(图中蓝色点所示)处于同一个格子的概率就会更低。

首先这和图像分类和定位算法非常像,我们在本周第一节课讲过的,就是它显式地输出边界框坐标,所以这能让神经网络输出边界框,可以具有任意宽高比,并且能输出更精确的坐标,不会受到滑动窗口分类器的步长大小限制

其次,这是一个卷积实现,你并没有在 3×3 网格上跑 9 次算法,或者,如果你用的是 19×19 的网格,19 平方是 361 次,以你不需要让同一个算法跑 361 次。相反,这是单次卷积实现,但你使用了一个卷积网络,有很多共享计算步骤,在处理这 3×3 计算中很多计算步骤是共享的,或者你的 19×19 的网格,所以这个算法效率很高。

事实上 YOLO 算法有一个好处,也是它受欢迎的原因,因为这是一个卷积实现,实际上它的运行速度非常快,可以达到实时识别。在结束之前我还想给你们分享一个小细节,如何编码这些边界框

3.6 交并比(Intersection over union)

你如何判断对象检测算法运作良好呢?在本视频中,你将了解到并交比函数,可以用来评价对象检测算法

在对象检测任务中,你希望能够同时定位对象,所以如果实际边界框是这样的,你的算法给出这个紫色的边界框,那么这个结果是好还是坏?所以交并比(loU)函数做的是计算两个边界框交集和并集之比。两个边界框的并集是这个区域,就是属于包含两个边界框区域(绿色阴影表示区域),而交集就是这个比较小的区域(橙色阴影表示区域),那么交并比就是交集的大小,这个橙色阴影面积,然后除以绿色阴影的并集面积。一般约定,在计算机检测任务中,如果𝑚𝑝𝑉 ≥ 0.5,就说检测正确,如果预测器和实际边界框完美重叠,loU 就是 1,因为交集就等于并集。但一般来说只要𝑚𝑝𝑉 ≥ 0.5,那么结果是可以接受的,看起来还可以。一般约定,0.5 是阈值,用来判断预测的边界框是否正确。一是这么约定,但如果你希望更严格一点,你可以将 loU 定得更高,比如说大于 0.6 或者更大的数字,但 loU 越高,边界框越精确。

所以这是衡量定位精确度的一种方式,你只需要统计算法正确检测和定位对象的次数,你就可以用这样的定义判断对象定位是否准确。再次,0.5 是人为约定,没有特别深的理论依据,如果你想更严格一点,可以把阈值定为 0.6。有时我看到更严格的标准,比如 0.6 甚至 0.7,但很少见到有人将阈值降到 0.5 以下。人们定义 loU 这个概念是为了评价你的对象定位算法是否精准,但更一般地说,loU 衡量了两个边界框重叠地相对大小。如果你有两个边界框,你可以计算交集,计算并集,然后求两个数值的比值,所以这也可以判断两个边界框是否相似,我们将在下一个视频中再次用到这个函数,当我们讨论非最大值抑制时再次用到。

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

到目前为止你们学到的对象检测中的一个问题是,你的算法可能对同一个对象做出多次检测,所以算法不是对某个对象检测出一次,而是检测出多次。非极大值抑制这个方法可以确保你的算法对每个对象只检测一次,我们讲一个例子

假设你需要在这张图片里检测行人和汽车,你可能会在上面放个 19×19 网格,理论上这辆车只有一个中点,所以它应该只被分配到一个格子里,左边的车子也只有一个中点,所以理论上应该只有一个格子做出有车的预测。

实践中当你运行对象分类和定位算法时,对于每个格子都运行一次,所以这个格子(编号 1)可能会认为这辆车中点应该在格子内部,这几个格子(编号 2、3)也会这么认为。对于左边的车子也一样,所以不仅仅是这个格子,如果这是你们以前见过的图像,不仅这个格(编号 4)子会认为它里面有车,也许这个格子(编号 5)和这个格子(编号 6)也会,也许其他格子也会这么认为,觉得它们格子内有车。

我们分步介绍一下非极大抑制是怎么起效的,因为你要在 361 个格子上都运行一次图像检测和定位算法,那么可能很多格子都会举手说我的Pc ,我这个格子里有车的概率很高,而不是 361 个格子中仅有两个格子会报告它们检测出一个对象。所以当你运行算法的时候,最后可能会对同一个对象做出多次检测,所以非极大值抑制做的就是清理这些检测结果。这样一辆车只检测一次,而不是每辆车都触发多次检测。

这么做之后,非极大值抑制就会逐一审视剩下的矩形,所有和这个最大的边框有很高交并比,高度重叠的其他边界框,那么这些输出就会被抑制。所以这两个矩形Pc分别是 0.6 和 0.7

接下来,逐一审视剩下的矩形,找出概率最高,𝑞 𝑑 最高的一个,在这种情况下是 0.8,我们就认为这里检测出一辆车(左边车辆),然后非极大值抑制算法就会去掉其他 loU 值很高的矩形。所以现在每个矩形都会被高亮显示或者变暗,如果你直接抛弃变暗的矩形,那就剩下高亮显示的那些,这就是最后得到的两个预测结果。所以这就是非极大值抑制,非最大值意味着你只输出概率最大的分类结果,但抑制很接近,但不是最大的其他预测结果,所以这方法叫做非极大值抑制。

这就是非极大值抑制,如果你能实现我们说过的对象检测算法,你其实可以得到相当不的结果。但结束我们对 YOLO 算法的介绍之前,最后我还有一个细节想给大家分享,可以进一步改善算法效果,就是 anchor box 的思路,我们下一个视频再介绍。

3.8 Anchor Boxes

到目前为止,对象检测中存在的一个问题是每个格子只能检测出一个对象,如果你想让一个格子检测出多个对象,你可以这么做,就是使用 anchor box 这个概念,我们从一个例子开始讲吧。

而 anchor box 的思路是,这样子,预先定义两个不同形状的 anchor box,或者 anchorbox 形状,你要做的是把预测结果和这两个 anchor box 关联起来。一般来说,你可能会用更多的 anchor box,可能要 5 个甚至更多,但对于这个视频,我们就用两个 anchor box,这样介绍起来简单一些。

总结一下,用 anchor box 之前,你做的是这个,对于训练集图像中的每个对象,都根据那个对象中点位置分配到对应的格子中,所以输出 y 就是 3×3×8,因为是 3×3 网格,对于每个网格位置,我们有输出向量,包含Pc,然后边界框参数bx, b𝑦 , bℎ 和bw ,然后c 1 ,c2 ,c3 。

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

我们先看看如何构造你的训练集,假设你要训练一个算法去检测三种对象,行人、汽车和摩托车,你还需要显式指定完整的背景类别。这里有 3 个类别标签,如果你要用两个 anchorbox,那么输出 y 就是 3×3×2×8,其中 3×3 表示 3×3 个网格,2 是 anchor box 的数量,8 是向量维度,8 实际上先是 5(pc,bx,by,bw )再加上类别的数量(c 1 ,c 2 ,c 3 )。你可以将它看成是 3×3×2×8,或者 3×3×16。要构造训练集,你需要遍历 9 个格子,然后构成对应的目标向量y。

最后你要运行一下这个非极大值抑制,为了让内容更有趣一些,我们看看一张新的测试图像,这就是运行非极大值抑制的过程。如果你使用两个 anchor box,那么对于 9 个格子中任何一个都会有两个预测的边界框,其中一个的概率𝑞 𝑑 很低。但 9 个格子中,每个都有两个预测的边界框,比如说我们得到的边界框是是这样的,注意有一些边界框可以超出所在格子的高度和宽度(编号 1 所示)。接下来你抛弃概率很低的预测,去掉这些连神经网络都说,这里很可能什么都没有,所以你需要抛弃这些(编号 2 所示)。

最后,如果你有三个对象检测类别,你希望检测行人,汽车和摩托车,那么你要做的是,于每个类别单独运行非极大值抑制,处理预测结果所属类别的边界框,用非极大值抑制来处理行人类别,用非极大值抑制处理车子类别,然后对摩托车类别进行非极大值抑制,运行三次来得到最终的预测结果。所以算法的输出最好能够检测出图像里所有的车子,还有所有的行人(编号 3 所示)。这就是 YOLO 对象检测算法,这实际上是最有效的对象检测算法之一,包含了整个计算机视觉对象检测领域文献中很多最精妙的思路。

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

所谓的候选区域,这在计算机视觉领域是非常有影响力的概念。我把这个视频定为可选视频是因为我用到候选区域这一系列算法的频率没有那么高,但当然了,这些工作是很有影响力的,

滑动窗法,你使用训练过的分类器,在这些窗口中全部运行一遍,然后运行一个检测器,看看里面是否有车辆,行人和摩托车。现在你也可以运行一下卷积算法,这个算法的其中一个缺点是,它在显然没有任何对象的区域浪费时间

所以这里这个矩形区域(编号 1)基本是空的,显然没有什么需要分类的东西。也许算法会在这个矩形上(编号 2)运行,而你知道上面没有什么有趣的东西。

所以这个细节就是所谓的分割算法,你先找出可能 2000 多个色块,然后在这 2000 个色块上放置边界框,然后在这 2000 个色块上运行分类器,这样需要处理的位置可能要少的多,可以减少卷积网络分类器运行时间,比在图像所有位置运行一遍分类器要快。特别是这种情况,现在不仅是在方形区域(编号 5)中运行卷积网络,我们还会在高高瘦瘦(编号 6)的区域运行,尝试检测出行人,然后我们在很宽很胖的区域(编号 7)运行,尝试检测出车辆,同时在各种尺度运行分类器。

这就是 R-CNN 或者 区域 CNN 的特色概念,现在看来 R-CNN 算法还是很慢的。所以有一系列的研究工作去改进这个算法,所以基本的 R-CNN 算法是使用某种算法求出候选区域,然后对每个候选区域运行一下分类器,每个区域会输出一个标签,有没有车子?有没有行人?有没有摩托车?并输出一个边界框,这样你就能在确实存在对象的区域得到一个精确的边界框。

澄清一下,R-CNN 算法不会直接信任输入的边界框,它也会输出一个边界框bx,by,bz和bw,这样得到的边界框比较精确,比单纯使用图像分割算法给出的色块边界要好,所以它可以得到相当精确的边界框。

现在R-CNN算法的一个缺点是太慢了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clark-dj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值