零基础深度学习教程第七课:目标检测(上)
- 一、目标检测
- 1.1 目标检测概念
- 1.2 本章课程介绍
- 二、目标定位
- 2.1 边界框的描述
- 2.2 标签值的构成
- 2.3 损失函数
- 三、利用特征点实现目标定位
- 3.1 特征点的选择
- 3.2 利用特征点实现“分类定位”过程
- 3.3 其它特征点识别定位例子
- 四、目标检测
- 4.1 算法实现
- 4.1.1 第一步
- 4.1.2 第二步
- 五、只含卷积层的滑动窗口算法
- 5.1 传统滑动窗口卷积网络算法的缺点
- 5.2 传统滑动窗口卷积网络的改进
- 5.3 改进算法的实现过程
- 5.4 总结
一、目标检测
1.1 目标检测概念
在实际情景中你会发现,图片分类在大部分的现实情景中并不实用。因为现实中的碰到的图像,往往是下图这样的(一张图片中含多个对象):
那么多目标同时在一张图片中,若此时再拿猫狗大头照训练的分类卷积网络会毫无作用。就算是一张图片里只有一只猫和一只狗,给猫加点噪声,都可以使该分类网络分寸大乱。而现实中更多的时候,一张图片里的东西是杂乱无章的,此时必须要做一个框,把所需要看的目标给框出来,然后再看看这些东西是什么。
于是你来到计算机视觉的下一层挑战——目标检测(从大图中框出目标物体并识别)。这意味着不仅需要利用算法判断图片中目标的所属类别,还需要在图片中标出它的位置!即分类定位问题。
前几年出现的YOLO算法更是实现了快速实时物体的检测,你一路走过就告诉你视线里都有什么在哪里,要知道这在无人驾驶里是何等的利器。
1.2 本章课程介绍
首先,会在之前目标识别的基础之上学习图片中只含有一个对象的目标定位,之后会学习一张图片中含有多个对象的目标检测。
二、目标定位
2.1 边界框的描述
要想学习目标检测,首先需要了解目标定位。图片分类我们已经熟悉了,其过程无非就是算法遍历图片,判断其中的对象所属类别:
例如输入一张图片,通过卷积网络输出其所属类别(行人、汽车、摩托、背景)。当分类完成后,如果你想定位图片中的汽车位置,该怎么做呢?此时可以让之前的分类网络多输出几个单元,以此输出一个边界框(bounding box),即让神经网络再多输出四个数字:bx、by、bh、bw(这四个数字是被检测对象的边界框参数化表示),如下图所示:
现在对bx、by、bh、bw这四个参数作具体描述:假设图片左上角坐标为(0,0),右下角坐标为(1,1)。边界框的中心点坐标为(bx,by),边界框高度为bh,宽度为bw:
假设上图:bx=0.5、by=0.7、bh=0.3、bw=0.4
2.2 标签值的构成
由于有了边界框的存在,所以训练集的标签值不仅要包含对象所属类别标签,还需包含描述边界框的四个参数。现在具体讲一下标签值的构成:
假设该例子中有四个分类类别(行人、汽车、摩托、背景),所以输出的分类标签应该有四种情况(1-4);除了分类标签之外,还需要输出描述边界框的四个参数:
标签值y是一个列向量:其中第一个元素Pc表示是否含有该对象,如果分类出的对象属于前三类(行人、汽车、摩托),那么Pc=1;如果分类出的对象为背景则表示图片中没有任何对象,则Pc=0。
在Pc元素之后,紧跟着四个边界框参数bx、by、bh、bw。在四个参数后紧跟着表示检测的对象所属类别的三个参数c1(行人)、c2(汽车)、c3(摩托),通过这三个参数来表示该对象所属1-3中的哪一个类别,所以目标值y形式如下:
注:也可写作y = [ Pc bx by bh bw c1 c2 c3 ]T
例如,下图中的标签值y就为:
这是图片中有一个检测对象的情况,那么要是图片中没有检测对象呢?
当检测这样一张图片时,Pc将为0,当Pc为0时,其他所有参数将毫无意义!
2.3 损失函数
采用均方误差构造用于目标“分类定位”的卷积网络的损失函数:
当检测图片中含有检测对象时(即Pc=1时),损失函数为:
注:y1、y2、y3…就是Pc、bx、by…
综上所述,将图片数据集放入这个用于目标“分类定位”的卷积网络中,采用监督学习输出一个分类标签和四个参数值,就能实现“分类定位”的目的!以上就是利用卷积网络解决对象的分类和定位问题的详细过程。
三、利用特征点实现目标定位
上一节中,我们通过确定边界框的四大参数(bx、by、bh、bw)来实现目标的定位,现将这种思想进行推广:神经网络可以通过图片中对象的各个特征点坐标(x,y)来实现目标的分类与定位。
3.1 特征点的选择
假设你准备构建一个人脸识别系统:
希望通过算法得到眼角这个特征点的具体位置(x, y)。你可以让神经网络的最后一层多输出两个数字lx和ly,即眼角位置(lx, ly)。同理,如果想得到四个眼角各自的准确位置,可以让神经网络依此输出(l1x, l1y)、(l2x, l2y)、(l3x, l3y)、(l4x, l4y)。 综上,你可以输出图片中对象的任何一个特征点坐标(鼻子、嘴巴、牙齿…),假设脸部共有64个特征点:(l1x, l1y)、(l2x, l2y)、…、(l64x, l64y),这些特征点能帮助你定义脸部轮廓。
3.2 利用特征点实现“分类定位”过程
首先,选定特征点个数,并生成包含这些特征点“特征值+目标值”的训练集(训练集中每一个特征点样本都是人工辛苦标注的),然后利用神经网络输出脸部关键特征点的位置。 具体做法是,准备一个卷积网络和一些人脸照片数据集,将这些人脸照片输入到卷积网络中,输出0或1(0代表没脸、1代表有脸),若是1,再输出(l1x, l1y)、(l2x, l2y)…(l64x, l64y),所以一共有64×2+1=129个输出单元。最后通过优化损失函数实现人脸的识别与定位:
3.3 其它特征点识别定位例子
假设你希望对人体的姿态进行识别和检测:
可通过定义一些关键的特征点,例如胸部中点(l1x, l1y)、左肩(l2x, l2y)、左肘(l3x, l3y)、大腿(l4x, l4y)等等。然后通过神经网络标注人物姿态的关键特征点,再输出这些标注过的特征点,就相当于输出了人物的姿态动作。
综上,通过特征点实现目标的识别与定位过程相对较简单,只需批量添加输出单元,用以输出要识别的各个特征点的坐标值。值得注意的一点是,特征点的选择在每一张图片中必须一样,例如在图片一中,特征点1代表右眼角,那么在图片二中特征点1也必须代表右眼角。
四、目标检测
学习过了“边界框定位”和“特征点定位”之后,就可以构建一个基于滑动边界框的目标检测算法,我们将学习如何通过卷积神经网络进行对象检测。
4.1 算法实现
算法构建步骤如下:
4.1.1 第一步
用一些剪切好的带标签的汽车图片(整张图片几乎都被汽车占据,因为这样的训练效果较好)作为训练集,监督训练卷积网络。
训练过程:依此输入这些训练样本,通过卷积网络计算输出y(0或1),0代表图片中没车,1代表图片中有车(该训练的训练目的是让算法具有“识别”功能)。
4.1.2 第二步
利用训练好的网络来实现基于滑动窗口的目标检测算法,实现步骤如下。 1)首先选定一个特定大小的窗口,例如下方这个红色窗口
2)将这个红色窗口在输入图像左上角框出一个区域,然后将框出来的这个区域作为卷积网络的输入,通过卷积网络的计算,输出0或1:
3)第三步:当卷积网络预测完第一个框出来的图像之后,此时红色框将会向右移动一步(步幅大小是有参数控制),然后重复第二步的操作:
4)第四步:迭代上述操作,直至红色窗口滑过图片的每一个角落(滑动的快慢是由步幅决定的)。以上过程就是所谓的图像滑动窗口操作。注:还可以通过选定滑动窗口的大小来调节算法,如下图:
其实,一个基于滑动窗口的目标检测算法相当于多个目标识别与定位的算法组成在一起的,因为每当边界框滑动一次剪切下来的图片,卷积网络相当于就要做一次目标识别与定位。该算法虽然能起到目标检测的效果,但是存在一些缺点,下一节将介绍改进方法。
五、只含卷积层的滑动窗口算法
5.1 传统滑动窗口卷积网络算法的缺点
以上是该算法的缺点之一,这个算法另一个缺点就是滑动窗口划出的每一个子图像都需要放进算法里面跑一遍(卷积网络需要逐个处理这些子图像),这样会造成大量的计算资源消耗,我们虽然可以将滑动步幅或边框设大一些,这样能起到节省计算成本的效果,但是这样做将无法准确定位图片中的目标,从而降低算法的预测准确性。为了解决上述问题,本节介绍一种只包含卷积层的滑动窗口算法。
5.2 传统滑动窗口卷积网络的改进
为构建只含卷积层的滑动窗口算法,首先介绍如何将传统卷积网络中的全连接层转化为卷积层。
(1)传统目标“识别定位”卷积网络
假设目标检测算法输入一个14×14×3的图像,经过如下卷积、池化、全连接操作,最终由softmax单元输出预测值y(4种可能)与目标位置:
(2)改进后的卷积网络
现在将上述的传统卷积网络稍作改进,将第一层的全连接层换成用400个5×5×16的过滤器进行卷积,输出1×1×400的三维矩阵(从数学角度讲上看,这个1×1×400的三维矩阵与全连接层的数据量是一样的)。将第二层的全连接层换成用400个1×1过滤器进行卷积,还是输出1×1×400的三维矩阵。最后再经过1×1的过滤器卷积得到最终输出1×1×4的矩阵:
以上就是用卷积层代替全连接层的过程!
5.3 改进算法的实现过程
现在不需要将原始图像划分成多个子图像分别进行卷积运算,而是直接把原始图像输入进卷积网络进行计算(滑动窗口在网络内部自动划分子图像),这样就能让相邻子图像之间的公共区域共享卷积计算。 假设现在将一张28×28×3的图像直接输入进卷积神经网络(不需要再划分子图像分别输入),然后利用改进后的算法得:
5.4 总结
总结一下滑动窗口实现过程,输入一张图片进用于目标检测的神经网络,网络会通过滑动窗口自动在这张图片上划分出多个子区域,总有一个区域里面包含了汽车:
我们不必再用连续的卷积操作分别计算每张划分后的子图片来识别图片中的汽车,而是直接对这一整张图片进行卷积操作,一次性输出所有预测值。
以上就是目标检测算法改进的全部内容,不过这个算法的依然有缺点,下一课将介绍目标检测中最为经典的YOLO算法。