ng-深度学习-课程笔记-13: 目标检测(Week3)

1 目标定位( object localization )

目标定位既要识别,又要定位,它要做的事就是用一个框框把物体目标的位置标出来。

怎么做这个问题呢,我们考虑三目标的定位问题,假定图中最多只出现一个目标,假定图片的左上角为(0,0),右下角为(1,1)。

我们输出层的标签有这么几个,pc, bx, by, bh, bw, c1, c2, c3,其中pc表示是否存在目标,c1,c2,c3分别代表三个类别的目标是否存在,(bx, by)表示框框中心点的坐标,bh表示框框高度,bw表示框框宽度。

考虑损失函数,y = 0 时,只考虑pc之间的逻辑回归损失或平方损失都行,因为此时没有目标;

y = 1时,一般对pc采用平方损失或者逻辑回归的损失,对c1, c2, c3采用softmax的损失,对bx, by, bh, bw采用平方损失。

 

 

2 特征点检测( landmark detection )

假如你想标记出人脸中的特征位置(比如眼睛),对于神经网络的输出单元,首先有个face表示是否有人脸,然后是一系列的特征点的坐标,比如l1x, l1y, l2x, l2y, l3x, l3y, l4x, l4y表示四个特征点,表示左眼的外眼角和内眼角,右眼的外眼角和内眼角。

当然要训练这个网络,必须有标签好的数据,一般都是人为辛苦标注的。

这个检测脸部特征模块,是一个识别脸部表情的基本模块,也是计算机图形效果(比如实现头戴皇冠,脸部扭曲)的一个关键模块。

如果你对人体姿态检测感兴趣的话,也是使用类似上述的方法,先检测出人体姿态的关键特征点。

 

3 目标检测( object detection )

比如我们想做一个汽车的目标检测,首先先构建一个数据集,输入图像,输出图像是否为汽车,注意有汽车的图像中汽车要尽量占满整个画布且在正中央。

用这个数据集训练一个卷积神经网络,能够预测图像中是否为汽车。

然后可以利用滑动窗口的技术,先用小窗口,对新来的图像用窗口截取一段用网络判断是否为汽车,依次滑动窗口进行判断,对每个位置用0和1标记,直到滑过图像的每一个角落。然后增大窗口,重复操作,再增大一点窗口,重复操作。

滑动窗口的缺点就是计算成本太高,每次滑动都要用卷积来计算一次,这样滑动太慢了。

如果滑动stride小,则计算量大;如果stride大,可能无法准确定位到目标。

 

4 滑动窗口的卷积实现( Convolutional implementation of sliding windows )

事实上,我们不用像上一节中那样,自己去滑动窗口截取图片的一小部分然后检测,卷积这个操作就可以实现滑动窗口。

如下图中间一行卷积的初始图,我们假设输入的图像是16*16的,而窗口大小是14*14,我们要做的是把蓝色区域输入卷积网络,生成0或1分类,接着向右滑动2个元素,形成的区域输入卷积网络,生成0或1分类,然后接着滑动,重复操作。我们在16*16的图像上卷积了4次,输出了4个标签,我们会发现这4次卷积里很多计算是重复的。

而实际上,直接对这个16*16的图像进行卷积,如下图中间一行的卷积的整个过程,这个卷积就是在计算我们刚刚提到的很多重复的计算,过程中蓝色的区域就是我们初始的时候用来卷积的第一块区域,到最后它变成了2*2的块的左上角那一块,我们可以看到最后输出的2*2块,刚好就是4个输出,对应我们上面说的输出4个标签。

这两个过程刚好可以对应的上。所以我们不需要把原图分成四个部分,分为用卷积去检测,而是把它们作为一张图片输入给卷积网络进行计算,其中的公有区域可以共享很多计算。

 

我们不用依靠连续的卷积操作来识别图片中的汽车,我们可以对整张图片进行卷积,一次得到所有的预测值,如果足够幸运,神经网络便可以识别出汽车的位置。

 

5 边界框预测( Bounding box prediction )

上一节的算法有一个缺点,就是边界框(bounding box)的位置可能不够准确,例如,可能你的框没有完美地框中汽车,而是框中了四分之三的样子。

其中一个能得到更精准的边界框的算法就是YOLO算法,YOLO的意思是you only look once。

怎么做的呢?假设我们的图像是100*100,我们在图像上放上3*3=9的网格(用3*3是为了介绍简单,实际实现会更精细,比如19*19)。

基本思路就是逐一在9个格子里使用目标定位。对于没有目标的格子,它的标签y就是pc为0,没啥好说的;

对于某个有目标的格子,按目标定位的方法贴上标签。需要注意的是,yolo会把目标分配到包含对象中点的那个格子里,所以如果车子的边缘跑到别的格子去了,我们会忽视那些边缘。

因为我们的标签有8个分量(参见前面说过的目标定位),所以最终的标签的shape是3*3*8。

我们要训练的卷积神经网络就是输入100*100*3的图像,输出3*3*8的标签。这样我们就可以得到精准的边界框了。

这个算法能够得到更准确的边界框而不用受限于滑动窗口的步长;其次这是一个卷积实现,我们并没有在9块区域跑9次算法,而是直接对整张图进行卷积的训练,因为在各个格子里的很多计算步骤是可以共享的。所以这个算法效率很高。

另外有个细节,关于bx, by, bh, bw,我们说格子左上角是(0, 0),右下角是(1, 1),那么这四个参数可以认为是在格子中占的比例大小,bx, by是(0,1)的,而bh, bw可能大于1,因为可能目标太大占了几个格子,指定边界框的方式有很多,这种约定是比较合理的。

 

6 交并比( Intersection over union)

交并比函数IoU是用来评判目标检测是否准确的,它做的就是计算预测边框和实际边框的交集和并集的比。

一般IoU大于等于0.5就说明检测正确,如果你希望严格点,可以定为0.6或0.7。

 

非极大值限制( Non-max suppression)

之前讲的yolo算法中,有个问题就是当一辆汽车占了很多个格子的时候,很多格子都会觉得它里面有辆车,所以算法可能会对同一对象做多次检测。

非最大值限制做的就是清理这些检测结果,使每个对象只被检测一次。具体怎么做,我们先假设目标只有一个,汽车,那么标签变成5个( pc, bx, by, bh, bw )

把图片分成19*19格子,对每一格子如果pc<=0.6,则丢弃,认为它不包含汽车。

对于剩下的格子,选择概率pc最高的框框,然后把跟这个框框的IoU很高(比如说>=0.5)的框框抑制;

然后再找概率最高的框框,接着把IoU(重叠)很高的框框抑制;

以此类推,最后把抑制的框框都去掉,这就是非最大值抑制。如果尝试同时检测三个目标的话,就对三个类独立地进行非最大值抑制。

 

8 Anchor Boxes

Anchor Boxes是处理一个格子出现多个目标的手段。

如下图所示,人和车重叠在了一起,这个时候可以预先定义不同形状的anchor box,这个例子中我们定义两个anchor box。

然后标签也变成原来的2倍,分别表示2个box:[ pc, bx, by, bh, bw, c1, c2, c3,  pc, bx, by, bh, bw, c1, c2, c3 ]

对于第一个box,行人的形状,用标签的前8个表示,这里所有的参数都和检测行人有关。

对于第二个box,汽车的形状,用标签的后8个表示,这里所有的参数都和检测汽车有关。

之前,训练的每一个目标,都分配到包含中点的格子里。

现在,训练的每一个目标,都分配到(包含中点的格子,和目标IoU最高的anchor box)里。

如果你有2个anchor但是格子出现了3个目标,这种情况算法并没有很好的处理办法,但执行了默认的手段就是把两个对象放在一个格子里且它们的anchor是一样的,希望你的数据集不会出现这种情况。

如何选择anchor呢,人们一般手工指定anchor的形状,你可以选择5-10个anchor box覆盖多种不同的形状,涵盖你想要检测的对象的各种形状。

后期YOLO论文有更好的做法,用k-menas将两类对象的形状进行聚类,用它来选择一组anchor box。

 

 

9 yolo算法( yolo algorithm )

先根据上面讲述的内容,给训练样本贴好相应的标签,然后训练,预测。

最后要做非最大值抑制,步骤如下。

(1) 如果anchor box有两个,那么对于每个格子都会得到有两个边界框;

(2) 抛弃概率低的框框;

(3) 假设我们要预测三个目标,那么对每一个类,单独用非最大值抑制去得到最后的预测框框。

 

10 候选区域( Region proposals )

候选区域用的比较少,但是这个概念在计算机视觉领域的影响力很大,是个很有趣的想法。

我们之前讲的滑动窗口,它可能会在显然没有任何对象的区域上运算,这很没意义。

针对这个,有人提出了R-CNN,带区域的卷积网络,这个算法尝试选出一些区域,在这些区域上运行卷积网络分类器是有意义的。

选出候选区域的方法是运行图像分割算法,找一些色块,在这些色块上做卷积得到特征,然后(SVM)分类。

R-CNN运行还是挺慢的,所以有一系列的研究工作去改进这个算法。

比如Fast R-CNN,用了卷积(实现的滑动窗口)来进行分类,提高了速度,但是它得到候选区的速度还是挺慢的。

所以又提出了Faster R-CNN,用卷积去来获得候选区域色块,结果比Fast快很多。

 

 

posted @ 2017-11-24 21:22  PilgrimHui  阅读(1580)  评论(0编辑  收藏  举报