Press "Enter" to skip to content

吴恩达卷积神经网络——学习笔记(三)

吴恩达卷积神经网络——学习笔记(三)

1. 目标定位 (Object Localization)
2. 特征点检测 (Landmark Detection)
3. 目标检测 (Object Detection)
4. 滑动窗口的卷积实现 (Convolutional Implementation of Sliding Window)
5. Bounding Box 预测 (Bounding Box Predictions)
6. 交并比 (Intersection over Union)
7. 非极大值抑制 (Non-max Suppression)
8. 锚框 (Anchor Boxes)

视频课程链接:

https://www.bilibili.com/video/BV1FT4y1E74V?

笔记参考链接:

https://blog.csdn.net/weixin_36815313/article/details/105728919

1. 目标定位 (Object Localization)

 

1.1 基本概念

 

对于图像分类和定位问题,通常只有一个较大的对象位于图片中间位置,我们要对它进行识别和定位。而在目标检测问题中,图片可以含有多个对象,甚至单张图片中会有多个不同分类的对象。因此,图片分类的思路可以帮助学习分类定位,而目标定位的思路又有助于学习目标检测,我们先从分类和定位开始讲起。

对于解决图像分类问题的步骤,可简单描述为输入一张图片到多层卷积神经网络,它会输出一个特征向量,并反馈给 softmax 单元来预测图片类型。假设分类的对象包括以下几类: 行人 、 汽车 、 摩托车 和 背景 ,则 softmax 函数会输出这四个分类的预测结果。

上述内容是标准的分类过程,要想再定位图片中汽车的位置,则可以让神经网络多输出4个单元,分别标记为
b x b_x b x ​ ,
b y b_y b y ​ ,
b h b_h b h ​ 和
b w b_w b w ​ ,即输出一个被检测对象的边界框(Bounding Box)的参数化表示。这里的
b x b_x b x ​ 和
b y b_y b y ​ 表示边界框的中心点坐标,
b h b_h b h ​

 

b w b_w b w ​

 

表示边界框的高度和宽度。

 

1.2 标签定义

 

 

接下来具体讲讲如何为监督学习任务定义目标标签 y y y 。假如上图的汽车图像是一张训练集图片,标记为 x x x ,经过神经网络输出的是边界框参数和一个分类标签,或分类标签出现的概率。目标标签 y y y 的定义如下: y = [ p c b x b y b h b w c 1 c 2 c 3 ] y=\begin{bmatrix} p_c \\ b_x \\ b_y \\ b_h \\ b_w \\ c_1 \\ c_2 \\ c_3 \end{bmatrix} ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ ​ p c ​ b x ​ b y ​ b h ​ b w ​ c 1 ​ c 2 ​ c 3 ​ ​ ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ ​

 

它是一个向量,其中第一个组件 p c p_c p c ​ 表示是否含有对象,如果对象属于前三类(行人、汽车、摩托车),则 p c = 1 p_c=1 1 ;如果是背景,即图片中没有要检测的对象,则 p c = 0 p_c=0 0 。第二到第五个组件 b x b_x b x ​ 、 b y b_y b y ​ 、 b h b_h b h ​ 和 b w b_w b w ​ 表示边界框的各项参数。第六到第八个组件 c 1 c_1 c 1 ​ 、 c 2 c_2 c 2 ​ 和 c 3 c_3 c 3 ​ 分别表示该对象属于1-3类中的哪一类,是行人,汽车还是摩托车。如果该对象为行人,则 c 1 = 1 c_1=1 1 ,其余为0;如果该对象为汽车,则 c 2 = 1 c_2=1 1 ,其余为0;如果该对象为摩托车,则 c 3 = 1 c_3=1 1 ,其余为0。

如果检测到对象,则
p c = 1 p_c=1 1 ,同时输出被检测对象的边界框参数
b x b_x b x ​ 、
b y b_y b y ​ 、
b h b_h b h ​ 、
b w b_w b w ​ 以及该对象类别
c 1 c_1 c 1 ​ 、
c 2 c_2 c 2 ​ 和
c 3 c_3 c 3 ​ 。如果图片中没有检测对象,则
p c = 0 p_c=0 0

,此时

 

y y y

 

的其它参数将变得毫无意义。

 

1.3 损失函数

 

这里将标签 y y y 的预测输出定义为 y = [ y 1 y 2 y 3 y 4 y 5 y 6 y 7 y 8 ] y=\begin{bmatrix} y_1 \\ y_2 \\ y_3 \\ y_4 \\ y_5 \\ y_6 \\ y_7 \\ y_8 \end{bmatrix} ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ ​ y 1 ​ y 2 ​ y 3 ​ y 4 ​ y 5 ​ y 6 ​ y 7 ​ y 8 ​ ​ ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ ​ 。损失函数可以定义为 L ( y ^ , y ) = { ( y 2 ^ − y 2 ) 2 + ( y 3 ^ − y 3 ) 2 + ( y 4 ^ − y 4 ) 2 + ( y 5 ^ − y 5 ) 2 y 1 = 1 ( y 1 ^ − y 1 ) 2 y 1 = 0 L(\hat{y},y)=\begin{cases} (\hat{y_2}-y_2)^2+(\hat{y_3}-y_3)^2+(\hat{y_4}-y_4)^2+(\hat{y_5}-y_5)^2 & y_1=1 \\ (\hat{y_1}-y_1)^2 & y_1=0 \\ \end{cases} L ( y ^ ​ , y ) = { ( y 2 ​ ^ ​ − y 2 ​ ) 2 + ( y 3 ​ ^ ​ − y 3 ​ ) 2 + ( y 4 ​ ^ ​ − y 4 ​ ) 2 + ( y 5 ​ ^ ​ − y 5 ​ ) 2 ( y 1 ​ ^ ​ − y 1 ​ ) 2 ​ y 1 ​ = 1 y 1 ​ = 0 ​ 通常做法是对边界框坐标应用平方差或类似方法,对 p c p_c p c ​ 应用逻辑回归函数,甚至采用平方预测误差,而不需要对 c 1 c_1 c 1 ​ 、 c 2 c_2 c 2 ​ 、 c 3 c_3 c 3 ​ 和 softmax 激活函数应用对数损失函数。

 

2. 特征点检测 (Landmark Detection)

 

上一节讲了如何利用神经网络进行目标定位,即通过输出四个参数值 b x b_x b x ​ 、 b y b_y b y ​ 、 b h b_h b h ​ 和 b w b_w b w ​ 给出图片中对象的边界框。更概括地说,神经网络可以通过输出图片上特征点坐标 ( x , y ) (x,y) ( x , y ) 来实现对目标特征的识别。

以人脸识别为例,假设你希望算法可以给出眼角的具体位置坐标 ( x , y ) (x,y) ( x , y ) ,你可以让神经网络的最后一层多输出两个数字 l x l_x l x ​ 和 l y l_y l y ​ ,作为眼角的坐标值。假设你想知道两只眼睛的四个眼角的具体位置,那幺从左到右,依次输出四个特征点坐标来表示这四个眼角,例如输出第一个特征点 ( l 1 x , l 1 y ) (l_{1x},l_{1y}) ( l 1 x ​ , l 1 y ​ ) ,第二个特征点 ( l 2 x , l 2 y ) (l_{2x},l_{2y}) ( l 2 x ​ , l 2 y ​ ) ,以此类推,这四个脸部特征点的位置就可以通过神经网络输出了。

 

除了以上所述的特征点,你还可以根据嘴部的特征点输出值来确定嘴的形状,从而判断人物是在微笑还是皱眉。如果你对人体姿态检测感兴趣,你还可以定义一些关键特征点,如胸部的中点,左肩,左肘,腰等,然后通过神经网络标注人物姿态的关键特征点,再输出这些标注过的特征点,就相当于输出了人物的姿态动作。

 

3. 目标检测 (Object Detection)

 

以构建一个汽车检测算法为例,大致的步骤如下:

 

创建一个标签训练集, x x x 表示汽车图片样本, y y y 表示对应的图片标签(建议可以适当剪切图片,使汽车居于中间位置并基本占据整张图片)

利用这个标签训练集训练卷积网络,即输入这些适当剪切过的图片,经过卷积神经网络输出预测结果 y ^ \hat{y} y ^ ​ ,0和1分别表示图片中有汽车或没有汽车。

 

训练完这个卷积神经网络,就可以用它来使用 滑动窗口法 实现目标检测。

选定一个特定大小的窗口,将这个窗口内的图像输入到卷积神经网络,神经网络判断方框内是否有汽车。
然后窗口向右滑动一定步长,并将窗口内的图像输入给卷积神经网络,再次运行神经网络进行判断,依次重复以上操作,直到这个窗口滑过图像的每一个角落。

选择一个更大的窗口,截取窗口区域并输入给卷积神经网络进行判断,再以某个固定步幅滑动窗口,重复以上操作,遍历整个图像。
继续扩大窗口大小,重复以上操作,这样不论汽车的大小以及在图片的什幺位置,总有一个窗口可以检测到它。

滑动窗口的目标检测算法具有明显的缺点,就是计算成本。你需要在图片中剪切出很多的小方块,并且一个个输入给卷积神经网络进行处理。如果选用的步幅很大,则会减少输入卷积网络的窗口个数,但是粗粒度可能会影响检测性能。反之,如果采用细粒度或小步幅,传递给卷积网络的小窗口会特别多,但这意味着超高的计算成本。

 

4. 滑动窗口的卷积实现 (Convolutional Implementation of Sliding Window)

 

为了构建滑动窗口的卷积应用,首先要知道如何把神经网络的全连接层转化成卷积层。

假设输入一个 14 14 1 4 × 14 14 1 4 × 3 3 3 的图像,使用16个大小为 5 5 5 × 5 5 5 的过滤器进行卷积操作后,输出大小为 10 10 1 0 × 10 10 1 0 × 16 16 1 6 的图像,经过一个窗口大小为 2 2 2 × 2 2 2 的最大池化层,图像尺寸减小到 5 5 5 × 5 5 5 × 16 16 1 6 。然后将其展开成一个一维数组,接着再添加一个具有400个单元的全连接层,最后通过 softmax 单元输出4个分类的概率,这4个分类分别对应是行人、汽车、摩托车和背景。

接下来将全连接层转化成卷积层。前面的卷积层部分保持不变,输出图像的尺寸为 5 5 5 × 5 5 5 × 16 16 1 6 ,使用400个维度大小为 5 5 5 × 5 5 5 × 16 16 1 6 的过滤器对它进行卷积操作,其输出维度为 1 1 1 × 1 1 1 × 400 400 4 0 0 。这里我们不再把它看作一个含有400个节点的集合,而是一个 1 1 1 × 1 1 1 × 400 400 4 0 0 的输出层。从数学角度看,它和全连接层是一样的,因为这400个节点中每个节点都有一个维度为 5 5 5 × 5 5 5 × 16 16 1 6 的过滤器,所以每个值都是上一层这些 5 5 5 × 5 5 5 × 16 16 1 6 激活值经过某个任意线性函数的输出结果。

 

然后使用400个 1 1 1 × 1 1 1 的过滤器进行卷积操作,则下一层的输出维度是 1 1 1 × 1 1 1 × 400 400 4 0 0 。最后再通过4个 1 1 1 × 1 1 1 的过滤器处理,得到一个 softmax 激活值。经过卷积神经网络的作用,最终得到这个 1 1 1 × 1 1 1 × 4 4 4 的输出层。

假设输入给卷积神经网络的图片大小是 14 14 1 4 × 14 14 1 4 × 3 3 3 ,测试集图片是 16 16 1 6 × 16 16 1 6 × 3 3 3 。在最初的滑动窗口算法中,首先将这片蓝色区域输入到神经网络中,输出预测的分类结果0或1,然后向右滑动2个像素,将这个绿框区域输入到神经网络,得到另外一个分类标签0或1。接下来继续将这个橘色区域输入给神经网络,卷积后得到另一个分类标签,最后对右下方的紫色区域进行一次卷积操作。最终,在输出层这4个子方块中,左上角子方块对应的是输入图像左上部分 14 14 1 4 × 14 14 1 4 区域的输出(红色箭头标识),右上角子方块对应的是输入图像右上部分 14 14 1 4 × 14 14 1 4 区域的输出(绿色箭头标识),左下角子方块对应的是输入图像左下部分 14 14 1 4 × 14 14 1 4 区域的输出(橘色箭头标识),右下角子方块对应的是输入图像右下部分 14 14 1 4 × 14 14 1 4 区域的输出(紫色箭头标识)。

 

结果发现,这4次卷积操作中很多计算都是重复的,即在执行滑动窗口的卷积过程中,卷积网络在这4次前向传播过程中共享了很多计算。因此我们不需要把输入图像分割成四个子集,分别执行前向传播,而是把它们作为一张图片输入给卷积神经网络进行计算,其中的公共区域可以共享很多计算。这样一来就提高了整个算法的效率,但是这种算法仍然存在一个缺点,就是边界框的位置可能不够准确。

 

5. Bounding Box 预测 (Bounding Box Predictions)

 

 

假设输入图像的尺寸是 100 100 1 0 0 × 100 100 1 0 0 ,将其划分成 3 3 3 × 3 3 3 网格。如果定义训练标签,需要对9个格子逐一定义一个训练标签 y = [ p c b x b y b h b w c 1 c 2 c 3 ] y=\begin{bmatrix} p_c \\ b_x \\ b_y \\ b_h \\ b_w \\ c_1 \\ c_2 \\ c_3 \end{bmatrix} ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ ​ p c ​ b x ​ b y ​ b h ​ b w ​ c 1 ​ c 2 ​ c 3 ​ ​ ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ ​ ,其中 p c p_c p c ​ 表示这个格子中是否有对象,如果这个格子里有对象,那幺就会给出边界框坐标 b x b_x b x ​ 、 b y b_y b y ​ 、 b h b_h b h ​ 和 b w b_w b w ​ , c 1 c_1 c 1 ​ 、 c 2 c_2 c 2 ​ 和 c 3 c_3 c 3 ​ 表示识别的三个类别,不包括背景类别。 YOLO 算法的做法是,取两个对象的中点,然后将这个对象分配给包含对象中点的格子。即使中心格子同时有两辆车的一部分,也假装中心格子没有任何我们感兴趣的对象。

如果训练一个输入为 100 100 1 0 0 × 100 100 1 0 0 × 3 3 3 的卷积神经网络,将图像输入给神经网络,因为这里划分成 3 3 3 × 3 3 3 网格,每一个格子都会得到一个8维输出向量,因此最终得到一个 3 3 3 × 3 3 3 × 8 8 8 的特征向量。

 

6. 交并比 (Intersection over Union)

 

 

交并比( loU )函数做的是计算两个边界框交集和并集之比,其中两个边界框的并集就是图中的绿色阴影部分),而交集就是图中的橙色阴影部分,因此交并比的计算就是把橙色阴影面积除以绿色阴影面积。

 

一般来说,在计算机检测任务中,如果 I o U ≥ 0.5 IoU\geq0.5 I o U ≥ 0 . 5 就算检测正确,如果预测器和实际边界框完美重叠,即交集等于并集, loU 就是1。人们定义 loU 这个概念是为了评价你的目标定位算法是否精准,这是衡量定位精确度的一种方式,你只需要统计算法正确检测和定位目标的次数,就可以用这样的定义来判断对象定位是否准确。

 

7. 非极大值抑制 (Non-max Suppression)

 

 

假设在上面这张图片里检测行人和汽车,将其划分成 19 19 1 9 × 19 19 1 9 的网格,理论上每辆车只有一个中点,即只有一个格子做出有车的预测。但实际上每个格子都运行一次图像检测和定位算法,神经网络可能会认为这辆车的中点在1号格子内部,也可能在2号或3号格子内部,因此可能会对同一个对象做出多次检测,而非极大值抑制的作用就是清理这些多余的检测结果。

实现非最大值抑制的步骤大致如下:

 

 

    1. 去掉所有预测概率 p c p_c p c ​ 小于或等于某个阈值(假设阈值为0.6)的边界框;

 

    1. 在剩余的的边界框中,选择概率 p c p_c p c ​ 最高的边界框。

 

    1. 遍历剩余的的边界框,如果和当前最高分框的交并比( IOU )大于一定阈值,则将这个边界框删除。

 

    1. 接下来在剩余的边界框中选择概率 p c p_c p c ​ 最高的边界框,重复上面的步骤2。

 

 

8. 锚框 (Anchor Boxes)

 

Anchor Box是为了解决同一个网格中有多个目标对象的情况。而现实情况中,你的网格划分越细,这种情况发生的就越少。

以上图为例,仍然使用 3 3 3 × 3 3 3 网格对图像进行划分,可以看到行人的中点和汽车的中点几乎在同一个网格中,而原先定义的标签 y y y 无法同时输出两个预测结果。

因此重新定义一个类别标签(如上图),其中 p c p_c p c ​ 表示这个格子中是否有对象, b x b_x b x ​ 、 b y b_y b y ​ 、 b h b_h b h ​ 和 b w b_w b w ​ 表示标记对象的边界框坐标, c 1 c_1 c 1 ​ 、 c 2 c_2 c 2 ​ 和 c 3 c_3 c 3 ​ 分别表示识别的三个类别,不包括背景类别。绿色方框标记的元素与 Anchor box 1 对应,橙色方框标记的元素与 Anchor box 2 对应。

 

Anchor Box的思路是,首先根据对象形状定义多个不同形状的 Anchor Box ,然后找出与每个 Anchor Box 交并比最大的实际边界框,将实际边界框的标签作为 Anchor Box 的标签,并且计算 Anchor Box 相对于真实边界框的偏移量。在本例子中 Anchor Box 的个数为2,输出标签 y y y 的维度是 3 3 3 × 3 3 3 × 16 16 1 6 或 3 3 3 × 3 3 3 × 2 2 2 × 8 8 8 。

 

目前 Anchor Box 的选择主要有如下三种方式:

人为经验选取
k-means聚类
作为超参数进行学习

Be First to Comment

发表回复

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