参考大佬:同济子豪兄
YOLOv2-yolo9000
yolo9000-batter,faster,stronger
Introduction
我们提出了一种新的方法来利用大量的图像分类数据,来扩大当前检测系统的范围。我们的方法使用目标分类的分层视图,允许我们将不同的数据集组合在一起。
我们还提出了一种联合训练算法,使我们能够在检测和分类数据上训练目标检测器。我们的方法利用有标签的检测图像来学习精确定位物体,同时使用分类图像来增加特征表达和鲁棒性。
Batter
- Batch Normalization
- High Resolution Classifier
- Anchor
- Dimension Cluster
- Direct location prediction
- Fine-Grained Features
- Multi-Scale Training
Batch Normalization
YOLOv2舍弃了Dropout,卷积后全部加入BN层,批归一化会获得收敛性的显著改善,同时消除了对其他形式正则化的需求。通过在 YOLO 的所有卷积层上添加批归一化,我们在 mAP 中获得了超过 2%的改进。批归一化也有助于模型正则化。通过批归一化,我们可以从模型中删除 dropout 而不会过拟合。
Batch Normalization(BN)就是对一批数据进行归一化。BN不仅可以加快了模型的收敛速度,而且更重要的是在一定程度缓解了深层网络中 “梯度弥散” 的问题,从而使得训练深层网络模型更加容易和稳定。
在 BN 出现之前,我们的归一化一般是在数据输入时进行求均值以及求方差做归一化,BN则可以在网络中任意一层进行归一化处理。
当模型训练时,网络每一层的输入数据的分布是一直在变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。BN 的提出,就是要解决在训练过程中,中间层数据分布发生改变的情况。
如上图所示,BN 步骤主要分为 4 步:
- 求每一个训练批次数据的均值
- 求每一个训练批次数据的方差
- 使用求得的均值和方差对该批次的训练数据做归一化,获得 0-1 分布。其中 ε \varepsilon ε是为了避免除数为 0 时所使用的微小正数。
- 尺度变换和偏移:将 x i x_{i} xi乘以 γ \gamma γ调整数值大小,再加上 β \beta β增加偏移后得到 y i y_{i} yi,这里的 γ \gamma γ是尺度因子, β \beta β是平移因子。这一步是 BN 的精髓,由于归一化后的 x i x_{i} xi基本会被限制在正态分布下,使得网络的表达能力下降。为解决该问题,我们引入两个新的参数: γ β \gamma \,\,\,\beta γβ。 γ \gamma γ和 β \beta β是在训练时网络自己学习得到的。
BN 到底解决了什么?
一个标准的归一化步骤就是减均值除方差,那这种归一化操作有什么作用呢?我们观察下图,
a 中左图是没有经过任何处理的输入数据,曲线是 sigmoid 函数,如果数据在梯度很小的区域,那么学习率就会很慢甚至陷入长时间的停滞。
减均值除方差后,数据就被移到中心区域如右图所示,对于大多数激活函数而言,这个区域的梯度都是有梯度的,这可以看做是一种对抗梯度消失的有效手段。
对于每一层数据都那么做的话,数据的分布总是在随着变化敏感的区域,相当于不用考虑数据分布变化了,这样训练起来更有效率。
减均值除方差得到的分布是正态分布,我们能否认为正态分布就是最好或最能体现我们训练样本的特征分布呢?
不能,比如数据本身就很不对称,或者激活函数未必是对方差为 1 的数据最好的效果,比如Sigmoid 激活函数,在 - 1~1 之间的梯度变化不大,那么非线性变换的作用就不能很好的体现,换言之就是,减均值除方差操作后可能会削弱网络的性能!针对该情况,在前面三步之后加入第 4 步完成真正的 batch normalization。
BN 的本质就是利用优化变一下方差大小和均值位置,使得新的分布更切合数据的真实分布,保证模型的非线性表达能力。
预测时的均值和方差
在训练时,我们会对同一批的数据的均值和方差进行求解,进而进行归一化操作。
在模型训练时记录下每个 batch 下的均值和方差,待训练完毕后,我们求整个训练样本的均值和方差期望值,作为我们进行预测时进行 BN 的的均值和方差:
最后测试阶段,BN 的使用公式就是:
High Resolution Classifier
所有最先进的检测方法都使用在 ImageNet 上预训练的分类器。从 AlexNet 开始,大多数分类器对小于 256×256 的输入图像进行操作。YOLO 初始版本以 224×224 分辨率的分类器。
YOLOv2也是先用224x224的进行预训练,与v1不同的是,又在 ImageNet 上以 448×448的分辨率对分类网络进行 10 个迭代周期的微调。这使网络来调整其卷积核以便更好地处理更高分辨率的输入。这个高分辨率分类网络使我们增加了近 4% 的 mAP 。
到底哪里用的448,哪里用的416?
YOLO 的卷积层将图像下采样 32 倍,所以我们希望输入的特征图是32的整数倍;我们希望特征图中位置的个数是奇数,即只有一个中心格子,因为目标(特别是大目标),往往占据图像的中心,所以在中心有一个单独的位置来预测这些目标的很好的,而不是四个都相邻的位置。因此选择了 分辨率为416 的输入图像。
Anchor
anchor是YOLOv2的核心。我们在YOLOv1里面没有使用anchor机制,是将图片划分为7x7的网格,每个网格负责预测两个bbox,谁与ground truth的IOU大,谁就负责去拟合这个ground truth。
这个时候可能会遇到一个问题,这两个bounding box是不受任何约束的,想怎么变怎么变,想多大就多大,想多宽就多宽,这显然很难训练。
于是在YOLOv2里面就引入了anchor机制,不让这两个bounding box随机生长了,给他们一个限制,这个限制就是anchor,又叫做先验框。
yolov2事先指定了5种不同的固定尺寸的anchor。每一个anchor都对应一个预测框,而这个预测框只需要去预测它相对于它所在的anchor的偏移量就可以了。
比如说对于这个图片而言,首先将图片划分为13x13的grid cell,比如说小女孩的中心点人工标注框的中心点落在了某个grade cell里,就应该由这个grade cell产生的这5个anchor中与ground truth IOU最大的那个anchor去负责预测。
预测框只需要预测出它相较于这个anchor的偏移量就可以了。
这边比较绕,再看个例子。
左图中他的每一个 grade cell 只画了两个anchor (应该是右图中的5个)。
比如说这个白框是人工标注的汽车的框那么它的中心点落在了4号grade cell里边这个车就应该由4号grade cell产生的5个anchor中的一个去负责预测汽车。
那么由这5个里边的哪一个呢?就是由这5个anchor中与这个白框(ground truth)的IOU最大的那个anchor去负责预测。
看右图,哪个IOU最大呢?显然是最大的那个框。
使用 Anchor 框,我们的精度发生了一些小的下降。YOLO 对每张图像只预测 98 个边界框,但是使用 Anchor 框我们的模型预测超过一千个。如果不使用Anchor 框,我们的中间模型将获得69.5 的 mAP,召回率为 81%。使用 Anchor 框的模型得到了 69.2 mAP,召回率为88%。尽管 mAP 下降了一点,但召回率的上升意味着我们的模型有更大的改进空间
一个小技巧:在YOLOv2中把模型输出的feature map的长宽设置成了奇数。因为奇数的长宽有一个中心的grid cell,这样当目标位于图片的中心时(事实上很多图片的目标都在图片中心位置),就能以中心的一个grid cell进行预测;而当feature map为偶数时,需要4个grid cell进行预测,这样会增加没必要的计算成本。
Direct location prediction
这样一来,YOLOv2的的输出就与YOLOv1不同了:
yolov1的输出是两个bbox的xywh和预测框的置信度,以及20个类别的置信度,共30个量。
两个bbox的两个confidence分别乘每个classes的confidence,这样一共 7x7x2=96 个向量。
yolov1的类别是归grade cell管的,yolov2的类别归anchor管了
如图所示,每个grid cell有五个anchor,每个anchor包含xywh+预测框的置信度+每个类的置信度,共25个信息,所以每个gird cell有 5x25=125维的向量,整张图像的输出就是 13x13x125的张量
Dimension Cluster
那么这5个先验框的尺寸咋设置呢?作者使用了k-means聚类算法。
左边是聚类数量k和平均IOU之间的关系,考虑到准确度和模型复杂度之间的权衡,选择k=5。
右边是在VOC和COCO数据集上的5个先验框的可视化结果。COCO数据集有更大的尺寸变化。
yolov1的预测框相对于grid cell是随机生长的,yolov2的预测框相对anchor的偏移也可能是随机乱窜的。
这时就要对偏移量进行限制。因为输出是预测框相对于anchor的偏移量,下面的
t
x
,
t
y
,
t
w
,
t
h
t_x,t_y,t_w,t_h
tx,ty,tw,th就是偏移量。
t
x
t_x
tx和
t
y
t_y
ty可以是从负无穷到正无穷的任何数,这就可能导致野蛮生长。
于是给他给它加了一个Sigmoid函数,这个函数的作用就是无论偏移值是多大多小,最终的输出是0到1之间的。这个 C x C_x Cx和 C y C_y Cy是grid cell左上角对应的坐标,这里它全部归一化为1x1了,就是说它的横坐标只可能在一个单位框范围内滑动,也就是说预测框的中心点肯定就被限制在了这个grid cell里面。
而宽和高可能比较大,也可能比较小,所以就不对其限制了。
最终的confidence和yolov1一样,由object的置信度乘上IOU
Fine-Grained Features
细粒度特征
在最后pooling之前,把特征图分成两路处理:一路进行正常的conv+pooling操作,以减小特征图尺寸,增加通道数;另一路将原特征图拆分成四份,在通道维拼接成一个长条(称为passthrough层);最后再将两路特征拼接在一起。这样能够保留较低层的特征(有点DenseNet的味道)
passthrough层 直观理解:
Multi-scale training
同一个模型,每10步就选取一个新的输入图像大小,以使得模型能够适应不同大小的图像输入。
为什么可以这样做呢?这是因为使用了Global Average Pooling (全局平均池化,GAP)操作,对输出的future map的每一个通道求平均来替代全连接层。虽然模型最后输出的feature map大小不同了,但是使用了GAP之后,不同尺度的feature map都变成了相同的大小(即:1)。
如果想yolov1用全连接层,则输入的图像大小必须是固定的。但是现在因为有了global average pooling你可以输入任意大小的图像,而它最后都能变成那个数据结构。
你输入的是高分辨率的大图片那么yolo会预测的比较慢,但是会预测的很准;如果你输入的是低分辨率的小图片那么yolo会预测的非常快,但是精度没有那么高;所以你可以通过选择不同输入图像的尺度来达到速度和精度的权衡。
YOLOv1 演变到 YOLOv2 的过程。从表中可以看出,加了Anchor boxes之后mAP反而下降了,为什么还要采用呢?因为加了Anchor之后可以大大增加Recall,所以是值得的;另外换了new network之后也没有很大的提升,那为什么要换呢?这是因为DarkNet相对于YOLOv1的骨干网络可以大大降低计算量,所以也是值得的。
LOSS
这里的loss与yolov2类似
Faster
Darknet-19
YOLOv2变更快的主要原因是换了新的骨干网络。下面是使用不同的骨干网络的速度、精度对比。
Darknet包含分类的darknet19和检测的darknet19。
分类网络可以看到它里边大量采用了1x1卷机来升维降维升维降维,1x1卷机就起到了这么一个作用——先降维再升维,它的计算量是很少,最后这个卷机层输出的是7x7x1000的一个张量,然后用global average pooling对这1000个通道求平均得到了1000个值,这1000个值正好就是1000个类别的概率。
如果是用于检测就是去掉后面的conv avgpool和softmax,后边加三个3x3卷机层,以及pass through层,最后是1x1卷机层,得到的是13x13x125维度的张量。
Stronger
类别更多
这个技巧并没有在后面的论文中用的特别多,但可以作为一个开脑洞的想法来了解一下。
COCO里面只有80个类别,而ImageNet里有22k个类别。因此,作者考虑将COCO数据集和ImageNet数据集结合起来训练YOLOv2,让模型既进行分类的训练又进行目标检测的训练,使得模型能进行细粒度的目标检测,能够检测出更多类别的物体。
但是强行将这两个数据集结合起来是很困难的。例如在ImageNet中美洲黑熊和亚洲黑熊是两个不同的类别,这是更细粒度的标签;而在COCO数据集中只有黑熊这一种相对来说粗粒度的标签。那么怎么将这两个数据集结合起来呢?
在YOLOv2中采用了将分类标签变成树状结构的方法,逐层使用softmax进行分类,这样就能将粗粒度的COCO和细粒度的ImageNet放在一起训练了。
下面是树状标签结构和逐层softmax分类的另一种表示方法。
从而要计算一个节点的绝对概率,就可以通过计算其一系列父节点的条件概率的乘积。例如要计算一张图片是卡车的概率,就可以这样计算:
在论文中也给出了一个计算一张图片是否是Norfolk terrier类别的例子:
在训练过程中,如果输入一张目标检测的图片,就反向传播目标检测的误差;如果输入的是一张分类的图片,就反向传播分类的误差。这样就可以让模型既学习到目标检测画框框的能力,又学习了ImageNet海量数据细粒度分类的能力
作者在COCO数据集和ImageNet分类数据集中进行了联合训练,在ImageNet目标检测数据集中进行了测试,得到的结果如下。从结果中发现,这样训练得到的动物的准确率是不错的,但是衣服和装备这些类别的效果是不好的。