YOLOv2是一个集成了分类和检测任务的神经网络,它将目标检测和分类任务统一在一个单一的网络中进行处理。
本文在yolov1的基础上,对yolov2的网络结构和改进部分进行讲解。yolov1的知识点可以看我另外一篇博客(yolov1基础精讲-CSDN博客)。
一、yolov1存在的不足
- 检测小目标和密集目标的效果差
- 对于重叠在一起的物体检测不准
- yolov1的定位不准
- 召回率较低
- map较低
二、yolov2针对上述问题做了哪些改进
在原论文的Better章节提到以下7个改进部分:
- Batch Normalization(批归一化)
- High Resolution Classifier(高分辨率分类器)
- Anchor(锚点)
- Dimension Cluster(维度聚类)
- Direct location prediction(直接位置预测)
- Fine-Grained Features(细粒度特征)
- Multi-Scale-Training(多尺度训练)
三、网络结构及改进点详解
1. 网络架构
YOLOv2使用了一个新的19层深度卷积神经网络Darknet-19作为其基础特征提取器。Darknet-19包含有19个卷积层和5个MaxPooling层,是一个完全卷积的网络,没有全连接层。
与复杂计算量大的VGG-16相比,Darknet-19大大的减少了计算量,同时保持了精度,提高了模型的速度。
YOLOv2的网络结构在处理分类和检测任务时,有一些区别。
上图是yolov2的图像分类网络结构图。利用很多1*1卷积不停的降维和升维,所以参数量比较少。最后通过一个全局平均池化将得到的7*7*1000的数据变成1*1*1000的数据(即1000个分类结果)。
上图是yolov2的图像检测网络结构图。yolov2删除最后一个卷积层,将其换成了三个3 × 3的卷积层,每个3 × 3的卷积层有1024个卷积核,最后一个由1 × 1的卷积层来得到13*13* [(5+20)*5] 的数据。网络结构会在后面部分解释。
2. Batch Normalization(批归一化)
Batch Normalization(BN)简单来说就是将神经元的输出减去均值再除以差,使输出变为以0为均值,标准差为1的分布。因为很多激活函数在0附近是非饱和区,远离0是饱和区,如果输出的数据太大或太小会陷入饱和区,造成梯度消失,难以训练。所以用BN层将数据集中到0附近的非饱和区。
Batch Normalization的详细讲解可以看我另一篇博客(批量归一化(BN)和层归一化(LN)的区别)。
在每层卷积层的后面都加入 batch normalization 层,不再使用dropout,使得模型在 mAP 上提升了2.4%。
3. High Resolution Classifier(高分辨率分类器)
在yolov1中,是用224*224的图像进行训练,用448*448的图像进行推理。模型在推理时适应这种分辨率的差异,所以性能会降低。
所以yolov2先在224*224的分类数据集上训练一会儿,再在448*448的分类数据集上训练10个epoch,最后在448*448的检测数据集上进行微调训练。这样就能适应大分辨率的输出,这个改进提升了3.5%的map
4. Anchor(锚点)
YOLOv1直接回归边界框的坐标和尺寸,可能在定位上不够准确,因为并没有对bounding box作尺度上的约束,可能会导致某个grid cell上的bounding box非常大。
YOLOv2引入了锚点(Anchors)的概念来改善目标检测的准确性和召回率,尤其是在小目标和密集目标的检测上。锚点是一组预定义的边界框形状,代表了数据集中常见物体的尺寸和比例。
为什么需要预定义的边界框形状呢,因为大部分的物体的检测框有其固有的特征。
如上图所示,人的检测框是瘦高的,车的检测框是矮胖的。
yolov2中将图片分为13*13个grid cell,每个grid cell有5个锚框,每个锚框对应一个预测框。预测框预测出相对于这个锚框的偏移量,而不像yolov1中没有尺寸和位置限制造成的野蛮生成。并且每个预测框都可以预测不同的物体,在YOLOv1中,由于类别概率分布是整个grid cell共享的,因此一个grid cell不能预测不同的类别。然而在YOLOv2中,由于每个bounding box有自己独立的类别概率分布,因此一个grid cell能够预测不同的类别。
与yolov1类似
在训练阶段,对于每个网格单元,只有那些与真实边界框具有最高IoU(交并比)的锚点才会被标记为“负责”预测该物体。这意味着在训练中,每个真实边界框只会与一个最适合它的锚点进行匹配,而其他锚点则被视为“负例”,即它们不包含任何物体,从而学习到不预测物体的情况。
在推断阶段,每个网格单元的5个锚点都会产生预测,但是NMS过程会去除那些重叠的低置信度预测,只保留最可能的检测结果。
YOLOv1输出结构
- 每个grid cell输出以下信息:
- 2个bounding boxes,每个bounding box包含:
- 4个坐标值(x, y, w, h)
- 1个置信度分数
- 共享的20个类别概率分布
YOLOv1每个grid cell输出:2 * (4 + 1) + 20 = 30个值
- 2个bounding boxes,每个bounding box包含:
YOLOv2输出结构
- 每个grid cell输出以下信息:
- K个bounding boxes(K通常为5),每个bounding box包含:
- 4个坐标值(x, y, w, h)
- 1个置信度分数
- 20个类别概率分布
YOLOv2每个grid cell输出:5* (4 + 1 + 20) =125个值
- K个bounding boxes(K通常为5),每个bounding box包含:
5. Dimension Cluster(维度聚类)
那anchor怎么得到的呢?
锚点是通过对训练集中的真实边界框进行K-means聚类分析得到的。具体步骤如下:
-
数据准备: 收集所有训练图像中真实边界框的宽高比。
-
初始化锚点: 选择一个锚点数量k,随机选择k个边界框尺寸作为初始的锚点。
-
分配边界框: 对于数据集中的每一个真实边界框,计算其与每个锚点之间的IoU(交并比)。将每个边界框分配给IoU最大的锚点,形成k个聚类。
-
更新锚点: 对于每个聚类,计算所有分配给该聚类的边界框的平均尺寸,用这个平均尺寸更新该聚类的锚点。
-
迭代优化: 重复步骤3和4,直到锚点的更新变化小于某个阈值或达到预定的迭代次数。这个过程类似于传统的K-means算法,但目标是最大化锚点和它们所代表的边界框之间的平均IoU。
-
评估和选择锚点: 评估不同数量的锚点(k值,yolov2设置为5)对模型性能的影响。通常,锚点数量越多,模型的召回率越高,但也会增加计算成本。通过实验,选择一个在性能和效率之间平衡的锚点集合。
anchor数量k为5时兼顾了性能与效率。
6. Direct location prediction(直接位置预测,损失函数解析)
yolov1中直接回归预测框可能全图乱跑。但是目前yolov2根据锚框不加以限制来预测相对锚框的偏移量也会导致乱窜,如上图所示。所以要加上限制。
下面对上面的图中的公式进行解释。(先将网格大小归一化,即令grid cell的宽高都为1)
7. yolov2的损失函数
该损失函数图中解析的比较明确了,不过多解释,如果有兴趣可以看哔站大佬的讲解(【精读AI论文】YOLO V2目标检测算法_哔哩哔哩_bilibili)。
8. Fine-Grained Features(细粒度特征)
YOLOv2中引入了PassThrough Layer,它将前面的卷积层的特征图与后面的层进行融合,从而将高分辨率的特征信息传递给最终的检测层。这种做法相当于跳过了一些中间层,直接将更早期、分辨率更高的特征图的信息整合到最终的检测中,增强了模型对小目标的敏感度。
网络过程中的操作如上图。
PassThrough Layer的操作如上图,能将图像的宽高减半,通道变为原来的4倍。
9. Multi-Scale-Training(多尺度训练)
YOLOv2使用了多尺度训练,即在训练过程中改变输入图像的大小。这样做的好处是网络可以学习到不同尺度的特征,从而在测试时能够更好地适应不同大小的目标。
如图所示,就是在训练的过程中每间隔一定的 iterations 后改变输入的图片大小。
由于yolov2没有采用全连接层,最后是用全局平均池化来得到分类,所以不用调整网络结构就可以输入不同分辨率的图像而得到相同的输出维度。