深度学习之目标检测-YOLO算法(一)

Hits: 46

今天我们开始介绍Coursera-Deep Learning第四课卷积神经网络的week3的内容:目标检测,主要内容是YOLO算法。在详细介绍这个算法之前我们先普及一些目标检测的基本知识。

目标定位(Localization)

所谓的检测(Detection)指的是从一张图片中识别出是否存在某个目标,而目标定位(Localization)指的是在识别目标的同时,输出它在图像中的位置。我们知道使用神经网络进行目标检测是很容易的,那么如何进行目标定位呢?很简单,跟目标检测一样,我们不仅可以对图像内容打标签,还可以对它所在的位置打标签,然后通过神经网络训练,定位目标。所以,一个完整的Object Detection应该包括Detection和Localization两部分,结合起来后我们得到以下的label \(y\):

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

其中,

  • \(p_c\)表示的是否有目标,0没有;1有
  • \(b_x\)和\(b_y\)表示该目标的中心点的坐标
  • \(b_h\)和\(b_w\)表示该目标的高度和宽度
  • \(c_1\),\(c_2\)和\(c_3\)分别表示该目标所属的类别,0没有;1有。

目标的高度和宽度以及坐标都是指目标大小所占整个图像的百分比,一般我们认为图像左上角的坐标为\((0,0)\),右下角的坐标为\((1,1)\)(这些都是需要人工标注的,也是个辛苦活儿)。定义了输出label之后,我们再看一下它的loss function:

$$
\ell(\hat{y},y) = \begin{matrix} (\hat{y_1}-y_1)^2 + ... + (\hat{y_8}-y_8)^2 & \text{if} \ y_1=1 \\ (\hat{y_1}-y_1)^2 & \text{if} \ y_1=0 \end{matrix}
$$

特征点检测(Landmark Detection)

上面我们介绍了如何使用神经网络来学习得到一个目标的位置(边界框),这个位置其实就是坐标。既然位置坐标可以通过学习获得,那么很自然地,一个目标的特征点也能通过学习获得,因为特征点也是由坐标组成的嘛。那什么是特征点呢?举个例子,对人脸而言,特征点可以是眼角,面部轮廓,眉毛等。如下图所示:
Imgur
特征点检测的方法和目标定位没什么区别,只不过label \(y\)中多增加了一些特征点的坐标而已。那特征点检测有什么用呢?很常见的一个应用-美颜相机的AR功能,比如它可以在你的头顶加一个皇冠,那么头顶部位的识别实际上就是一种特征点检测。

目标检测(Object Detection)

目标检测算法大致可以分为两步(以识别汽车为例):

  • 先找到一些只有汽车的图片,然后把他们丢到CNN里面训练,最终得到一个汽车分类器
    Imgur

  • 滑动窗口算法,采用各种大小不同的窗口扫描图片,把每一个扫描过的窗口里的图像丢到分类器里,去判断是否是汽车
    Imgur

很明显,这个所谓的滑动窗口算法是很愚蠢的(当然也很直观),简直就是蛮力,效率太低了。对于以前的线性分类器而言可能还不错,但是对CNN来说计算量就太大了。下面我们介绍一种高效的实现方式-卷积实现。

滑动窗口的卷积实现

  • 全连接层转化为卷积层
    如何将全连接层转化为卷积层呢?请看下图:
    Imgur
    转换开始于第一个全连接层,上图的FC是一个包含400个神经元节点的集合;而下图则是通过400个\(5 \times 5 \times 16\)的滤波器把图像卷积成一个\(1 \times 1 \times 400\)的卷积层,这两者在数学上是等价的,但是他们的作用却截然不同,我们可以通过后者高效地实现滑动窗口算法。

  • 滑动窗口的卷积实现
    下图表示的就是一个\(16 \times 16\)的原始图像,使用大小为\(14 \times 14\)的滑动窗口的卷积实现。
    Imgur
    我们可以看到,下半部分输出层黄色正方形的左上角的蓝色格子和上图的蓝色格子是等价的,其余的也类似。因为滑动窗口的大部分格子都是共享的,通过卷积实现之后,一次正向传播即可完成四个窗口的预测,这样便可以减少大量的冗余计算,提高效率

简单的滑动窗口算法是有其局限性的,比如它对目标边框的检测并不准确,这个很好理解。下文我们就正式介绍YOLO算法是如何更精准地检测目标边界的。


发表评论

电子邮件地址不会被公开。 必填项已用*标注