目标检测算法 - YOLOv2
文章目录
Better,Faster,Stronger。
2017年,提出了yolov2和yolo9000,yolo9000能够实时检测超过9000种物体,主要检测网络还是yolov2。yolov2的整体网络架构和基本思想没有变化,重点解决yolov1召回率和定位精度方面的不足。相比其它的检测器,速度更快、精度更高、可以适应多种尺寸的图像输入。
yolov1是利用全连接层直接预测Bounding Box的坐标。而yolov2借鉴了Faster R-CNN的思想,引入Anchor机制;利用K-means聚类的方法在训练集中聚类计算出更好的Anchor模板,大大提高了算法的召回率;同时结合图像细粒度特征,将浅层特征与深层特征相连,有助于对小尺寸目标的检测。
YOLOv1缺点:
- 准确率较低
- 定位性能较差
- Recall较低
- 检测小目标和密集目标的能力比较差
YOLOv2在YOLOv1基础上进行改进:
- Batch Normalization
- High Resolution Classifier
- Anchor
- Dimension Cluster
- Direct location prediction
- Fine-Grained Features
- Multi-Scale Training
1. Batch Normalization
BN层一般放在线性层的后面,激活函数的前面。BN层可以加快收敛,改善梯度,远离饱和区,可以使用大的学习率来训练网络,使网络对初始化不那么敏感,起到了正则化的作用,防止过拟合,甚至可以取代DropOut层。
注意:
训练和测试时的BN层是不同的。
BN和DropOut同时使用时,性能会降低!!
为什么需要进行Batch Normalization操作呢?
- 很多的激活函数,比如sigmod激活函数,Tanh激活函数,在0附近为非饱和区,最容易训练。如果输出太大或者太小则陷入了激活函数的饱和区,饱和区意味着梯度消失,难以训练,所以使用Batch Normalization强行把神经元的输出集中到0附近。
训练阶段
例如,batch size为32,某层的某个神经元会输出32个响应值。
对这32个相应求均值、标准差,再做归一化。
把归一化后的响应值乘 γ \gamma γ再加上 β \beta β。
测试阶段
测试阶段均值、方差、 γ \gamma γ, β \beta β都用训练阶段全局求出的。
Batch Normalization相当于做线性变换。
μ
t
e
s
t
=
E
(
μ
b
a
t
c
h
)
\mu_{test}=\mathbb{E}(\mu_{batch})
μtest=E(μbatch)
σ
t
e
s
t
2
=
m
m
−
1
E
(
σ
b
a
t
c
h
2
)
\sigma^2_{test}=\frac{m}{m-1}\mathbb{E}(\sigma^2_{batch})
σtest2=m−1mE(σbatch2)
B
N
(
X
t
e
s
t
)
=
γ
⋅
X
t
e
s
t
−
μ
t
e
s
t
σ
t
e
s
t
2
+
ϵ
+
β
BN(X_{test})=\gamma · \frac{X_{test}-\mu_{test}}{\sqrt{\sigma^2_{test}+\epsilon}}+\beta
BN(Xtest)=γ⋅σtest2+ϵXtest−μtest+β
2. High Resolution Classifier
高分辨率的分类器。
YOLOv2先在224*224的图像分类数据集上训练,然后再448*448的图像分类数据集上训练了10个epoch。最后在448*448的目标检测数据集上进行微调。这样网络就能适应大分辨率的输入。
3. Anchor、Dimension Cluster、Direct location prediction
anchor是YOLOv2的核心。YOLOv3,YOLOv4,YOLOv5也是用anchor机制。在YOLOv1里面没有使用anchor机制,直接使用两个bounding box,谁跟ground truth的IoU大,谁负责去拟合这个ground truth。这个时候可能会遇到一个问题,这两个bounding box是不受任何约束的,想怎么变怎么变,想多大就多大,想多宽就多宽,不受约束。没有给他一个限定范围,完全让他俩任意生长,这样做显然是不好的。
于是在YOLOv2里面就引入了anchor机制,不让这两个bounding box随机生长了,给他们一个限制,加个紧箍咒,给他们一个参考,这个参考就是anchor,又叫做先验框。如上图所示以两个anchor为例,一个瘦高,一个矮胖分别负责预测不同形状的物体。这样的话bounding box就不会随机生长了,就会有了自己的使命了,知道自己应该预测什么样的物体了。所以这个时候每个预测框只需要预测出它相较于这个anchor的偏移量就行了。
在YOLOv2中,将一张图片划为了13*13的grid cell,每个grid cell预测5个anchor,即共13*13*5=845个anchor。
事先指定了5种,长宽大小尺度不同的先验框,每个anchor对应一个预测框,而这个预测框只需要去预测输出相对于它所在的anchor的偏移量。
模型输出结构:
在YOLOv2中,类别归于anchor管理,在YOLOv1种,类别归于grid cell管。
在YOLOv2中,每个grid cell产生5个anchor。每个anchor包含4个定位参数、1个置信度参数和20个条件类别概率,即每个anchor会产生25个数。即每个grid cell会产生
25
∗
5
=
125
25*5=125
25∗5=125个数。
YOLOv2使用的是Darknet-19作为骨干网络,输入图像为416*416,YOLOv2将其划分为13*13的网格,对应输出为13*13的feature map。
定义anchor的个数为5个,并不是手动去选择的。
在Faster RCNN和SSD里面,anchor的长宽大小尺度是人们手动去选择的。
为了解决这个问题,作者对整个voc和coco数据集进行了长宽比的聚类,不同的聚类中心个数对应着不同的IoU。聚类中心越多,anchor能覆盖的IoU就越大,但是anchor越多,模型会变的越复杂。则取了anchor数为5。如下图,黑框表示Pascal Voc2007数据集中的anchor长宽比,蓝框表示coco目标检测数据集中的anchor长宽比。
加入anchor后,输出相较于所在anchor的偏移量,这个偏移量仍然是可以全图随便偏移的,会导致模型非常不稳定。
为了限制预测框的位置,作者加了一个限制。YOLOv2加了一个sigmoid函数,无论输入的偏移是负无穷到正无穷的什么数,最后的输出总是在0~1之间。通过sigmoid函数,将预测框的中心点限制在了它所在的grid cell里面。
最终的 b b b就为预测框。
4. Loss Function
5. Fine-Grained Features
细粒度特征。
浅层的网络预测出特征图后分为两路,一路进行正常的卷积、下采样操作,一路将这个feature map拆分为4份,将两路的结果进行叠加,拼成一个更大的结果。这个结果包括底层的细粒度的信息以及经过卷积和下采样后高层的信息。整合了不同尺度的特征,有利于小目标的检测。
拆分方法:
6. Multi-Scale Training
同一个模型,每10步就会重新选取输入图像的大小。也就是说,在模型训练期间,把不同大小的图像输入到模型中,就强迫了模型必须能兼容、能覆盖所有尺度输入大小的图像。
模型的权重没有改变,模型的结构也没有改变。模型结构没有改变,那么为什么能够输入不同尺度的图像呢?因为Darknet19有一个全局平均池化层,它把输出通道的每一个feature map求平均来替代全连接层。
如果输入的是一个高分辨率的大图片,YOLO会预测的比较慢,但是会预测很准。如果输入的是低分辨率的小图片,YOLO会预测的非常快,但是精度没有那么高。因此,我们可以选择不同输入图像的尺度来达到速度和精度的权衡。
7. Faster
使用Darknet-19作为骨干网络。使用Darknet19使网络变得更快。
YOLOv2采用了一个新的基础模型(特征提取器),称为Darknet-19,包括19个卷积层和5个maxpooling层。
Darknet-19与VGG16模型设计原则是一致的,主要采用 3 × 3 3\times 3 3×3卷积,采用 2 × 2 2\times 2 2×2的maxpooling层之后,特征图维度降低2倍,而同时将特征图的channles增加两倍。
Darknet-19最终采用global avgpooling做预测,并且在 3 × 3 3\times 3 3×3卷积之前使用 1 × 1 1\times 1 1×1卷积来压缩特征图channles以降低模型计算量和参数。
Darknet-19每个卷积层后面同样使用了batch norm层以加快收敛速度,降低模型过拟合。在ImageNet分类数据集上,Darknet-19的top-1准确度为72.9%,top-5准确度为91.2%,但是模型参数相对小一些。
使用Darknet-19之后,YOLOv2的mAP值没有显著提升,但是计算量却可以减少约33%。
8. Stronger
使检测类别变的更多。
yolov2说是可以检测出9000种类别的物体。
作者将coco目标检测数据集和ImageNet图像分类数据集联合训练。
coco数据集并不是很细粒度,而ImageNet图像分类数据集有几万个类别,但是它只有分类的标签,并没有目标检测定位的标签。
因此,作者将这两个数据集结合在一起,让模型既能学目标检测,也能学图像分类,而且能学细粒度的目标检测,能够检测出在ImageNet中的物体。
如果强行的将两个数据集合并在一起是很难的。因为我们在普通的图像分类中使用的softmax,是假设所有的类别是互斥的。
因此,不能简单的把检测数据集和分类数据集强行的弄成这种扁平的分类结构。
ImageNet的分类体系是WORDNET(普林斯顿大学提出的一个语言学数据库),是一种错综复杂的有向图结构。
YOLO9000将这种错综复杂的有向图结构简化成了层次分明的树状结构。
作者提出了一种层级分类方法(Hierarchical classification),主要思路是根据各个类别之间的从属关系(根据WordNet)建立一种树结构WordTree,结合COCO和ImageNet建立的WordTree如下图所示:
WordTree中的根节点为"physical object",每个节点的子节点都属于同一子类,可以对它们进行softmax处理。在给出某个类别的预测概率时,需要找到其所在的位置,遍历这个path,然后计算path上各个节点的概率之积。
在训练时,如果是检测样本,按照YOLOv2的loss计算误差,而对于分类样本,只计算分类误差。在预测时,YOLOv2给出的置信度就是 P r ( p h y s i c a l o b j e c t ) Pr(physical object) Pr(physicalobject),同时会给出边界框位置以及一个树状概率图。在这个概率图中找到概率最高的路径,当达到某一个阈值时停止,就用当前节点表示预测的类别。