文章目录

YOLO系列:

论文题目:YOLO9000:Better, Faster, Stronger

论文下载地址:​​https://arxiv.org/pdf/1612.08242.pdf​

YOLO 9000就是YOLOV2,这个9000的含义是,YOLOV2模型能检测9000个种类。

1.YOLO-V1回顾

【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_人工智能

先将输入图片分成 S * S个网格,每一个网格叫做 grid cell。

训练阶段:

真实框的中心点落在那个grid cell里,就由那个grid cell所生成的B个bbox中与真实框IOU最大的那个框去负责拟合真实框。

每个grid cell还要预测20个类别(VOC数据集)的条件类别概率,然后整合+后处理(NMS等),得到最后结果。

预测阶段

直接将图片放到模型里(某种CNN),模型输出7 * 7 * 30维的张量,然后进行后处理(NMS等),最后可视化结果。

7 * 7 * 30的含义:
一开始画的 7 * 7 的 网格。每个网格有两个bbox,每个bbox里有 中心坐标x和y,还有框的w和h,再加一个置信度,所以一个bbox就有5个信息,每个grid cell有两个bbox就是10个信息,再加上20种类别,就是30个信息。
7 * 7 * 30公式化为:
公式:S * S * (5 * B + C)
其中 S是一开始网格的参数 比如yolov1中的7 *7 。
B是每个grid cell画多少个bbox。
C是数据集的类别有多少个。

在YOLO-V1中存在的缺点和局限:

  • 对于密集物体和小物体的检测能力较差。
  • 定位精度较差。
  • 对大小框一视同仁。
  • 虽然快,但准确度不如当时的最好模型。

2.Abstract(摘要)

作者在摘要里说明了本篇论文分为两部分,
第一部分就是对yolov1的改进,最终效果是,可以很快但精度略低,可以很精准但速度略慢。
第二部分是对如何检测9000个物体的说明,用了一个联合训练的方法,使得yolov2可以检测出来原本没有标签的物体。
训练是在coco目标检测数据集和imagenet分类数据集,验证在imagenet目标检测数据集,这里有不同的三个数据集。

作者也放了一些检测的效果图:

【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_卷积_02


我还去百度翻译了一下,左边识别出来的是german sheph erd(德国牧羊犬),

右边这个是siberian husky(西伯利亚雪橇犬)。这些物种在原本的训练集上是不存在的,只因用了联合训练的机制,让他识别出来了。而且识别的精度物种非常细化,好厉害啊。

不过在论文中展示的也是有错的,看下面这张图:

【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_目标检测_03

左边 rodent (啮齿动物),右边vertebrate(脊椎动物),右边是个螃蟹呀, 我去百度了一下,螃蟹是无脊椎动物,所以这里出错了还放在了论文中,不过这个也是比较难识别的,人都不一定知道,我还都是百度出来的哈哈。
不过按照这个作者的习惯,感觉9000种物体识别应该只是个发论文的噱头,毕竟在摘要里也提到了map只有20%不到。

3.Introduction(引言)

作者第一段提出了期望,相当于他的期望吧,一个通用的目标检测模型应该做到,速度快,准确度高,检测物体范围广,就是可以检测各个领域各种物体,而不是单一的局限比如人脸,猫。

作者在这一段提出了前人的不足,就是深度学习发展迅猛,精度和速度都开始稳步提升,但是对于可检测的物体还是比较少的。

引言第三段作者提出了他为什么要使用联合训练,就是摘要种所说的联合coco目标检测数据集和imagenet分类数据集,是因为目标检测当时的数据集比较小,相对于图像分类来讲。图像分类有几千万张,几万个类。而目标检测只有十万百万张,几千类。作者想自己标注一个新的大量的目标检测数据集,不过成本太大了,所以只能采用联合数据集训练方法。

4.Better(更准)

开头直接指出yolov1的缺点:

  • 对小目标,密集目标检测能力比较差;
  • 定位能力比较差;
  • 将所有目标全部检测出(recall)的能力较差;

作者为了对 定位能力和检测出全部目标能力进行改进,提出了很多措施,下面来看看都有哪些。

(1)Batch Normalization.(BN,批归一)

BN我在之前读论文的时候详细的说过,这里就不再赘述了,可以看一下我整理的BN那一篇论文,​​【精读AI论文-BN】​​ 这是一个普遍的常用技巧。BN是对每一个神经元的输出进行标准化,而不是对某一层输出整体标准化。

在yolov2的所有卷积层中都加入了BN(卷积-BN-激活)。加入后有2%的mAP提升。

(2)High Resolution Classifier.(高分辨率的分类器)

对于目标检测而言,图片分辨率高的话会让定位和识别分类更加精准,所以在yolo v1中,作者预训练时用的是imagenet分类数据集是224 * 224的,后面微调的时候将224 * 224 图片变成448 * 448的尺寸(目标检测)输入网络,这样改变尺寸,网络就要多重新学习一部分,会带来性能损失。

这块容易混,再简单说一下,v1中预训练使用的是分类数据集,大小是224 * 224 ,然后迁移学习,微调时使用yolo模型做目标检测的时候才将输入变成448 * 448。

作者在V2中改进,直接在预训练中输入的就是448 * 448的尺寸,微调的时候也是448 * 448。

这一个弥补措施提高了 4%的mAP。

说实话我觉得这是作者故意留的一手,这是非常容易想到的点,要不就是作者着急发论文,要不就是作者想第二年再继续发论文留的(手动狗头)。

(3)Convolutional With Anchor Boxes.(带有锚的卷积)

这个anchor机制我最早是在Faster R-CNN里看到的,在刚看yolov1的时候我就在想,grid cell生成的是不是 anchor,读到后面发现不是,在v1里生成的是 bounding boxes。

在yolov2中,一张图片分割成13 * 13 的网格,每个grid cell生成5个长度比例都定好的 anchor。也是通过IOU计算,选出来一个anchor产生的预测框去预测物体。

也就是每一个grid cell生成5个anchor,这5个anchor分别对应5个预测框,这些预测框要计算对应anchor的偏移量和置信度。

刚开始的anchor尺寸比例通过数据集分析聚类得到。

v1版本中每个grid cell 携带的是30个信息(whxy+置信度+分类数),v2版本中每个grid cell携带的是 25 * 5 =125个信息,5就是5个anchor,25是 xywh+置信度+分类数。所以v1输出7 * 7 * 30 。v2输出 13 * 13 * 125(13 * 13 * 5 * 25)。

为了让模型更加稳定,并且v1中bbox存在尺度无限制问题,v2中做出了一些改进,让预测框的中心点约束在该grid cell内,而对于anthor则没有约束。

并且去掉了v1中的全连接层。
去掉池化层,让输出的分辨率更高,并且将输入分辨率变成416*416,目的是想让最后输出的feature map是奇数大小。这里的奇数偶数是指最后输出的大小(输入除以32)。

为啥要奇数?如果是偶数的话,中心点就落在了四个格子的交汇处,奇数就刚好落在一个格子的中心。也就是希望让一个grid cell去预测物体,而不是四个。

看下面这个图理解: 左奇数,右偶数。

【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_深度学习_04

这一块原文中有个 ​​conditional probability​​条件概率,在v1中也出现了,和v1中的意思也是一样的,就是在有物体且是某一种分类的概率。并不是单指某一分类的概率。 所以叫条件概率,既满足有物体这一条件下的概率。

v1中是 7 * 7 * 2 = 98个框,v2中是13 * 13 * 5 = 845个框。

不用anchor:69.5%mAP,recall 81%。
用anchor:69.2mAP,recall 88%。

精度下降0.3%,不过recall上升了 7%,这里其实也比较好理解,v1里就不到一百个框,v2里变成不到一千个框了,多了这么多框recall肯定增加了,不过增加了这么多框,必然带来了更多无用的框,precision下降一点点也是可以理解的。

再明确一下这俩的区别:
recall:真正目标被检测出来的比例。
precision:预测框中包含目标的比例。

简言之,recall表示得找全,precision表示得找准。

(4)Dimension Clusters.(维度聚类)

这一块主要解释如何得到anchor。
首先批评了一下Faster R-CNN。Faster R-CNN使用的RPN里出现了anchor,但他的anchor是手工指定了长宽比和尺寸,相当于一个超参数,不过这违背了yolo对于目标检测模型的初衷,因为如果指定了anchor的大小就没办法适应各种各样的物体了。

v2中不再手工指定anchor的长宽比,而是使用k均值聚类方法。

关于k均值聚类我之前也有整理过笔记,可以看一下----​​机器学习算法----聚类​​ 在计算聚类距离的时候没有用传统的欧氏距离,用的IOU。

作者给出公式:距离度量指标:

【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_深度学习_05


box:其他框, centroid:聚类中心框

作者通过一系列实验表明,聚类个数k=5是最优选择。也就是一个grid cell生成5个anchor。
当然可以让k变得很大,比如20,30。因为k越大就生成越多的anchor,越多的框自然准确率就能上去了,但同时也成倍的增加了模型的复杂度,R-CNN不就是因为提取2K个候选框拉跨的嘛,所以作者实验出来k=5是最平衡的点。

(5)Direct location prediction. (直接预测位置)

在前面有说过v1中bbox框无限制导致一系列的问题,虽然加入了anchor,不过仍无法控制偏移量,所以要进一步限制偏移量。
这也是作者在一段中说的加入anchor带来的模型不稳定问题,就是偏移量无限制的问题。

在Faster RCNN中:
预测框中心坐标= 输出的偏移量*anchor宽高+anchor中心坐标

yolov2改进方法:

【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_目标检测_06


也就是给他加了个sigmoid函数限制到了0-1之间。

其中【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_数据集_07是grid cell左上角坐标(归一化的),【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_目标检测_08(归一化的)是anchor的高宽,【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_目标检测_09就是预测框的xy坐标和框的高宽。

输出的是 【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_深度学习_10

这一操作提升了5%的mAP。

(6)Fine-Grained Features.(细粒度特征)

在网上找了张图来看一下操作过程:

【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_目标检测_11


一个feature map,也就是在最后的池化之前,分成两路,一路是做拆分,分成四块,四块拼成一个长条,另一个是做正常的池化卷积操作,最后两个长条叠加输出。

这里的叠加不是ResNet里的add,而是拼接,是DenseNet里的concat。

这里优点残差的思想,这样可以整合不同尺度的特征。有利于小物体的目标检测。

这一操作提升了1%的mAP。

(7)Multi-Scale Training.(多尺度训练)

一个问题:低分辨率图片,识别快但精度低,高分辨率图片,识别慢但精度高。

为了让模型更加鲁棒,能检测更多的物体,所以不再固定输入尺寸。

每10个batch就换一个尺度(32倍下采样)。

作者在训练期间输入不同尺度,让模型可以兼容各种尺度的图片,让精度和速度达到一个最优平衡。

这里之所以能接受不同尺度的输入,就还是之前的那个问题,卷积层对尺寸没要求,都是直接滑动窗口式的感受野,但是全连接层是有要求的。所以在全连接层之前使用了全局平均池化操作。

5.Faster(更快)

上一大章节讲如何变得更精确,这一章节就是怎么变的块,

这一段开头先批评一波VGG,害谁也要批一下VGG,说VGG慢的不行,所以yolov1用的GoogleNet,也就是inceptionv1。速度很快,但是对比VGG精度稍微有所下降。

在yolov2中改进了这个主干网络变成了darknet-19。
这里顺带说一下,darknet是一个框架,就类似于pytorch,tensorflow。darknet-19是个基于这个框架的模型,他和VGG googlenet不同,darknet-19是专门为了服务于yolov2而产生的。

darknet-19网络结构:
Darknet-19 总共有 19 层 conv 层, 5 个 maxpooling 层。Darknet-19 吸收了 VGG16, NIN 等网络的优点,网络结构小巧,但是性能强悍。

darknet-19具体结构:

注意这是分类模型,不是目标检测模型。

【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_卷积_12


可以看到darknet-19里使用了3 * 3 *,1 * 1 ,全局平均池化GAP这样的操作。

对于目标检测模型,去掉最后一个卷积层,换成了3个 3 * 3 的卷积层, 然后再接1 * 1 卷积。

Training for classification.(训练分类模型)

这一小节主要说了一下训练细节,超参数什么的。

对于图像分类网络:

  • 数据集 imagenet 1000;
  • 160 epoch;
  • SGD优化器;
  • 初始学习率0.1;
  • 4次多项式学习率衰减;
  • 权重衰减(L2正则化)0.0005;
  • 动量0.9;
  • 数据增强:随机裁剪,旋转,色调(H),饱和度(S),明暗度(V)等的变化;
  • 224 * 224上训练,然后放到448 * 448上微调;
  • 微调时,10epoch,初始lr0.001;

对于检测网络基本也是这些,零散的那些变化稍看一眼就行。

6.Stronger (更强)

以上的两大章节就是这篇论文的第一个部分,基本都是对v1的改进。

这一章节更强的意思就是他检测更多的分类。也就是开头说到联合训练识别9000个分类。

联合coco目标检测数据集和imagenet分类数据集。
输入的若为目标检测标签的,则在模型中反向传播目标检测的损失函数。
输入的若为分类标签的,则反向传播分类的损失函数

一个问题:

coco的数据集标签比较大,这里不是图片大小的大,是指分类的比较粗,比如狗,猫,而imagenet分类则比较细化,比如二哈狗,金毛狗。

这时候如果用softmax进行最后的分类,则会产生问题,因为softmax输出最概率的那个分类,赢家通吃,各种分类之间彼此互斥,若狗,二哈狗,金毛狗在一起的话就会出问题。

所以要联合训练,必须让标签有一定程度上的一致性。

原始正常的数据集中数据结构是WordNet(有向图)。作者改造成了WordTree(树)。

作者用了一堆文字说明他是如何改变,直接看网上找的这张图就懂了。

【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_深度学习_13

在WordTree结构上进行操作,需要预测的是每一个节点相对于父节点的条件概率,要计算某个几点的绝对概率 或者说联合概率,就直接从他乘到根节点。

最后只在同层的节点里进行softmax。

用了这个方法之后,精度稍微下降了一点点。

论文中也给出了数据集融合的图解:

【目标检测 论文精读】……YOLO-V2 & YOLO9000 ……(YOLO9000: Better, Faster, Stronger)_数据集_14


作者融合了coco数据集和imagenet图片数量最多的前9K个类数据集。

在训练的时候也更改了yolov2的模型结构,anchor由5个改成了3个,原来输出(13 * 13 * 5 * 5 +20) 就是13 * 13 的网格,5个anchor,每个anchor25个信息(xywh和置信度加上类别数),现在输出的就是 (13 * 13 * 3 * 5+9418)anchor数变成了3个,然后类别变成了9418个类。

5个anchor改成了3个anchor,可能是因为类别太多数据量太大吧。

7.思考

anchor和bbox的区别:

我一开始就在想,弄出来个anchor干啥,这不就是v1里的bbox嘛,v1里是2个bbox,v2里改成5个bbox不行吗?

可能我的理解还不够深,目前来看,直观的理解这俩的区别,就看有没有先验。对比bbox,anchor是通过在训练集上经过聚类算法得出来的框,比如训练集是人和自行车,那anchor就是长高的框,和矮宽的框,他不再是杂乱无章的,而是对数据集有一定的拟合度的框了。
并且使用anchor之后,最后输出的是预测框相对于anchor的偏移量。
这会让模型训练更加稳定且收敛更快。

V1和V2版本的输出张量公式为何不同?

yolov1的输出张量是 7 * 7 ((2* **5 )+20),2 * *5+20是 两个bbox的5个信息(一共十个信息) +20个分类。

在yolov2里输出的张量是 13 * 13 (5* * (5+20) ), * (5* * (5+20) )是5个anchor框,每个框里5个信息+20个分类。

也就是说 V1是 (框数 * 信息数)+分类数。
v2 是(框数 *(信息数+分类数))。

造成这个原因的根本是 V1里分类由grid cell负责,V2中加入了anchor机制,所以分类由anchor负责。

这个问题我搞了半个多小时,这就是论文没读好的下场!

8.小总结:

对比yolov1所作出的改进:

  • 加了BN(卷积后,激活函数前);
  • 加了高分辨率分类器;
  • 加了anchor(聚类得到个数,1个gird cell 生成5个anchor);
  • 限制预测框;
  • 加入细粒度特征(类似于concat的残差)
  • 加入对尺度训练
  • 改进骨干网络(GoogleNet 变darknet-19)
  • 通过WordTree将不同数据集结合联合训练。用一种新颖的方法扩充了数据集。

再用一张表格对比一下V1和V2版本

yolov1

yolov2

一张图片划分为7 * 7的网格(grid cell)

一张图片划分为13 * 13的网格(grid cell)

每个grid cell 生成2个bbox框,与真实框IOU最大的那个框负责拟合真实框

每个grid cell 生成5个anchor框,通过IOU计算选一个anchor产生预测框去拟合真实框

输入448 * 448 * 3,输出7 * 7 * 30维的张量(30的含义:两组bbox的xywh和置信度+20个类别)

输入416 * 416 * 3 输出13 * 13 * 125维张量(125的含义:五组anchor的xywh和置信度+20个类别),