目标检测(Object Detection)的前世与此生(一)

目标检测(Object Detection)的前世与此生(一)

首先说点题外话,上一篇的实时人脸识别中我说要把mtcnnfacenet的论文和代码好好解释解释,并谈谈本身的理解,可是当我准备写的时候,发现仍是我太年轻了,我发现若是想要将其解释的通俗易懂,而且能在之后的项目中用的驾轻就熟的话,那么它的发展历程就不得不说说了,否则会以为好多东西都很突兀,本次就说说这object detection,那么各位老爷瞧好吧。html

简介

Object Detection与Target Recognition是两个不一样的概念,这个各位老爷应该都知道。Object Detection的目的是在目标图中将目标用一个框框框出来,而且识别出这个框中的是啥,并且最好的话是可以将图片的全部物体都框出来,这样作的目的是为了下一步的Target Recognition。因此了,咱们接下来要作的就是用一些好办法将这个框框找出来(其实就是找出来这个框的坐标位置了),而在这个过程当中技术和方法也是在不断的进步拉,从RCNN->SppNET->Fast-RCNN->Faster-RCNN,固然如今还有更棒的,可是我如今不写,准备留在下一篇再写(我也还没学...),可是若是不搞定这个技术演进,后面技术中的各类新东西会让人痛不欲生的算法

神经网络是如何工做的

答案是:我也不知道 markdown

这个问题太大,可是对于不只仅是追求运用的人来讲,这实际上是一个挺让人困惑的问题(至少我是如此) 说一些各位爷都知道的,神经网络经过一系列的节点将数据中最直接的特征==>抽象的特征,使得抽象后的数据逼近目标,从而才有的可比性(衡量的尺度是loss) 网络

举个例子,卷积网络奏效的过程(好像容易理解一点),经过不一样的卷积核,提取图像不一样的特征(抽象),再通过组合(进一步抽象),最终达到获得一系列的高纬度的抽象特征,当输入的图片符合的时候,才可以从其中抽取出相似的高纬度特征,从而达到了目的(网上一大堆的图,也不知道贴啥好,下面是随便找的图)机器学习

cnn.jpg

能够看出来,一开始提取出来的是一些不一样方向的线条特征,接下来继续抽象组合,最后达到目标要求,这就是一个朝着目标不断抽象出来更高级特征的过程,这个看着很好理解,是由于符合人类的认知,而之前的研究人员也是这样作的,他们各类办法寻找应该抽取的特征,从而能达到更好的效果,可是效率低小,不少时候效果也很差。 别急,让我再举一个例子,若是看过吴恩达老师的机器学习课程,应该知道其中有一节课是识别手写数字,当时用的不是卷积,而是直接将28*28的手写数字图片展成一维,每个像素都当成输入的特征,最后也达到了预期效果。这里不由该思考了,神经网络起初看到的东西是一堆“在人类看来”毫无关系的像素值,处理的手段也是让人看不懂了,因此又回到了最开始的问题了,咱们并不了解神经网络的行为,咱们知道的只是其在进行特征提取,提取不一样的特征,提取更高维度的特征,而且这种特征早已超出了人类的认知,因此它才能够高效的工做,完成一些人类没法完成的工做,好比刚才说的早期人工设定卷积核,寻找更好的目标特征,这些目前都已经被深度神经网络取代了,由于网络能够寻找到更高层次,更抽象(抽象到人类没法理解)的特征函数

说到这里,有时候又会感慨,这是否有些太玄学了,好像机器跳出了人类由于多年的天然进化和社会阅历的固有认知,寻找到了最直接的 现象与结果之间的联系,就好像若是占卜是正确的话,那么是否是其方法是以一种人类不理解的方式寻找到了因雨果的联系,固然我说这些不是为了玄学,而是为了让各位爷认识到这个问题,不少事情因束缚于人类的躯壳而没法去理解,如四维空间或者更高维度的空间是不可想象通常,祖母悖论等各类问题,都是认识论与真理论的不统一而致使的,生而为人是渴望追求真理的,但不少咱们作不到,因此这也是我喜欢深度神经网络的缘由,它有机会让我领略到更多的东西,好,废话讲完学习

RCNN->SppNET->Fast-RCNN->Faster-RCNN

在Object Recognition以前进行Object Detection的目的是为了减小没必要要因素的干扰(好比从背景很复杂的图片识别出一个小动物,那样准确率会大大的下降),此外还能同时获得目标在图片中的位置(还包括宽度,高度)。测试

当决定要进行Object Detection的时候,你们想法都是差很少的,窗口扫描嘛,不一样大小的窗口从左到右,从上到下的,不用想,这样是超级浪费时间的,绝大部分的扫描都是没有用的,由于框住的根木不是目标,因此继续想,要是我能直接框住图片中的目标,而不框那些无关的背景,并且也不要框的特别准确,就好啦。 当年绝对有不少人有这样的想法,你们都知道目前的窗口扫描办法不少扫描是彻底没有意义的,可是要怎么作哦,这种感受有点像作题目的时候,有了一点思路,可是却想不到好办法,解决办法是什么呢?在RCNN里就用到了优化

RCNN(regions with CNN)

SS(selective search)

在RCNN中使用了一个叫作SS(selective search 选择性搜索)的方法,这个算法也算是为Object Recognition打开了一个新的大门(同时也要吐槽在此算法上太多的博文都是在水,啥也说,贴个论文截图就完事,固然也多是我太水,理解不了其中的深邃思想,但我就是要说)spa

我来简单说说这个算法,在遇到上一段所说的问题,该论文做者发现,图片中的目标(好比人,汽车,小猫...)与背景是有区别的,好比颜色区别,纹理区别、大小区别等

ss.png

如上图所示(截自原论文),图片中的大量天空背景是无效的,而咱们想要检测的奶牛在颜色纹理方面很类似,能够与背景区分开来

论文的思想是

  • 首先经过利用颜色的类似性(毕竟若是颜色很类似,那么极有多是一个总体),造成一些小的区域(上图左边最下面一层),具体算法是将整张图当作一个无向图,节点之间的距离就是像素的距离(在这里使用RGB计算距离并很差,最好转换如下色彩空间,好比HSV等),而后设定一个阈值,从其中寻找最小生成树,造成最初的感兴趣区域(region of interest ROI)(若是没有学过离散,能够看如下这篇文章基于图的图像分割)
  • 而后对ROl进行再次的合并(如上图),可是合并要遵循一些规则--相邻区域的类似度

    • 颜色类似度(color similarity):比较两个区域的颜色直方图
    • 纹理类似度(texture similarity):比较两个区域的梯度直方图(这个会有点难理解,其实纹理的形状表如今其轮廓上,全部用梯度直方图能够很好的表示出纹理之间的差别)
    • 尺寸类似度(size similarity):防止大的区域和小的区域合并,要遵循先小的合并(由于图片中存在包含关系,好比轮子和汽车都很容易被框选出来,而轮子是属于汽车的,若是直接大的和小的合并,那么不少细节会被丢失掉)
    • 交叠类似度(shape compatibility measure):这个不太好描述(见下图),当两个区域合并后,合并造成的新图形占其边框矩形面积的多少 表明着这样合并的合理性,好比图中的右侧,合并后它们只占了框定他们矩形的很小的一部分,当咱们把这样的一个区域投入cnn中识别的时候,效果依然不好,仍是存在大量的背景信息,因此这样是不合理的

jd.png

  • 类似度是上一步骤的计算获得的各类类似度的加权和,而后利用这个类似度做为合并的标准,而后重复这个步骤,直到最终合并为一个区域,而在这个合并过程当中,获得的大大小小的区域的边界框,都将做为咱们的侯选框

ss1.png

更多具体的算法细节能够看选择性搜索这篇文章(我也用了博主的一张图...)

R-CNN

(详情参看https://www.cnblogs.com/skyfs...,我下面的内容将会有不少都是这篇文章的,会穿插说一些本身的理解)

  • 使用ss选出2000个侯选框,将候选框拉伸为227*227统一大小(拉伸方式为padding=16,直接拉伸,通过实验这样效果最好),再选用一个分类CNN(好比AlexNet或者其余),将分类数从1000改成20,并做fine-tuning

    11.jpg
    22.png

    其实我以为上面的这个图画得有点不太直观,AlexNet的网络结构为

    5个卷积层(conv1+conv2+conv3+conv4+conv5) + 3全链接(fc6+fc7+fc8)

    (因此上面这张图中最后一层就是softmax loss,而不是什么全链接层)

    这里要说一下fine-tuning,你们都知道通常的图片分类训练,人工在进行数据标注时候较容易,因此训练数据不少,而目标检测的gt(ground truth)框标注起来很费事,因此训练数据不多,这种大型的网络训练是很浪费时间的,由于使用的CNN,其中大部分作的工做都是将图像中的特征抽象出来,因此其中的大部分参数是能够直接拿来使用的(至少是很接近咱们预期的目标的),在这里使用的的AlexNet,其已经实现了1000对象的分类,而RCNN中要实现检测的20个类别也在其中,这时候确定有人会想,既然这样,还不如不要作fine-tuning了,又不是不能识别(不断的质疑、思考将会促使咱们进步),RCNN做者RBG大神对此进行了研究测试,发现效果并很差,具体的缘由我先卖个官子。

    这时候停下来思考一下整个目标检测步骤该是怎么样的

    1. ss获得侯选框
    2. 检测侯选框中的是不是目标的得分状况
    3. 按照得分状况对侯选框进行排序,而后按照某种规则筛除一些框
    4. 对最后剩下的框作一个边框回归(将框位置和大小微调一下))

乍看好像挺合理的,直接用AlexNet计算预选框为目标的几率(softmax输出为几率)就行了啊,而后按照上面步骤进行下去,那么这样的话,最终的准确率会让你大大的失望了,研究人员的一直在作的事情就是想不断的提升正确率以致于想出了各类巧妙的办法,而咱们这里的作法不以为太粗鲁了吗?为何呢?这和咱们的数据有很大的关系,AlexNet训练用的数据或者说不少其余的图片分类网络使用的训练图片每每是图片中间是事物的主体,并且几乎没什么噪音,而咱们这里使用ss获得的2000个预选框状况真的是惨不忍睹,绝大部分都是背景不说,就算框中有主体存在,那也每每是残缺不全的(只框到了部分),因此这样的网络是不能直接用的,咱们要用本身的数据fine-tuning一下(训练一下CNN)

  • fine-tuning

    首先咱们标注数据,用于训练CNN,使用SS得到的2000个预选框,IoU(不懂的本身查下吧,10s就懂)>0.5的标记为正样本,反之为副样本,以前说过去掉最后一层(去掉fc8,其原来为1000),改成20,而后随机初始化这一层的参数,其余层参数不变,采用SGD,学习速率设置为0.001(由于原AlexNet使用的是0.01,这样设置的好处是不会为原来网络的参数形成大的影响,只是在微调),batch size为128(32个正样本,96个副样本),你可能还会想,使用这样的数据进行训练,最后获得的结果会好吗

    其实这样有点像是被牵着鼻子走的感受,可是不要着急,学习的过程原本就是会有好多突然想不明白的地方,毕竟是在用短短几天的时间去感悟别人辣么久的研究成果
  • 训练SVM

    在作完上一步的fine-tuning后,咱们并非要使用其来预测预选框中内容为目标的几率,而是要使用fc7层(20分类的softmax前一层)的特征来训练SVM(由于是20分类,因此训练20个SVM),负样本为IoU<0.3(包含彻底没框住目标的,好比背景,以及框住了目标一点点部分的,这样的预选框并无意义,因此将其认定为负样本),正样本为将目标彻底框住的预选框

    那么先使用CNN+softmax进行fine-tuning,而后再使用SVM的意义在哪里呢?为何不直接单独使用softmax进行预测,或者单独使用SVM进行训练预测呢?为何要使用不一样的定义正负样本的策略呢?其实这一切的缘由其实都是因为咱们的训练数据致使的。 首先咱们知道CNN+softmax训练是十分容易过拟合的,由于softmax loss计算的是几率,这样的损失函数对于精度的追求是无止境的,只要继续训练,很容易就会产生过拟合的状况,每每的解决办法是使用大量的数据,而目标检测缺乏的就是大量的数据。SVM使用的是打分策略,一旦分数超过那个delta,就不会再继续调整了,因此其使用小样本训练效果也会很好。因此咱们天然而然的就想到了直接使用SVM(不进行fine-tuning,直接抽取fc7的特征进行训练),可是效果惨不忍睹,缘由是什么我上面也解释过,由于不合适,事实上RBG大神在训练的时候,试过直接使用conv五、fc六、fc7进行SVM训练,可是准确度实在是过低(精度上不去),甚至其中结果最好的是使用conv5,因此他想到了仍是必需要进行fine-tuning,因而便使用CNN+softmax测试了一下,并且为了防止过拟合的问题,特地的将loU设置为0.5,达到了没有‘’过拟合‘’,而后使用fine-tuning后的conv5,fc6,fc7进行了SVM测试,发现fc7的准确率爆棚。

    那么为何SVM的正负样本阈值要那样设置呢? 关于负样本的阈值设定,做者测试了IoU阈值各类方案数值0,0.1,0.2,0.3,0.4,0.5。最后经过训练发现,若是选择IoU阈值为0.3效果最好(选择为0精度降低了4个百分点,选择0.5精度降低了5个百分点),即当重叠度小于0.3的时候,咱们就把它标注为负样本。而正样本确定是要设定为将目标彻底框住的预选框了,这样训练后的结果是,可以很是逼近目标的预选框将会获得高分。

  • NMS(Non-Maximum Suppression 非极大值抑制)

    当SVM训练完毕后,咱们将一张图片的2000个预选框输入,最终获得2000*20的矩阵(2000表明预选框的数量,20表明每一个预选框在每一个类别的得分(置信度)),而后使用NMS筛除绝大部分的多余的预选框,具体作法以下

    1. 首先从每一个预选框中找出最高得分类,肯定预选框的预测结果
    2. 一共20个类别,从第一个类别开始,将全部属于这个类别的预选框放到一个集合Bi(i表明第几个类别)中,按照分数进行排序,从高到低,使用最高分如下的全部预选框和最高分预选框计算IoU,若是IoU大于设定的阈值,则将这些符合的条件的预选框删除(目的是对于同一个目标只保留一个得分最高的预选框),而后将最高分预选框放入目标集合Di中,剩下的预选框继续重复这个过程,直到这个集合为空。

      举栗:当前排序为 A B C D E F G,A得分最高,使用 B C D E F G和A计算IoU,结果B D E都符合,则从集合中去掉B D E,此外将A放入另外一个目标集合中,这时候当前集合只剩下C F G,F和C的IoU值符合,去掉F,C加入目标集合,此时集合中只剩下G,将G放入目标集合,当前集合为空,而后进行下一个类别的判断
  • Bounding box regression(边框回归)

    (边框回归终于来啦,此真乃神来之笔,之前历来没想过回归还能这么用,真的是长见识了,也但愿各位能感觉到其精髓之处,还有就是边框回归在后面还会一直使用,必定要搞懂了)

    网上关于边框回归的介绍少之又少,我也不知道个人解释会不会让大伙满意,先看着吧,有什么不理解的留言就行了

    在上一步NMS后,咱们获得了一些预选框(以下图所示,图是盗来的...)

bbox.png

咱们获得的筛选后的预选框多数状况是如图中红框所示,虽然框住了主体部分,可是和gt依然有些出入,咱们须要使用边框回归将其微调一下,具体作法以下所示

bbox1.png

* p为筛选后的预选框
* G^为咱们进行边框回归后的目标
* G为gt

边框回归想作的事情很简单也很容易想到,描述一个预选框的信息有 (x,y,w,h),x,y表明其中心点的坐标,w表明宽,h表明高,想要实现预选框与gt之间的变换,咱们只要可以将(x,y)平移到gt的中心,而后对w和h进行伸缩变换就行了(即进行一个平移变换和一个伸缩变换)

先看论文给出的公式(markdown不知道怎么打这公式,我就截图了截图来源,侵删)

bbox2.png

从上面公式中能够看出,在进行回归训练的时候,咱们输入的是预选框的pool5层的特征(AlexNet的第五个卷积层后跟着一个max pooling,就是这里的咱们预选框的输入,pool5的特征信息中包含了预选框抽象后的一些特征),gt的(x,y,w,h)做为‘’标签‘’来进行监督训练,下面我来讲一下本身对这些的理解

首先我第一次看到这里的时候以为很诧异,一个回归是如何作到 仅仅输入一个预选框的信息 就能获得校订信息的?要知道咱们在测试的时候,仅仅只输入预选框的数据,整个回归是对全图绝不知情的,感受这样的过程很难以想象,因而对其特别感兴趣

每当我遇到本身没法理解的东西时候,都会提醒本身是否是陷入思惟误区了,并且这仅仅是一个线性回归,这不像是深度神经网络这样的黑盒子,让人彻底摸不到头脑。试想一下,人类在见到半个小猫的身体的时候,是大概可以猜想出来小猫头的位置的,这里应该也是相似的,咱们经过对预选框pool5层数据进行训练,让其对一个目标的‘’总体‘’敏感,从而当咱们输入的预选框没有彻底框中目标的时候,它知道这个预选框与真是的目标相差了多少,从而给咱们以反馈

咱们但愿学习到平移量和伸缩量,有的人会想,既然已经作的是回归了,为何不直接返回具体的平移量和伸缩量,使得Px ,Py直接加上,Pw Ph直接乘上,这固然是不行的,想象一下归一化,由于输入的图片大小是不同的,因此平移的值有大有小,当咱们不想让网络学习到大小差别的时候,通常作法都是归一化(即将有量纲转为无量纲),因此咱们这里除以Pw,Ph

而至于为何在进行伸缩计算处理的时候要加上log形式,我认为是由于在Loss函数中,tx,ty是有正负之分的,因此也要将其处理为相同的形式,将原来的(0,+无穷)映射到(-无穷,正无穷)(固然不会无穷这个夸张了...)

上面的优化函数你们应该都看得懂,最后加入了L2正则

2018-08-24 10-09-31屏幕截图.png
2018-08-24 10-09-44屏幕截图.png

最后训练完毕后,按照上面式子便可获得结果(d(P)表明pool5特征通过变换后)

哇,RCNN终于说完啦,不得不说,RCNN想法巧妙,做者真的奇思妙想,可是确实是太复杂了,彻底没有端到端的那种爽感,像是在东拼西凑,不过有了这些基础打底,后面的看起来会很轻松的,若是以为这里有哪些不懂的或者一时间难以接受的,不要着急,慢慢理解嘛或者留言,毕竟我光写就写了很久的了,拜了个拜~


Fast R-CNN

在谈Fast RCNN以前,先介绍在RCNN后的新技术

SPP Net

SPP Net由如下两部分组成

SPP (Spatial Pyramid Pooling 空间金字塔池化)

在RCNN中,预选框大小不一,而图片输入CNN后通过卷积,还须要进行全链接,很显然输入不一样大小的图片将会致使全链接层没法工做,因此全部的预选框在输入CNN以前都通过了crop(剪裁)或者warp(拉伸扭曲),以固定的大小输入,虽然RCNN做者尝试了使用不一样的变形操做从而使得精度较高,但无论怎样都不能否认的是图片确实变形了,在必定程度上使得图片失真,从而影响到了最终的效果,而SPP的思想即是不管你输入的图片大小是多少,使用不一样尺度的池化层将其变为固定大小的特征(详情见下图)

ssp.png

假设我输入的图片经层层卷积处理后,到达SSP层,当前大小为40*60*256

  • 金字塔第一池化层,将输入特征切分为140*60*256特征,对其池化,获得1个256维度特征
  • 金字塔第二池化层,将输入特征切分为420*30*256特征,对其池化,获得4个256维度特征
  • 金字塔第三池化层,将输入特征切分为1610*15*256特征,对其池化,获得16个256维度特征

将上面的到的256+4*256+16*256特征叠加起来,做为全链接层的输入,就是这么简单啦,可是效果是出奇的好,这个算法也是何凯明大神提出的

ROI映射到feature map

ROI(region of interest)即咱们以前提到的预选框,这个想法的具体内容是,经过SS选择出来的2000个预选框输入CNN计算特征速度太慢,为何不把整张图直接输入CNN,获得一整张图的特征,而后根据各个预选框的位置从那个一整张图的特征中crop对应的特征,再输入SPP进行运算呢,后来通过这般改进后,准确度没有受影响,而速度提升了好多好多(示意图在下面)

ROI.png

在RCNN的基础上加上以上两项技术,即组成了SPP Net,可是即使这样,依然是存在些许问题的,而Fast RCNN即解决了不少问题

ok,下面说一下Fast RCNN的改进之处


RCNN.png

RCNNloss.png

上图即是Fast RCNN的网络结构了,其相对于RCNN的更改之处在于,将原来的pool5层替换为Rol池化层,在原来的全链接层后又加上了一个bbox回归

Rol池化层是简化版的SPP,它只进行一次池化,即将输入的预选框的映射特征分割为r*r块区域,再进行池化

分类不在是之前的先softmax分类进行fine tuning,而后svm再使用分类,而后再bbox回归,如今而是分类bbox回归同时进行,即完成了端到端

若是是一直看下来的同窗,确定会有疑惑,大概的疑惑应该是如下几点

  • RCNN中说若是不fine tuning准确度会大大降低,这里这样作效果会好吗
  • RCNN中说由于数据少,直接使用softmax分类会致使过拟合,那为何还要用softmax呢,svm为何不用了呢?
  • 不进行fine-tuning而直接进行bbox回归,准确率会高吗?

上面应该是一些直观的问题,我说一下本身的理解,具体的分析推荐你们看一篇博文,里面说的已经很详细了

先说说做者为何再也不使用原来的RCNN和SPP那种结合模式,其一,分步的训练很繁琐,一个环节出问题,步步出问题,前面步骤一旦肯定就再也不改动了,很死板。 其二,不管是训练仍是测试的时候,由于要使用到pool5和fc7的特征,须要占用磁盘存储空间,致使速度变慢,其三,由于训练是分步骤的,使得后面svm的训练和bbox回归的反馈没法传递回CNN,也就没法进行训练调整,阻碍了准确率的进一步的提高,其四,spp由于使用的是金字塔池化,致使反向传播的时候效率低下,或者说很难反向传播
说到这里,大概应该能有一点感受,Fast RCNN的这种采用multi-task loss将会相辅相成的训练网络,并且训练的数据也要按照要求处理,具体的细节请看下面博文,遇到不理解的地方,能够留言

Fast R-CNN学习笔记


Faster RCNN

哇,终于写到Faster ECNN了,原本觉得学习目标检测的演进会是一件很快的事情,结果拖了那么久了...想玩彻底理解真的是一件很费时的事情啊

在这篇中,我还写写如何在caffe下训练Faster RCNN以及对代码作一些注释说明,还会再作一个基于Faster RCNN的小项目吧,let's begin

(aaaaaaaaaa,今天写的一天的东西丢掉了。。。。。。。。好难受啊,我之后写东西的时候不再走神了,我决定直接代码开始了,今晚要是让我再写一遍,我会崩溃了,等那天心情好了再从新写好了,说不定那时候会有更深入的认识呢)