0 前言
在上一篇文章中,我们学习了YOLOv1模型,YOLOv1将图像划分为7×7=49个网格,每个网格只会预测两个预测框,而且这两个预测框预测的类别是共享的。
虽然YOLOv1单阶段检测与两阶段相比是极具创新性的,但是其依然存在一些问题:
同一个网格中存在多个小而密集的物体,部分物体就无法被预测。
预测框最多只有98个,虽然情况不常见,假如一张图像有超过98个物体,就会漏检。
虽然YOLOv1与R-CNN相比速度明显,但是准确率依然有待提高。 针对上面的问题,YOLOv2在前人的肩膀上做了诸多改进。
1 思维导图
可以看出YOLOv2的改进点还是挺多的,针对YOLOv1的主干网络、特征提取、训练以及预测框,都做出了相应的调整,使得检测效果得到了提高。
2 主干网络
2.1 DarkNet-19网络
我们首先来看一下DarkNet-19的网络结构图:
乍一看,其实就是普通的卷积神经网络,但是仔细观察可以发现,网络中的卷积核大小要么是3×3,要么是1×1,并且是有规律的堆叠,这并不是随便设置的,卷积核的大小有讲究。主要作用是什么呢? 作者这么设计网络主要是为了通过小卷积核获得大的感受野。在卷积的特性中,小卷积核堆叠在一起可以等效于大卷积核的感受野:
2个3x3卷积的感受野等于1个5x5卷积
3个3x3卷积的感受野等于1个7x7卷积。
上面大家感兴趣的可以去推导一下。
这种做法最早在VGG网络中得到运用,可以在能够获得较大感受野的同时,而显著降低计算量和参数量。
那么1×1卷积有什么作用呢?我们可以看到在3×3卷积中穿插了不少1×1卷积。1×1卷积虽然不能改变特征图的尺寸大小,但是可以灵活调整通道数。
因此在DarkNet-19中,通过3×3卷积和1×1卷积的组合,可以显著降低计算量,提升了网络的效率。
DarkNet-19末端采用全局平均池化,相当于将每个通道的特征图求均值,最终进行分类,但是YOLOv2是检测任务,因此其实是没有采用的。
除此之外,为了加快网络训练速度,避免网络的过拟合,减少了训练中的波动,使得优化过程更稳定,从而找到更好的局部最优解,在DarkNet-19的训练中采用批归一化(Batch Normalization)。批归一化在我们之前讲解Transformer的文章中也介绍过,所谓的归一化,其实就是对一组数据减去均值再除以标准差,只不过在具体的计算中,加入了一些参数和影响因子。
如上图所示,Batch Norm是上面第一种,其中N代表的是样本批次,我们可以看出它是对不同批次的样本取出特征为一组数值再进行运算,对比第二张图中的层归一化(Layer Norm)则是对单一样本、每一个层单独计算。还有其他归一化方式,这里我们不做出展开,后续有机会专门写一篇文章介绍比较。
2.2 细粒度特征提取(Pass Through)
由于随着卷积层的不断堆叠,特征图的分辨率会越来越小,YOLOv2作者认为这会导致来自浅层网络的细粒度特征会丢失,影响小尺寸目标的检测和识别,因此需要将浅层网络提取的高分辨率、细粒度特征与深层网络提取的低分辨率、语义丰富的特征进行融合。 融合的方法不是粗暴的拼接,还包括特征的重排。
具体是个什么过程呢?我们举个例子:
来自浅层网络提取的特征尺寸为26×26×512,来自深层网络提取的特征尺寸为13×13×1024,我们最终将来自于浅层网络的特征26×26×512转变为13×13×2048,再和深层网络的特征融合拼接在一起,得到最终输出的特征大小为13×13×3072。
计算过程:
假如我们有4×4×3的特征图,我们要将特征转化为2×2×12。我们要在空间维度上每隔一个元素进行采样,然后拼成一个小特征图。 比如蓝色,我们将第一个通道的所有蓝色取出来,可以得到一个特征图,三个通道就可得到三个特征图,其余颜色同理。
3 训练
3.1 高分辨率分类器
虽然YOLOv1也采用了再ImageNet上进行预训练,但是ImageNet数据集的分辨率为224×224,在正式进行检测任务时,输入分辨率突然成了448×448。这种剧烈变化,使得网络被迫调整权重参数来适应新的分辨率,作者认为这可能会影响检测效果。
因此针对分辨率的变化,作者采取了一个折中的办法:将图像的分辨率从224×224放大到448×448,并且先在ImageNet数据集上训练10个Epoch。
这样做有两个好处:
网络在正式训练前,就已经调整了参数适应更高的分辨率。
网络在高分辨率图像上训练过,后续训练可以更有效的提取高分辨率图像中的特征。
结果也确实使得检测的性能有了较大提升,mAP(平均精度均值)提升了约4%。
在YOLOv2中,最后使用的输入图像大小,从448×448调整为了416×416,这样在经过主干网络后,特征图的大小是13×13,这样能够使得图像的正中心恰好位于网格中间。如果输入时448×448,最终的输出会是14×14的网格,这会造成图像的中心点位于网格的交叉点处,假设中心刚好有一个物体,该物体的中心会落在四个网格的交界处,导致其所属的网格不明确。
3.2 多尺度训练
为了提升模型针对不同尺寸物体的检测能力,模型在训练阶段会动态、随机的改变输入到网络中的图像尺寸。
比如每训练10个epoch,图像的尺寸就会改变如352×352,608×608等,这个过程会贯穿整个训练过程。使得网络在不同分辨率下进行训练,可以学习到数据中的多尺度特征,提升检测效果。
4 锚框机制
我们先来看看YOLOv2的输出,是一个一个三维张量,尺寸为 13 × 13 × (5 × (4 + 1 + C))。
其中13×13是特征图的大小,被划分为13×13的网格
5指的是5个预测框(YOLOv1是2个)
4 + 1 + C包含4个位置参数:(tx, ty, tw, th);1个置信度参数 (t0)以及C个类别概率
假如总共有20类,最终输出为 13 × 13 × 125。
由于YOLOv1预测的框的形状是任意的,难以适应不同大小的物体(比如有的宽一些,有的窄一些,汽车和人的形状差别就很大),所以YOLOv2引入预先设定好大小的框的形状,这里就是锚的含义所在,预先放置一个目标,等着预测框来靠近。这样的锚框设定5个。
那么预测框如何确定呢?
模型预测的不再是预测框的坐标,而是预测5组相对于5个锚框的偏移量 (tx, ty, tw, th)。将偏移量映射到对应的锚框上,就得到了最终的预测框。
我们假设网络的输出为(tx,ty,tw,th):
其中:tx 和 ty 用来预测目标中心点相对于其所属网格左上角点的偏移量,需要经过σ函数转换,预测框中心点坐标为 (bx, by),宽和高分别为(bw,bh)。对应网格的坐标为(cx,cy),锚框的尺寸为pw、ph(宽和长)。
将tx和ty经过sigmoid函数进行映射到0~1之间,确保预测框中心点落在当前网格内部,然后计算得到:
在训练阶段,预测框和真实框是如何匹配的呢?
这一点和YOLOv1还是保持一致的,当真实目标的中心点落在哪个网格内,这个网格就需要负责预测出这个物体。
最终网络会输出得到5个预测框,这么多预测框需要筛选,此时那我们选择与当前真实框IOU最大的那个预测框加入训练,如果一个网格内存在多个物体,此时网格会为每个物体分别选择出IOU最大的预测框。因此一个网格可能会负责多个物体的检测。比如下图中红色框为预测框,绿色框为真实框,我们会选择IOU最大的那个作为责任框,也就是实线的那一个。
YOLOv2的损失函数相当复杂:
第一部分用来计算置信度误差
第二部分是锚框和预测框的坐标误差
第三部分则是真实框与匹配的预测框各部分的损失总和,包括坐标损失、置信度损失以及分类损失。
其核心思想是分别计算边界框坐标、置信度和分类概率的误差,并通过权重系数进行平衡。
欢迎大家关注我的gzh:阿龙AI日记。