入职以后,慢慢接触到图像分类以及目标检测这一块,由于之前一直做的都是NLP相关,对于图像这一块了解甚少。因此觉得需要记录一下学习的一个过程,以便以后复习。由于个人水平有限,如果文章有错误,还恳请各位指出,万分感谢~
对于目标检测,这是一个十分复杂和困难的任务,其主要有两个部分:
- 目标定位
- 物体分类
用通俗的话来说就是,先要找出图片中的object,再去识别这个object是什么。本文主要分析目标检测中如何去定位到这个物体的方法。
单物体的定位
首先我们针对图片中只有单个物体来进行讨论分析。最初的物体定位的方法是参考图片分类的方法。如下图所示
在图片分类中,输入一张图片给网络,将经过一个卷积网络,然后把提取的特征输入到softmax层中,输出这张图片的label。而在物体检测中,我们在提取完特征之后多加了一个输出,也就是输出物体所在的bounding box的坐标。这样,我们的网络就可以得到图片中物体所在的位置以及类别了。
假设我们现在需要检测一张图片中是否有车,行人,摩托车这三个类。那么我们可以定义网络的输出为:
其中,输出 $y$ 的第一项 $p_c$ 代表这张图片中是否存在我们需要检测的物体的概率,0代表图片中不存在需要检测的物体,1代表图片中存在。紧接着的四项 $[b_x,b_y,b_w,b_h]$ 代表bounding box的位置,$[b_x,b_y]$ 为物体的bounding box的中点坐标,$b_w$ 为bounding box的宽,$b_h$ 为bounding box的高。$[c_1,c_2,c_3]$ 代表检测出的物体属于车,行人以及摩托车这三个类的概率。
那么损失函数可以定义为
其中 $y_i$ 代表网络输出 $y$ 的第 $i$ 项。当图片中有我们需要检测的物体时,我们的损失函数就是计算整个向量 $y$ 的均方误差;而当图片中不包含我们需要检测的物体时,我们只需要计算 $y_1$ 的均方误差,而对其余的输出不再关心。
这样我们就可以检测这种图片中只包含有一种物体的情况,对于一张图内有多个物体的情况,我们可以是用滑窗的思想来进行处理。假设我们的识别任务是,识别出图片中的车辆位置
step1: 制作一个数据集,使得汽车占了图像的绝大部分;
step2: 针对上一步制作的数据集,训练一个分类模型,判断图片是否是汽车;
step3: 在图片中取一个固定大小的框,固定步长,滑动窗口遍历整个图片。每次对滑窗中的图片输入到第二步中训练好的模型,判断图片是否有汽车;
step4: 扩大框的大小,重新执行第三步,直到框的大小取到整个图的大小;
这样我们就可以识别出一张图片里多个汽车了。但是这个方法有两个缺点:
- 针对一个滑窗,我们需要遍历整个图像,其中有大量的计算是重复的;
- 针对一张图像,我们需要迭代不同大小的滑窗;
针对第一点,研究学者们做出了改进。假设我们的图片分类模型如下图所示
研究学者们针对模型的全连接层进行了调整,把第一个全连接层改为了有400个大小为5*5*16的卷积核的卷积层,这样卷积的输出形状为1*1*400;针对第二个全连接层,我们可以使用400个大小为1*1*400的卷积核的卷积层代替,这样我们卷积层的输出仍然是1*1*400,最后使用4个1*1*400的卷积核的卷积层。这样我们的网络就是一个全卷积网络了。具体结构如下图所示:
这样做有一个好处,就是针对一张图片,我们的滑窗操作可以直接类似于卷积,在整张图片上做一次计算即可,这样就避免了许多冗余的计算,具体过程如下图所示:
假设我们的图片大小为16*16,而我们取的滑窗大小为14*14。此时,我们就不需要再把图片中14*14的滑窗从图中取出来输入到网络中,而是直接对整张图片输入到网络中进行计算。这样我们最后会得到的向量是2*2*4。输出向量的前两个维度2*2代表我们的滑窗的个数,对于16*16的图像,我们使用14*14的滑窗最后得到的结果是2*2。而向量的最后一个维度代表了当前滑窗识别出的物体属于4个类的概率。这样就避免了许多冗余的计算。
针对第二点,研究学者不再遍历滑窗大小,而是通过一些方法去得到大约2000个候选框。再对这2000个候选框进行分类,最后通过回归的方法对bounding box进行完善。
对于候选框的选取方法,主流的有如下几种:
- select
交并比(IoU,Intersection over union)
那么我们一般如何来定义bounding box的正确性呢。一般是用IoU来定义bounding box的准确性。那么IoU是如何计算得出的呢,我们可以看下面这个例子。
如上图所示,红色框框是真实的bounding box,而灰色的框框是我们模型预测的bouding box。那么我们怎么去计算IoU呢?
IoU的计算就是把bouding box与predict box的交集面积除以两者并集的面积,一般如果 $IoU>0.5$ 我们就会认为预测的框是框对的。当然,如果你想要模型预测的框更加准确,你可以把阈值调高到0.6或者0.7都可以。
非极大值抑制
针对一个物体,我们检测出了多个box都框住了它,那么我们如何去除掉多余的box,但是不会去除掉别的物体的box呢。这个时候就可以使用非极大值抑制的方法。这个算法的主要思想如下所示:
step1: 在当前图片中选取一个概率值最大的bounding box;
step2: 计算其他bounding box与当前选定的box的IoU,去除掉IoU大于0.5的box;
step3: 从剩下的bounding box中继续选取概率值最大的那个,重复第二步,直到遍历完所有的box后停止;
这样我们就可以得到多个物体的bounding box了。