滑动窗口法的卷积实现虽然效率更高,但仍然存在问题,不能输出最精准的边界框。因为滑动窗口法中,取这些离散的位置集合并不能完全匹配目标大小、位置。

目标检测 任意矩形框 目标检测 bounding box_目标检测 任意矩形框

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

        比如输入图像是 100×100 的,然后在图像上放一个3×3网格,实际实现时会用更精细的网格,可能是 19×19。基本思路是使用图像分类和定位算法,逐一应用在图像的 9 个格子中。更具体一点,定义训练标签,所以对于 9 个格子中的每一个指定一个标签y,y是 8 维的:

目标检测 任意矩形框 目标检测 bounding box_python_02

        pc等于 0 或 1 取决于这个绿色格子中是否有图像。然后bx, by, bh ,bw作用就是,如果那个格子里有对象,那么就给出边界框坐标。c1,c2,c3就是你想要识别的三个类别,背景类别不算,所以你尝试在背景类别中识别行人、汽车和摩托车,那么c1,c2,c3可以是行人、汽车和摩托车类别。这张图里有 9 个格子,所以对于每个格子都有这么一个向量。

      PS:所以,一个向量的长度为1+4+nc,1为是否有目标,4表示bx, by, bh ,bw目标外接矩形,nc为目标的one-hot编码,长度为要识别的类别数。

目标检测 任意矩形框 目标检测 bounding box_目标检测 任意矩形框_03

        这张图有两个对象,YOLO 算法做的就是,然后将这个对象分配给包含对象中点的格子。所以左边的汽车就分配到这个格子上(编号 4),然后这辆 Condor(车型: 神鹰)中点在这里,分配给这个格子(编号 6)。所以即使中心格子(编号 5)同时有两辆车的一部分,我们就假装中心格子没有任何我们感兴趣的对象,所以对于中心格子,分类标签𝑦和这个向量类似,和这个没有对象的向量类似,即:

目标检测 任意矩形框 目标检测 bounding box_深度学习_04

        绿色框和黄色框的格子目标标签应该是这样的:

目标检测 任意矩形框 目标检测 bounding box_自动驾驶_05

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

目标检测 任意矩形框 目标检测 bounding box_目标检测 任意矩形框_06

        对于这个例子中,左上格子是 1×1×8,对应的是 9 个格子中左上格子的输出向量。所以总的目标输出标签尺寸就是 3×3×8:

目标检测 任意矩形框 目标检测 bounding box_目标检测 任意矩形框_07

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

这样的网格精细得多,那么多个对象分配到同一个格子得概率就小得多。

即使对象可以横跨多个格子,也只会被分配到 9 个格子其中之一,就是 3×3 网络的其中一个格子,或者 19×19 网络的其中一个格子。在 19×19 网格中,两个对象的中点处于同一个格子的概率就会更低。

特点:

        1)它显式地输出边界框坐标,所以这能让神经网络输出边界框,可以具有任意宽高比,并且能输出更精确的坐标,不会受到滑动窗口分类器的步长大小限制。

        2)这是一个卷积实现,有很多共享计算步骤,在处理这N×N计算中很多计算步骤是共享的,所以这个算法效率很高。

真值标签:

        这里有两辆车,我们有个 3×3 网格,我们以右边的车为例(编号 1),红色格子里有个对象,所以目标标签𝑦就是, 𝑝𝑐 = 1,然后𝑏𝑥、𝑏𝑦、𝑏ℎ和𝑏𝑤,然后𝑐1 = 0,𝑐2 = 1,𝑐3 = 0,边界框确定:

目标检测 任意矩形框 目标检测 bounding box_深度学习_08

        在 YOLO 算法中,对于这个方框,我们约定左上这个点是(0,0),然后右下这个点是(1,1),要指定橙色中点的位置,bx大概是 0.4,by大概是 0.3。然后边界框的高度用格子总体宽度的比例表示,所以这个红框的宽度可能是蓝线的 90%,所以bh是 0.9,它的高度也许是格子总体高度的一半,这样的话bw就是 0.5。换句话说,bx,by,bh,bw单位是相对于格子尺寸的比例,所以bx,by必须在 0 和 1 之间。如果它不在 0 和 1 之间,如果它在方块外,那么这个对象就应该分配到另一个格子上。

𝑏𝑥和𝑏𝑦必须在 0 和 1 之间,因为从定义上看,橙色点位于对象分配到格子的范围内,如果它不在 0 和 1 之间,如果它在方块外,那么这个对象就应该分配到另一个格子上。这个值( 𝑏ℎ和𝑏𝑤)可能会大于 1,特别是如果有一辆汽车的边界框是这样的(编号 3 所示),那么边界框的宽度和高度有可能大于 1。

PS:

        1、坐标量化时,bx,by,bh,bw是相对于格子尺寸的比例;

        2、每个目标只会被分配到一个格子上,以重点落地位置为准;

        3、𝑏𝑥和𝑏𝑦必须在 0 和 1 之间,边界框的宽度和高度有可能大于 1。

        指定边界框的方式有很多,还有其他更复杂的参数化方式,涉及到 sigmoid 函数,确保这个值( 𝑏𝑥和𝑏𝑦)介于 0 和 1 之间,然后使用指数参数化来确保这些( 𝑏ℎ和𝑏𝑤)都是非负数等。