目标检测

本文来自于网易云课堂

目标定位

目标检测
目标定位不仅仅是要识别出图片有没有那个东西还要用方框标记出目标的位置。对于一个多分类问题,我们可以利用softmax来表示输出,那么图形的边框该如何表示呢?我们可以采用表框的参数化表示,如bx,by,bh,bw。下面我们介绍一下约定:图片左上角为(0,0),右下角为(1,1),要想确定边界框的具体位置,需要指定边框的中心为(bx,by),边界框的高度为bh,宽度为bw。因此训练集不仅包括神经网络要预测的分类标签,还包含边界的四个参数。接着采用监督学习算法,输出一个标签还有4个参数值。
目标检测
那么如何为监督学习任务定义目标标签y呢?
目标检测
对于上图中的4类,神经网络输出的是这4个数据和一个分类标签或分类标签出现的概率。目标标签的定义如下,它是一个向量,第一个组件Pc表示是否含有对象,如果有对象,则Pc为1,如果是背景,Pc为0.这里只针对图片中只有一个对象的情况。
目标检测
那么对应的损失函数定义如下
目标检测

特征点检测

上节课讲了如何利用神经网络获得边框,即输出边框的四个参数,更概括的说,神经网络可以通过输出图片上特征点的(x,y)坐标来实现对目标特征的识别。
假设你正在构建一个人脸识别应用,出于某种原因,你希望眼角能给出算法的具体位置,眼角坐标为(x,y),那么你可以让神经网络的最后一层输出两个坐标(x1,y1),同样你也可以对其他的部位进行特征点标记,比如嘴,脸型以及鼻子的关键特征点等。选定特征点,并生成特定的标签集,然后利用神经网络输出脸部关键特征点的位置。
目标检测
你可能玩过人脸上带皇冠的应用,这是微信的玩法,就是利用了人脸识别来做的。再比如说人体姿态识别,可以标记胸部,腿,腰的位置来实现检测。

目标检测

假如你想构建一个汽车检测算法,步骤是首先训练一个(x,y),这些输入可以适当剪切一下,让汽车在中间。然后可以开始训练卷积网络了,训练完以后,你就可以利用滑动窗口来实现目标检测了。
目标检测
具体步骤如下,假设给定一张测试图片,如下所示。你要做的是首先选定一个特定大小的窗口,比如图片下方的这个窗口,将这个红色小窗口输入卷积网络。具体过程就是以固定步幅滑动窗口,遍历图像的每个区域,把这些剪切过的小图像输入卷积网络,对每个位置进行0和1分类,这就是所谓的图像滑动窗口操作。然后重复选择更大的窗口重复进行该步骤。这种方法具有明显的缺点,即计算成本问题。
目标检测
目标检测

卷积的滑动窗口实现

通过卷积网络实现滑动窗口对象检测算法,但是效率很低。如果在卷积层上应用这个算法会有明显的改观。我们来看一下这个过程。
为了构建滑动窗口的卷积应用,首先要知道如何把神经网络的全连接层转换为卷积层。卷积层替代全连接层的过程从下图就可以很明显的看出来。
目标检测
目标检测
在此基础上,那么如何通过卷积实现滑动窗口对象检测算法呢?首先在图片上剪出一片区域,假设是14*14,然后把它放到卷积中,继续输入一下个,同样是14*14,重复操作,直到某个区域识别出汽车。但我们不用依靠连续的卷积操作,来识别图中的汽车,而是一次输出所有的结果。
目标检测
目标检测
目标检测
这个算法明显提高了效率,但是任然存在缺点就是它的边界框的位置可能不太准确。那么该如何解决这个问题呢?请看下一节。

边界框预测

目标检测
对于上面这个图来说,可能蓝色的框是最接近的输出了。但实际上红色的框才是应该的边界框,并且它的形状可能还不是标准的正方形。那么如何得到更精准的边框呢?这里就用到了yolo算法,它是you only look once的意思,就是你只看一次。具体是这么做的,比如你的输入图像时100*100,然后在一个图像上放一个网络,为了简单一些,这里采用3*3的网格,实际中可能使用更精细。基本思路是使用图像分类和定位算法,然后将算法逐一应用到9个格子上。更具体一点,你需要这样定义标签,对于每个格子指定一个标签y,y是8维向量,和之前的一样。所以,这张图有9个格子,每个格子都有一个向量。
目标检测
对于中间的格子,即使里面有2个对象我们也把它当做没有。这个算法的优点在于,其能精准的输出边框。所以测试的时候你要做的是喂输入图像,然后跑正向传播,得到一个输出y,然后对应于每个格子你就可以得到每个格子是1还是0,就可以确定位置。只要一个格子不超过一个对象,这个算法就是ok的。实际上可能会用19*19的格子,这样的格子小得多,那么一个格子会有多个物体的概率也会小的多。把对象分配到一个格子的过程是,观察对象的中点,然后将这个对象分配到其中点所在的格子。所以即使对象横跨多个格子,也只会分配到其中一个格子中。这里有2件事情要注意,这和图像分类和定位算法非常像,它显示的输出边界坐标,所以这能让神经网络输出边框,可以具有任意高宽比,并且能输出更精确的坐标,不会受到滑动窗口算法的步长限制。其次这是一个卷积实现,并没有在3*3的网格上跑9次算法。如果你用的是19*19,那么就要跑361次。所以不需要跑361次,相反这是一个单次卷积实现。这也是它受欢迎的原因,这样跑的速度就会非常快,基本上能达到实时的程度。
还有一个关于如何编码bx,by,bh,bw的小细节。bx,by,bh,bw是相对格子尺度的比例,bx,by必须在0和1之间,以为它肯定在格子内部,而bh,bw有可能大于格子尺度,
目标检测

交并比

如何判断对象检测算法运行良好呢?交并比函数可以用来评价对象检测算法。交并比函数计算预测输出与标准输出下,交集与并集之比。一般约定,在计算机检测任务中,如果IoU大于0.5就认为是正确的。0.5是人为约定的,如果你想严格一下可以定为0.6或者0.7。IoU衡量了两个边界狂重叠的大小。
目标检测

非极大值抑制

目前为止,学到的对象检测的一个问题是你的算法可能对同一个物体做出多次检测,非极大值抑制可以确保只做出一次检测。
目标检测
假设你需要在这张图里检测行人和汽车。你可能会放19*19的网格,理论上这辆车只有一个中点,所以它应该只分配到一个格子里。实践中,你跑对象分类和定位算法时,对于某个格子都有跑一次,中心点旁边的格子可能都会认为自己里面有对象。
目标检测
那么非极大值抑制是如何起作用的呢?因为你要在361个格子上都要跑一次,所以可能有好多个格子都会说我的Pc或者我的概率会比较高,而不是只有2个格子。所以最后可能会检测出多个结果。
目标检测
而非极大值抑制就是要清理这些多出来的结果。它通过比较概率值,将最大的那个变亮而把小的变暗。如果把小的删除,那么就只剩下最亮的那个。
目标检测
具体来说,对于每个格子都会有8个维度的输出,这里我们只检测汽车,所以省略后面的分类。具体过程如下图
目标检测

anchor boxes

如果你想让一个格子检测出多个对象,那么就可以使用anchor box这个概念。
目标检测
目标检测