Deep Learning Note: 4-8 边框预测

1. 边框预测

  前文介绍的滑窗算法的一个缺点是无法准确给出目标的边框,这是因为在一轮滑窗过程中使用的窗口大小是固定的,且窗口每次移动一个特定的步长,如果窗口大小和移动步长不合适,可能会刚好跳过目标,或者只包含了目标的一部分。

  YOLO算法给出了更精确地进行边框预测的方法。YOLO 是 You Only Look Once 的缩写,其基本步骤是,将输入图像划分为若干网格,在每个网格上通过图像分类和定位算法。

  例如将一张 $100 \times 100$ 的图片通过 $3 \times 3$ 的网格划分为 9 块,如图 1 所示。这里为了方便说明,只使用了 $3 \times 3$ 的网格,实际中通常会使用更精细的网格,如 $19 \times 19$。

图 1

图 1

  对于图 1 中的每个格子,其标签的定义与分类和定位问题相同。仍以之前的检测图片中行人、汽车、摩托车的问题为例,标签为:

\begin{equation}
y = \begin{bmatrix}p_c \\ b_x \\ b_y \\ b_h \\ b_w \\ c_1 \\ c_2 \\ c_3\end{bmatrix} \tag{1}
\end{equation}

  式 (1) 中,$p_c$ 表示该网格中是否有目标,如果有目标(行人/汽车/摩托车),则 $p_c = 1$;如果没有目标,则 $p_c = 0$。$b_x$、$b_y$、$b_h$、$b_w$ 为目标位置。如果有目标,即 $p_c = 1$ 时,$c_1$、$c_2$、$c_3$ 表示图像中是否有对应分类(行人/汽车/摩托车)的目标,每个网格中最多只能有 1 个目标,即 $c_1$、$c_2$、$c_3$ 中最多只能有一个为 1。

  YOLO 算法以目标中心点的位置来判断目标所在网格,每个目标只能属于一个网格,如果目标占据了多个网格,则只有目标中心点所在的网格有 $p_c = 1$。例如对于图 1 中的两辆车,其中心点分别位于第 4 和 第 6 号网格,这两个网格的 $p_c = 1$;而对于 5 号网格,虽然它包含了两辆车的一小部分,但两辆车的中心都不在该网格,故标记该网格 $p_c = 0$。

  图 1 中共有 $3 \times 3$ 个网格,每一个网格都有一个 $8 \times 1$ 的标签,则整张图像的标签、也就是网络输出的大小为 $3 \times 3 \times 8$。由此可以设计一个网络,其输入为 $100 \times 100 \times 3$ 的图像,输出大小为 $3 \times 3 \times 8$。

  在测试时,对于网络输出 $3 \times 3 \times 8$ 的数据,首先读取 $3 \times 3$ 个位置上的 $p_c$,即检查这 9 个网格中是否有目标,如果某个网格的 $p_c = 1$,则进一步检查 $c_1$、$c_2$、$c_3$ 判断目标类型,并通过 $b_x$、$b_y$、$b_h$、$b_w$ 找到目标位置。这个算法只适用于每个网格中最有只有 1 个目标的情况,通过使用更精细的网格,可以降低同一网格中同时出现两个目标的概率。

  YOLO 算法的一个优势是它直接输出了目标的准确边框,边框可以具有任意的比例和位置,不再像滑窗算法那样受到窗口大小和移动步长的限制。另外,它的实现也是卷积式的,通过一次传播传播即可完成对 9 个网格的预测,而不必分别对每个网格进行独立计算。这也使得 YOLO 算法的运行速度非常快,甚至可以进行实时对象检测。

  下面对边框的位置,即 $b_x$、$b_y$、$b_h$、$b_w$ 的取值,给出更详细的定义。对于图 1 中的 6 号网格,其中有一辆车,规定该网格左上角为坐标 $(0, 0)$,该网格右下角为坐标 $(1, 1)$,如图 2。

图 2

图 2

  $b_x$ 和 $b_y$ 定义为目标中心点(图 2 中黄点)在网格中的坐标,有 $b_x = 0.4$、$b_y = 0.3$;$b_h$ / $b_w$ 定义为目标高度/宽度占网格高度/宽度的比例,有 $b_h = 0.5$、$b_w = 0.9$。可以得到该网格的标签为:

\begin{equation}
y = \begin{bmatrix}1 \\ 0.4 \\ 0.3 \\ 0.5 \\ 0.9 \\ 0 \\ 1 \\ 0\end{bmatrix} \tag{1}
\end{equation}

  需要注意的是 $b_x$ 和 $b_y$ 的取值在 0 和 1 之间,而 $b_h$ 和 $b_w$ 的值可以大于 1,例如目标很宽,横跨了多个网格,则其 $b_h$ 就会大于 1。

2. 交并比

  通过检测算法得到目标的边界后,可以使用交并比(Intersection Over Union,IoU)来对这个边界进行评价。交并比顾名思义,就是交集和并集的比。

  例如对于图 3 左图所示的样本,其中有一辆车,标记为红框,算法检测到的车的边界为紫框,则 IoU 的值为红框和紫框的交集(图 3 中图的黄色区域),除以红框和紫框的并集(图 3 右图的绿色区域)。

图 2

图 3

  IoU 的值越高,表示算法的检测结果与实际情况越接近,算法的检测越准确。通常使用 0.5 作为判断算法检测是否正确的阈值,当 $IoU > 0.5$ 时,认为算法的检测是正确的。这个阈值可以根据实际需要进行调整,如果对算法的要求更加严格,则可以使用更大的阈值,如 0.6 或 0.7 等等。

3. 非极大值抑制

  前面所介绍对象检测算法的一个问题是,可能会在多个位置都检测到同一个物体,通过非极大值抑制(Non-Max Suppression),可以确保算法对每个物体只检测到一次。

  仍前面检测图像中行人、汽车和摩托车的问题为例,对于如图 4 所示的图像,使用 $19 \times 19$ 的网格进行划分,在每个网格上进行目标分类和定位。

图 4

图 4

  如前所述,物体所在的网格定义为物体中心点所在的网格,对于图 4 中的两辆车,可能会有多个网格都认为汽车的中心点(图 4 中绿点和黄点)在自己的范围内($p_c = 1$),因此在网络的输出中,同一辆车会被重复检测出来多次,如图 5 所示。

图 5

图 5

  图 5 中边框旁边的数字表示概率,可以据此通过以下步骤去除图 5 中的重复检测:

  1. 首先找到图中检测概率最大的那个边框,即图 6 中绿色箭头所指的边框,对应概率为 0.9。
  2. 保留绿色箭头所指的边框,去除与该边框具有较大 IoU 的其他边框。图 5 中与 0.9 概率的边框具有较大 IoU 的边框如图 6 中红色箭头所示,保留绿色箭头的边框,去除红色箭头的边框,此时对于右侧的汽车,只保留了一次检测结果。
  3. 在剩余的边框中找到检测概率最大的那个边框,即图 6 中蓝色箭头所指的边框,对应概率为 0.8。
  4. 保留蓝色箭头所指的边框,去除与该边框具有较大 IoU 的其他边框,旁边概率为 0.7 的边框。
图 6

图 6

  经过以上步骤,只有绿色和蓝色箭头所指的边框被保留了下来,每辆汽车只保留了一个检测结果。这个过程就是非极大值抑制。

  下面给出非极大值抑制的一般方法,为了方便说明,这里以检测一类目标的情况为例,如仅检测图片中的汽车,不在检测摩托车和行人,此时网络输出的预测为:

\begin{equation}
y = \begin{bmatrix}p_c \\ b_x \\ b_y \\ b_h \\ b_w\end{bmatrix}
\end{equation}

  由于只检测汽车一类目标,$y$ 中就不在包含对应各个分类的 $c_1$、$c_2$ 和 $c_3$,此时 $p_c$ 即为检测到汽车的概率。非极大值抑制的过程为:

  1. 丢弃所有 $p_c \leq 0.6$ 的边框(预测结果)。
  2. 重复进行以下步骤,直到所有的边框都被处理过一遍:
    2.1. 找到具有最大 $p_c$ 的边框,输出它作为一个预测结果。
    2.2. 对于剩下的边框,如果它与上一步所找到边框的 $IoU \geq 0.5$,则将该边框丢弃。

  上面的步骤只是针对检测一类目标的情况,如果要同时检测多类目标,如同时检测行人、汽车、摩托车,则网络输出如式 (1) 所示,其中有 $c_1$、$c_2$、$c_3$ 分别表示目标是行人、汽车、摩托车的概率,此时需要对这 3 个分类分别进行非极大值抑制。

4. Anchor Box

  目前介绍的目标检测算法都要求一个网格中最多只有一个目标,例如前面检测图像中行人、汽车和摩托车的问题,对于如图 7 所示的输入图片,将其划分为 $3 \times 3$ 的网格,此时图中行人的中心点(黄点)和汽车的中心点(蓝点)都位于同一个网格,而对于该网格,网络输出的形式如式 (1),它只能表示一个边框,

图 7

图 7

  使用 Anchor Box 可以实现多个目标的检测。例如规定两种 Anchor Box,如图 8 所示。

图 8

图 8

  此时重新定义样本的标签(也就是网络输出)为:

\begin{equation}
y = \begin{bmatrix}p_c^{(1)} \\ b_x^{(1)} \\ b_y^{(1)} \\ b_h^{(1)} \\ b_w^{(1)} \\ c_1^{(1)} \\ c_2^{(1)} \\ c_3^{(1)} \\ p_c^{(2)} \\ b_x^{(2)} \\ b_y^{(2)} \\ b_h^{(2)} \\ b_w^{(2)} \\ c_1^{(2)} \\ c_2^{(2)} \\ c_3^{(2)}\end{bmatrix} \tag{2}
\end{equation}

  式 (2) 相当于将两个式 (1) 垂直叠加起来,分别表示两个 Anchor Box,各值的上角标 $(i)$ 表示该值属于第 $i$ 个 Anchor Box。$c_1^{(i)}$、$c_2^{(i)}$、$c_3^{(i)}$ 表示图像中第 i 个 Anchor Box 是否有对应分类(行人/汽车/摩托车)的目标。

  在未使用 Anchor Box 时,每个目标都被分配给其中心点所在的网格,网络输出大小为 $3 \times 3 \times 8$。使用 Anchor Box 后,每个目标都被分配给其中心点所在的网格,以及与其具有最大 IoU 的 Anchor Box,网络输出大小为 $3 \times 3 \times 16$。

  例如对于图 7 中的人,它的中心点位于第 3 行第 2 列的网格,其形状与图 8 中的 Anchor Box 1 具有最大的 IoU,标记第 8 个网格的 Anchor Box 1 为行人。类似地,对于图 7 中的汽车,它的中心点也位于第 3 行第 2 列的网格,其形状与图 8 中的 Anchor Box 2 具有最大的 IoU,标记第 8 个网格的 Anchor Box 1 为汽车。则该网格的标签为(省略了坐标 $b_x$、$b_y$、$b_h$、$b_w$ 的值):

\begin{equation}
y = \begin{bmatrix}1 \\ b_x^{(1)} \\ b_y^{(1)} \\ b_h^{(1)} \\ b_w^{(1)} \\ 1 \\ 0 \\ c_3^{(1)} \\ 1 \\ b_x^{(2)} \\ b_y^{(2)} \\ b_h^{(2)} \\ b_w^{(2)} \\ 0 \\ 1 \\ 0\end{bmatrix}
\end{equation}

  再举一例,如果某个网格中只有汽车,则其标签的形式如下(其中的 ? 表示不关心):

\begin{equation}
y = \begin{bmatrix}0 \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ 1 \\ b_x^{(2)} \\ b_y^{(2)} \\ b_h^{(2)} \\ b_w^{(2)} \\ 0 \\ 1 \\ 0\end{bmatrix}
\end{equation}

  如果使用了两个 Anchor Box、而某个网格中有 3 个对象,或者某个网格中的两个对象属于同一个 Anchor Box,则算法无法处理这些情况。需要注意的是,上面为了方便说明,只使用了 $3 \times 3$ 的网格和两种 Anchor Box,实际中可以根据需要使用更多网格和 Anchor Box。例如使用 $19 \times 19$ 的网格,此时两个对象属于一个网格的概率会大大降低。对 Anchor Box 数量的选择通常是手工进行的,只要能覆盖到目标的各种形状即可,更高级的做法是通过 K-均值算法对目标形状进行聚类。

  Anchor Box 可以让算法更加专精,如前面使用两个 Anchor Box 检测行人和汽车的例子,算法的一部分输出可以专精于检测瘦高(图 8 中 Anchor Box 1)的目标,另一部分输出可以专精于检测矮长(图 8 中 Anchor Box 2)的目标。

5. YOLO 算法

  前面已经介绍了 YOLO 算法的一些关键组件,下面把它们组合到一起,构成 YOLO 算法。

  还是以从图片中识别行人、汽车、摩托车的问题为例,使用 $3 \times 3$ 的网格和前文例子中的两个 Anchor Box。

  图 9 所示的输入图像被划分为了 9 个网格,为了方便说明,在每个网格左下角进行了编号。

图 9

图 9

  图 9 中第 8 号网格中有一辆车,则该网格的标签为(省略了坐标 $b_x$、$b_y$、$b_h$、$b_w$ 的值):

\begin{equation}
y = \begin{bmatrix}0 \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ 1 \\ b_x \\ b_y \\ b_h \\ b_w \\ 0 \\ 1 \\ 0\end{bmatrix}
\end{equation}

  而图 9 中第 1 ~ 7 号和第 9 号网格中什么都没有,这些网格的标签为(其中的 ? 表示不关心):

\begin{equation}
y = \begin{bmatrix}0 \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ 0 \\ ? \\ ? \\ ? \\ ? \\ ? \\ ? \\ ?\end{bmatrix}
\end{equation}

  通过以上方法标记样本,每个样本的标签的大小为 $3 \times 3 \times 2 \times 16$,然后就可以使用这些被标记的数据进行训练。

  模型输入一张图像,输出一组大小为 $3 \times 3 \times 2 \times 8$ 的数据,或者写成 $3 \times 3 \times 2 \times 16$,如图 10 所示。

图 10

图 10

  网络对 $3 \times 3$ 网格中的每个网格给出两个 Anchor Box 的预测,对于其中检出目标($p_c = 1$)的预测中的边框,通过非极大值抑制进行过滤,其过程如下。

  对于如图 10 所示的输入图像,网络在每个网格中给出对应两个 Anchor Box 的两个预测边框,如图 11 所示。

图 11

图 11

  接下来去除预测概率较低的边框,如图 12。

图 12

图 12

  最后,对于每个要检测的分类(行人、汽车、摩托车),分别使用非极大值抑制来得到最终的预测结果,如图 13。

图 13

图 13