这系列文章的内容目录如下:

  • 目标检测的任务

  • 深度学习在目标检测中的应用

    • RCNN
    • fast RCNN
    • faster RCNN
    • RFCN
    • yolo
    • yolo V2
    • SSD
  • tensorflow目标检测API的使用

第一篇里介绍RCNN及fast RCNN,在第二篇里介绍了faster RCNN,第三篇介绍了RFCN,现在是第四篇,介绍yolo和yoloV2。

yolo和yoloV2都是一步到位的检测框架,下一篇将介绍的SSD也是一步到位,这类框架相比于RCNN系列在检测速度上有了质的提高。

先说yolo,yolo是一步到位检测框架的开始,所以结构也显得有些简单,几乎是用神经网络在“蛮力”拟合。
yolo使用一个神经网络完成所有的事,不再像之前介绍RCNN系列先找ROI再看ROI里面是什么,没有这些步骤了,一张图片输入CNN,直接得到哪些区域有什么东西,所以yolo的过程就像下面这样简单:
深度学习在目标检测中的应用及其tensorflowAPI实践(四)
我们来看看是什么样的CNN实现了这样的功能,结构如下:
深度学习在目标检测中的应用及其tensorflowAPI实践(四)
上图中把一张图片固定到448x448x3的尺寸,图片变大相对的目标也会变大,这样对目标检测有好处的,因为当前所有的目标检测框架对小目标的检测效果都不好,我自己的经验是把图片放大确实可以把本来没识别出来的小目标给识别出来。
接着进行卷积操作,最后是两个全连接,把一张图片计算到了7x7x30这个尺寸(全连接后变换一下形状得到的,全连接的原始输出是一列向量),接下来就是yolo重点的地方了,可以把这7x7的feature map回退到原始图片上,就相当于在448x448的原始图片上划分了7x7的网格,就像下面这样:
深度学习在目标检测中的应用及其tensorflowAPI实践(四)
上图中的S=7,接下来对这网格上的每个格子我们预测两个bbox,可以想象成是faster RCNN中的anchors,只不过在faster RCNN里我们自己固定了9个bbox的大小,而在这里我们不固定,让网络自己输出两个bbox的坐标,除了输出坐标外还会给每个bbox一个可信度,待会说明这个可信度的计算方式,接着还有这个网格里是什么东西(VOC数据集是20个分类),所以在VOC数据集上,每个网格会有((4+1)x2+20)=30个输出,7x7的网格就会有7x7x((4+1)x2+20)=7x7x30个输出,这就是上面网络结构图里最后得到的那个尺寸。
说到这可能还是很迷糊的,怎么这网络不是和一般的卷积网络差不多么,怎么就能输出bbox和类别了,下面细说。
首先看下面的图,对于某个网格来说,它的30个输出基本是这样的:
深度学习在目标检测中的应用及其tensorflowAPI实践(四)
上图左边是一个网格预测出的两个bbox的向量,右边是损失函数,我们一一说明:

  • 我们先说右侧损失函数里第三行和第四行的CiCi^,这是我们上文提到过的可信度其计算方式如下:

    Ci=Pr(Object)IOUpredtruth

    其中第一项Pr(Object)表示这个方格里有物体的概率,在训练时,我们以物体中心落在的那个格子为有物体的格子,即Pr(Object)=1,如果训练图片上物体的中心没有落在这个格子上则认为这个格子的Pr(Object)=0,后面一项表示预测出的bbox和真实的bbox之间的IOU,两者相乘即为Ci可信度

  • 关于这个可信度,再多说一些,对于训练图片,这个Ci的打标,从计算公式上来看,一张图片中只有有物体的格子里这个Ci才会有值,其余的bbox的Ci由于Pr(Object)为0,所以对于7*7=49个方格里,只有少数的几个格子里bbox的Ci是大于0的,而在打标注的时候我们并不知道网络会预测出怎么样的bbox坐标,所以在tensorflow实现yolo时,label中的Ci项只有Pr(Object)的值,即0或者1,当模型输出了bbox的坐标后,如果这个格子的Pr(Object)为1,则说明这个格子在某个物体的中心,这时就计算模型输出的bbox坐标和真实的bbox坐标之间的IOU,这样就算出了这个预测bbox的可信度。所以可信度的label在训练前并不知道,只知道Pr(Object),在有预测输出后才可以算出可信度,而我们训练Ci的目的就是为了让模型输出的Ci和真实的Ci接近,这样就可以对所有输出的7*7*2=98个框进行筛选,选出是物体的概率较高的框。

  • 由于正负样本比例悬殊较大,很多框里都是没有目标的,所以在损失函数里计算Ci时给正负样本赋予了不同的权重,让正样本,即有目标的样本拥有更大的权重。

  • 再看上面公式里的x,y,w,h,这是bbox的四个坐标值,其中x,y用对应网格中心的offset归一化到0-1之间,w,h图像的width和height归一化到0-1之间,对于w,h,作者做了一个开根号的操作,这样做的目的是为了让相对较小的box预测的更准一些

  • 剩下的一项pi(c)是对20个类别的softmax损失

  • 注意损失函数的公式里有很多示性变量,做机器学习的对这个应该不陌生,有些预测值只有正样本参与了

yolo在预测的时候,对每个方格里的两个bbox取Ci较大的那个,然后对所有方格的bbox按照Ci选择Ci较大的作为最终预测结果。

yolo就是这样一个简单的结构,利用一个神经网络完成了目标检测的端到端训练和检测,重点是设计了一个很不错的损失函数。

yolo的速度很快,因为整个过程就是跑一个神经网络,但是有很多缺点,对小目标的检测精度不好,并且由于一个方格里只有两个bbox,所以对于靠的很近的群体目标检测精度也比较差。

针对yolo的一些缺点,作者又提出了yoloV2,我个人觉得yoloV2就是对yolo打了一些补丁,并且有一些补丁有点加入人工先验去拟合待预测的数据集的意思。

yoloV2的大体思路和yolo差不多,也是用一个CNN解决所有问题,我们先看看yoloV2用到了哪些技术:
深度学习在目标检测中的应用及其tensorflowAPI实践(四)
上图是原论文作者贴出来的,可以看出来yoloV2在准确度上比yolo有了很大的提高,到了78.6%.

  • BN:yoloV2使用了BN归一化层,关于这个BN这里不细说,这是google inceptionV2中提出的使得神经网络收敛更快更准的算法
  • 高分辨率:在训练yolo的时候,作者首先在imagenet上进行了预训练(按照imagenet的分类来训练),是基于256*256的图片做的预训练,然后在检测时把分辨率调到了448*448,在yoloV2中,作者直接在448*448的图片上进行了分类预训练,然后再训练检测
  • 带anchors的卷积:在yolo里最后用来预测结果的是全连接层,而在yoloV2里作者参考了faster RCNN中的anchors思想,也是做了一系列的卷积,最后得到一个feature map(原论文得到的feature map是13*13的),接着在这个feature map上的每个点做anchors,和faster RCNN中的做法一样
  • 维度聚类:在faster RCNN中anchors的尺寸都是固定的,而在yoloV2里,作者对训练集中的所有bbox尺寸进行了聚类,最后选择了几个聚类中心的坐标为anchors的尺寸,聚类时用的距离衡量标准是IOU。这个方法我第一眼看到的时候感觉很巧妙,这样可以帮助模型收敛的更快,但后来我觉得这个人为加入的先验有点太多了,感觉像是为了拟合某个数据集而做的
  • 预测目标:对x,y,w,h的预测做的修改,这部分可以参考原论文,个人觉得每篇目标检测的框架这部分都是类似的,只是细节有所不同
  • 不同尺度的feature map:在这里作者用了一个和SSD很类似的方法,原本用来预测的是卷积网络最后一层的输出,是一个13*13的feature map,在前面一层卷积网络的输出是26*26的feature map,这意味着对应到原图上时,这个26*26的feature map每个点对应的区域更小,这样对小目标的检测可能更好,所以在最终预测时把这个26*26的feature map也加入了,在上面做了一系列的anchors
  • 多分辨率检测:由于yoloV2全部是卷积层和池化层,所以不同大小的图片都是可以输入的,只不过最后得到的feature map不一样大,这样作者在训练网络时就用了不同大小的图片,最小为320,最大为608,以32为step,每训练10epoch就随机选择图片的大小,这样在预测时也可以对不同大小的图片进行预测,对小图片的预测速度很快

以上是yoloV2对yolo的主要改进,可以看出作者参考了faster RCNN的anchors,这是一个很好的方法,在SSD中也用到了。
yoloV2的输出和yolo类似,每个anchors都有x,y,w,h和C可信度,再加上20个类别的onehot。
此外,作者还提出了自己的网络结构,darknet,这部分细节不说,感兴趣的可以去看原论文。

在原论文里作者还介绍了yolo9000,是一种可以对9000类别的目标进行检测的技术,因为目标检测打标注的数据集很少,所以很难去做对9000类这么多的目标检测训练,作者结合imagenet的1000类提出了wordtree的方案。

下一篇说SSD,相比yolo&yoloV2,我个人更喜欢用SSD,因为我觉得SSD更科学一些,在VOC上的准确率也比yoloV2高,更重要的是有tensorflow官方的API支持,代码质量有保障。
关于SSD,请继续关注~