1、基础模型:yolov3-spp。考虑到yolov4、yolov5的tricks可能存在过度优化,因此选择yolov3添加spp结构作为基础网络。
2、yolox-darknet53:对yolov3基础模型添加各种trick是,例如Decopled head,SimOTA,anchor free等。
3、训练过程添加很多策略,例如:
(1)添加EMA权值更新,cosine学习率机制,warmup学习率调节等
(2)使用IOU损失函数训练reg分支,BCE损失函数训练cls与obj分支。
(3)添加随机水平翻转、颜色调节数据增强方法,马赛克和mixup。发现随机缩放裁剪与马赛克增强方法冲突,移除RandomResizedCrop方法。
在此基础上,又增加了Strong augmentation、Decoupled head、anchor-free、multi positives、SimOTA,等5种trick
① 输入端:Strong augmentation数据增强,Mosic、Mixup数据增强。(训练最后15个epoch关闭)
② BackBone主干网络:主干网络没有什么变化,还是Darknet53。
③ Neck:没有什么变化,Yolov3 baseline的Neck层还是FPN结构。
④ Prediction:Decoupled Head、End-to-End YOLO、Anchor-free、Multi positives。
将原始的yolo head 拆分为reg、cls、obj三个分支,Decoupled head 的收敛速度更快,且精度更高,但运算复杂度会增加。
Concat前总共有三个分支:
(1)cls_output:主要对目标框的类别,预测分数。因为COCO数据集总共有80个类别,且主要是N个二分类判断,因此经过Sigmoid激活函数处理后,变为20*20*80大小。
(2)obj_output:主要判断目标框是前景还是背景,因此经过Sigmoid处理好,变为20*20*1大小。
(3)reg_output:主要对目标框的坐标信息(x,y,w,h)进行预测,因此大小为20*20*4。
最后三个output,经过Concat融合到一起,得到20*20*85的特征信息。
Decoupled Head②输出特征信息,并进行Concate,得到40*40*85特征信息。
Decoupled Head③输出特征信息,并进行Concate,得到80*80*85特征信息。
再对①②③三个信息,进行Reshape操作,并进行总体的Concat,得到8400*85的预测信息。
并经过一次Transpose,变为85*8400大小的二维向量信息。
这里的8400,指的是预测框的数量,而85是每个预测框的信息(reg,obj,cls)。
在Yolov3、Yolov4、Yolov5中,通常都是采用Anchor Based的方式,来提取目标框,进而和标注的groundtruth进行比对,判断两者的差距,即损失函数,再更新网络参数。
以yolov3为例,图片大小416*416,输出三个特征图大小为13*13,26*26,52*52。因此产生3*(13*13+26*26+52*52)*(80+4+1)=904995个预测结果。当输入为640*640时,产生3*(20*20+40*40+80*80)*85=2142000个预测结果。
yolox采用Anchor free方式。网络最后输出8400*85 = (20*20+40*40+80*80)*(80+4+1)的特征向量, 当输入为640*640时,最终输出得到的特征向量是85*8400。相对于yolov3的anchor base 少了2/3的参数。
比如上图中,最上面的分支,下采样了5次,2的5次方为32。
并且Decoupled Head①的输出,为20*20*85大小。
因此如上图所示:
最后8400个预测框中,其中有400个框,所对应锚框的大小,为32*32。
同样的原理,中间的分支,最后有1600个预测框,所对应锚框的大小,为16*16。
最下面的分支,最后有6400个预测框,所对应锚框的大小,为8*8。
当有了8400个预测框的信息,每张图片也有标注的目标框的信息。
这时的锚框,就相当于桥梁。
这时需要做的,就是将8400个锚框,和图片上所有的目标框进行关联,挑选出正样本锚框。
而相应的,正样本锚框所对应的位置,就可以将正样本预测框,挑选出来。
这里采用的关联方式,就是标签分配。
8400个anchor框信息,每一个框对应85*8400特征向量中的预测框信息。
对于这些预测框,需要区分正样本与负样本,其中,正样本占少数。
这里需要利用锚框和实际目标框的关系,挑选出一部分适合的正样本锚框。
关键点:(1)初步筛选、(2)SimOTA。
(1)初步筛选:包括根据中心点判断、根据目标框判断
A、根据中心点判断:寻找anchor-box的中心点,落在groundtruth-boxes矩形范围内的所有anchor。
B.根据目标框来判断:以groundtruth中心点为基准,设置边长为5的正方形,挑选在正方形内的所有锚框。
(2)SimOTA:精细化筛选
引入SimOTA后,AP值提升了2.3个百分点。整个筛选流程,主要分为四个阶段:
a.初筛正样本信息提取:筛选出8400个锚框中正样本锚框位置
b.Loss函数计算:针对筛选出的1000个候选检测框,和3个groundtruth计算Loss函数。
c.cost成本计算:有了reg_loss和cls_loss,就可以将两个损失函数加权相加,计算cost成本函数了,reg_loss计算方式:
pair_wise_ious_loss = -torch.log(pair_wise_ious + 1e-8)
cls_loss 计算方式:
pair_wise_cls_loss = F.binary_cross_entropy( cls_preds_.sqrt_(), gt_cls_per_image, reduction="none").sum(-1)
d.SimOTA求解:
第一步:设置候选框数量:挑选10个iou最大的候选框
第二步:通过cost挑选候选框:选cost最低的dynamic_ks个框。
第三步:过滤共用的候选框
第四步:loss计算
a.在前面精细化筛选中,使用了reg_loss和cls_loss,筛选出和目标框所对应的预测框。
因此这里的iou_loss和cls_loss,只针对目标框和筛选出的正样本预测框进行计算。
而obj_loss,则还是针对8400个预测框。
b.在Decoupled Head中,cls_output和obj_output使用了sigmoid函数进行归一化,
但是在训练时,并没有使用sigmoid函数,原因是训练时用的nn.BCEWithLogitsLoss函数,已经包含了sigmoid操作。
而在推理过程中,是使用Sigmoid函数的。