深度学习专项课程(4)(第三周)

深度学习专项课程(4)(第三周)

本周介绍了目标检测的相关内容。

目标定位

前面我们了解了图片的分类问题,即判断一张图片包含哪一类物体。目标定位问题不仅仅要对图片进行分类,还要准确指出物体在图片中的具体位置。而检测问题的不同指出是图片中的物体不止一个。

dl_72

定位问题所使用的神经网络问题与图片分类的问题的网络结构相似,只需对输出层稍作改变即可。
图片分类问题中只要在输出层给出图片所属类别的概率,在定位问题中则还要给出 bounding box 的具体位置。位置参数用 $b_x,b_y,b_h,b_w$来表示,其中 x,y表示bounding box 中心的位置,h,w表示bounding box 的宽度和高度。

dl_73

相应的,我们的标签 y 也要随之改变。
这里假设只包括下面三种物体,背景类别说明图片中不存在上面三种物体:

  • 行人
  • 汽车
  • 摩托车
  • 背景

标签 y 的形式如下:

$$
\large
\begin{bmatrix}
pc \\ b_x \\ b_y \\ b_h \\ b_w \\ c_1 \\ c_2 \\ c_3
\end{bmatrix}
$$

如果图片中存在上面三种物体则 pc = 1, 否则 pc = 0 。$b_x,b_y,b_h,b_w$ 表示 bounding box 的位置,$c_1,c_2,c_3$ 表示具体属于哪一类。

$$
\large
\begin{bmatrix}
0 \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ ?
\end{bmatrix}
$$

如果是背景的话,其他的参数就不用关心具体是什么了。

特征点检测

神经网络可以通过输出图片上特征点的(x,y)坐标来实现对目标特征的检测。

举例来说,在人脸识别的应用中可以检测人脸的关键点,如眼角,或是下颚的一些关键点。也可以应用在人体姿态关键点检测。

这些关键点的训练数据往往需要人工来实现标注。

dl_74

目标检测

基于滑动窗口的目标检测算法。

这里假设我们想实现一个汽车检测的算法。

首先我们需要准备好数据集,数据集中的图片应该如下图所示,汽车位于图片的中心,且充满了整个图片,标签的值 为 1 ,如果是背景的话标签的值 为 0 。

我们使用准备好的数据集训练一个神经网络,该网络可以判断输入的图片是否是汽车。

dl_76

有了上面的准备后,就可以用它来实现滑动窗口的目标检测。具体步骤如下。

我们使用不同大小的窗口,以一定的步长在图片上滑动,将每次滑动后得到的图片输入神经网络,判断是否是汽车。

像这样不同大小的窗口遍历过整个图像后,我们就可以得出汽车在图片中的位置了。

dl_75

该算法的缺点也很明显,就是它的计算成本很高。

如果选用较大的步长,不能准确得出汽车的位置。如果选用较小的步长,则计算成本很高。

卷积的滑动窗口实现

上一节内容讲到的滑动窗口算法计算成本很高,这里给出滑动窗口的卷积实现,可以大大减少计算成本。

在这之前需要了解如何把卷积神经网络的全连接层转化为卷积层。

下图的上半部分是一个传统的卷积神经网络结构,其后面两层是全连接层。

下半部分使用卷积方式实现了全连接层的一个神经网络。

网络的前三层是相同的,从全连接层的部分两个网络有了不同。

下面的网络 在原本是全连接层的地方 使用了 400 个 5x5x16 的过滤器,卷积之后得到了 1x1x400 的层,这在数学上是与全连接层相同的结构。接下来又用了 400 个 1x1x400 的卷积核 得到了 1x1x400 层,这与上面第二个全连接层对应。最后在使用 4 个 1x1x400 的过滤器得到了最后一层。

这就是使用卷积操作实现全连接层的过程。

dl_77

接下来看看如何使用卷积的方式实现滑动窗口算法。

下图中第一个是我们训练用的神经网络。第二个和第三个都是检测用的神经网络。

在第二个神经网络中输入的图片规格是 16x16x3 ,使用 14x14x3 的窗口,步长为 2 个像素的设定进行滑动,那么需要进行四次卷积操作,也就是将检测的图片分成四个子集进行检测。

这四次操作中有许多操作是重复的。

其实不必将图片分成四个部分进行检测,只要将整张图片进行一次卷积操作即可。如第二个网络所示,最后输出的结果是 2x2x4 的层,其中左上角部分就代表整张图片左上角的子集的检测结果,右上角部分就代表整张
图片右上角子集的检测结果。

这样的操作就大大减少了计算量。

dl_78

Bounding Box 预测

上面我们提到了卷积的滑动窗口算法,这个算法虽然大大提升了效率,但无法准确的预测 bounding box的位置。

其中一个可以得到更精确的边界框的算法是 YOLO(YOU ONLY LOOK ONCE) 算法。

其基本思路是将图片分成 9 个部分,对每一部分实施我们前面提到过的定位算法。对每一个部分都给出一个标签,同前面一样标签是 8 维的。如果图片中包含待检测的物体,我们根据物体的中心位置将其分配到对应的部分中。图片中没有物体的部分则当作背景来处理。

所以一张图片就对应了 3x3x8 的标签。

在检测时,也输出 3x3x8 的预测标签。我们根据输出的预测标签来判断物体所在的具体位置。

在实际应用中我们可以将图片分成 19x19 个部分,这样得到的结果会更加精确。

根据上面的内容,只需要进行一次卷积操作就可以得到最终的结果,所以该算法的运行速度很快,甚至可以达到实时的效果。

dl_79

交并比

如何判断目标检测算法运作良好呢?我们可以使用交并比这一指标来评价目标检测算法。

图片中实际的边界框是红色的,紫色的是预测的边界框。IoU(Intersection over union) 就是两个边界框的交集和并集之比。

按照惯例,如果 IoU > 0.5 的话,就认为检测正确。0.5 只是约定俗成的一个值,如果你更严格的话可以设定为 0.6 或 0.7 。

dl_80

非极大值抑制

目前我们所学到的目标检测算法可能对同一个对象做出多次检测,非极大值抑制这个方法可以确保你的算法对每个对象只检测一次。

将图片分成 19x19 个格子之后,每个格子都运行图片分类和定位算法,那么可能不止一个格子会认为自己这里有目标物体,并给出结果。

dl_81

在下图中,同一个物体的检测会得到不止一个 bounding box ,非极大值抑制的作用就是:选择一个可能性最高的 bounding box ,并丢弃与其 IoU 过大(即重叠度很高)的 bounding box 这样就可以保证每一个物体只有一个预测结果了。

dl_82

Anchor Boxes

现在还有一个问题就是,每一个格子只能检测一个物体。如果想让一个格子检测出多个物体,就要使用 Anchor Boxes 这个方法。

下图中行人和汽车的中点都位于同一个格子内。可以看出行人和汽车的形状有明显差异,我们设置两个 Anchor Boxes,并对 标签 y 做出修改。

标签由原来的 8 变成了 16。 标签的上半部分设置为检测 Anchor Box 1,下半部分设置为 检测 Anchor Box 2 。

dl_83

不使用 anchor box 使用 anchor box
图片中的物体分配到中点所在的格子中 图片中的物体分配到中点所在的格子中,并分配一个 IoU 最高的 anchor box
输出的 y 3x3x8 输出的 y 3x3x2x8

看一个例子:

如果人和车的中点位于一个格子内,标签就如下图左边所示。如果只有车没有人就如右边的所示。

dl_84

如果只有两个 anchor box 而有三种物体的话,算法处理的并不好。但这种情况并不常见。

YOLO 算法

我们已经学过了所有必要的组件,这一节我们将组件组装起来构成 YOLO 目标检测算法。

首先我们要构建训练集

这里我们检测三类物体,anchor box 设置为两个。

dl_85

训练好神经网络之后,我们再进行预测

对不同的格子都做出预测。

dl_86

最后要运行一下非极大值抑制

对每一个格子,神经网络会输出两个 bounding box , 我们直接丢弃那些存在物体概率过低的 bounding box 。

dl_87

dl_88

再对每一物体运行一下非极大值抑制,接得到了最后的结果。

dl_89

候选区域

前面我们提到的滑动窗口算法,因为要遍历整个图片,所以会在明显不存在物体的区域进行计算。而这会浪费时间。

R-CNN 的想法是先运行分割算法,将图片分成不同尺寸的色块,再在不同的色块上进行图片的分类,这样做的效率将会提升很多。

dl_90

然而这样还是太慢了,所以许多研究工作都针对这一问题展开。

算法 内容
R-CNN 感兴趣区域提议,在每个区域上运行分类器,输出标签和边界框
Fast R-CNN 感兴趣区域提议,使用卷积的方式实现滑动窗口来分类感兴趣区域
Faster R-CNN 使用卷积的方式产生感兴趣区域

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×