深入浅出Yolo系列之Yolox核心基础完整讲解 - 知乎在Yolov4、Yolov5刚出来时,大白就写过关于Yolov3、Yolov4、Yolov5的文章,并且做了一些讲解的视频,反响都还不错。 而从 2015年的Yolov1,2016年Yolov2,2018年的Yolov3,再到2020年的Yolov4、Yolov5,Yolo系列也…https://zhuanlan.zhihu.com/p/397993315如何评价旷视开源的YOLOX,效果超过YOLOv5? - 知乎https://www.zhihu.com/question/473350307当代目标检测中yolov1的影子 - 知乎影子1:confidence vs IoU prediction branch 这篇文章里的Soft-IoUlayer: https://arxiv.org/pdf/1904.00853.pdf和PAA里的IoU Prediction Branch: https://arxiv.org/pdf/2007.08103.pdf与yolo的confidence branc…https://zhuanlan.zhihu.com/p/266077719
centernet和yolov1思路接近,yolov5的正负样本分配则和之前的策略都不一样,但是感觉yolov5这种正负样本分配才更科学一点,比atss还要好一点,atss说是自适应,但是其实只是iou阈值的自适应,免去了对超参数的设定,其根据l2距离筛选anchor,iou计算均值和方差其实还是不够好,只是fpn分层预测的一个替代方案,看到yolov5的simota确实做的更好,就像作者说的的, Anchor free and dynamic label assignment are all you need.非常建议看江大白版的simota,讲的非常细,看的很明白。作者对文章的定义是report,因此和v4类似,基本都是一些实验分析。我也很认同作者在知乎的分析,目标检测发展到今天,确实很难界定fcos和yolo了,事实上,在真实场景下,确实取决于很多因素。
1.introduction
yolox的版本也很多,可以看到有基于yolov3-spp版本改的,也有基于v5版本改的,v5的效果是好于v4的,两者是相互借鉴吧,但是scaled-yolov4是比yolov5要略好一点的。
目标检测的方案多集中在anchor-free detector,advanced label assignment strategies,end-to-end(NMS) detector,但是这些目前都没有引入到yolo系列,yolo中仍然是anchor-based detector和人工设计的正负样本分配规则(v1-v4的最大iou,v5的wh shape规则,跨层预测和三个网格分配正样本)。yolox用yolov3-spp做基础改进,v4、v5可能对anchor-based的流程有点过度优化了,yolox-darknet53将yolov3提高到47.3%,比u版的yolov3的44.3%高,用有csp和pan的yolov5时,yolox-l在640下能到50%,在小模型上还有yolox tiny和yolox nano。
2.yolox
2.1 yolox-darknet53
implementation details
500 epochs with 5 warmup,SGD,We use a learning rate of lr x bs/64 (linear scaling), with a initial lr = 0.01 and the cosine lr schedule. The weight decay is 0.0005 and the SGD momentum is 0.9. 默认8卡,
yolov3 baseline
yolov3-spp,ema,cosine lr schedule,iou loss,iou-aware branch(这个分支在v3中应该是边界框置信度分支,换成iou分支后可以涨点),bce loss for cls and obj分支,iou loss for reg分支。这里要注意在v3的损失上对于obj是有obj,reg,cls三个损失的,对no obj,是有noobj分支的,obj和noobj是边界框置信度损失,只用了randomhorizontalflip,colorjitter and multi-scale做数据增强,没用randomresizedcrop,因为发现randomresizedcrop和mosaic有些重合。使用这些基准的措施,yolo就可以涨到38.5%.
decoupled head
yolov1-4中用的都是coupled head,传统的目标检测基本都是decoupled head,如下所示,yolo是将cls,reg和obj全放在一个向量中,而decoupled head将这三组信息解耦到三个head上去,yolox用decoupled head替换coupled head之后,收敛速度提升了,图中蓝线的收敛速度快很多,作者在原始yolo上将coupled head换成decoupled head之后,map上升,在end-to-end yolo上更换decoupled之后,map上升很多,这也是作者之所以发现decoupled head比coupled head的一个实验由头。这几组实验说明之前yolo系列的检测头是不合理的,损害了性能,但是decoupled head会增加运算复杂度,但经过权衡速度和性能上的得失,最终使用1个1x1 的卷积先进行降维,并在分类和回归分支里各使用了 2个3x3 卷积,最终调整到仅仅增加一点点参数,YOLOX 在 s,m,l,x 模型速度上的轻微下降也全源自于此。表面上看,解耦检测头提升了 YOLOX 的性能和收敛速度。
代码如下:
for i in range(len(in_channels)):
self.stems.append(
BaseConv(
in_channels=int(in_channels[i] * width),
out_channels=int(256 * width),
ksize=1,
stride=1,
act=act,
)
)
self.cls_convs.append(
nn.Sequential(
*[
Conv(
in_channels=int(256 * width),
out_channels=int(256 * width),
ksize=3,
stride=1,
act=act,
),
Conv(
in_channels=int(256 * width),
out_channels=int(256 * width),
ksize=3,
stride=1,
act=act,
),
]
)
)
self.reg_convs.append(
nn.Sequential(
*[
Conv(
in_channels=int(256 * width),
out_channels=int(256 * width),
ksize=3,
stride=1,
act=act,
),
Conv(
in_channels=int(256 * width),
out_channels=int(256 * width),
ksize=3,
stride=1,
act=act,
),
]
)
)
self.cls_preds.append(
nn.Conv2d(
in_channels=int(256 * width),
out_channels=self.n_anchors * self.num_classes,
kernel_size=1,
stride=1,
padding=0,
)
)
self.reg_preds.append(
nn.Conv2d(
in_channels=int(256 * width),
out_channels=4,
kernel_size=1,
stride=1,
padding=0,
)
)
self.obj_preds.append(
nn.Conv2d(
in_channels=int(256 * width),
out_channels=self.n_anchors * 1,
kernel_size=1,
stride=1,
padding=0,
)
)
yolox的代码写的一般,先是一个stem 1x1conv,降维,后面接两个3x3conv,最后面再接一个预测的conv。
strong data augmentation
添加了mosaic和mixup,Mosaic 经过 YOLOv5 和 v4 的验证,证明其在极强的 baseline 上能带来显著涨点。我们组早期在其他研究上发现,为 Mosaic 配上 Copypaste,依然有不俗的提升。组内的共识是:当模型容量足够大的时候,相对于先验知识(各种 tricks,hand-crafted rules ),更多的后验(数据/数据增强)才会产生本质影响。不过我们实现的 Mixup,没有原始 Mixup 里的 Bernoulli Distribution 和 Soft Label ,有的仅是 0.5 的常数透明度和 Copypaste 里提到的尺度缩放 ( scale jittering )。 YOLOX 里的 Mixup 有如此明显的涨点,大概是因为它在实现和涨点原理上更接近 Copypaste,而不是原版 Mixup。Data Augmentation 里面需要强调的一点是: 要在训练结束前的15个 epoch 关掉 Mosaic 和Mixup ,这对于 YOLOX 非常重要。可以想象,Mosaic+Mixup 生成的训练图片,远远脱离自然图片的真实分布,并且 Mosaic 大量的 crop 操作会带来很多不准确的标注框。如下图:
此外由于使用了大量的数据增强,再使用imagenet预训练不再有益,因此yolox均是train from scratch。
anchor-free
yolox的anchor-free改进非常简单,将预测框在每个位置从3减到1,每个位置预测4个值,即网格左上角偏移量,以及预测框的高度和宽度,将每个对象的中心位置指定为正样本,并预先定义比例范围以指定对象的fpn级别(fpn分层预测)。这个anchor-free方案听起来和fcos是一样的。
multi positives
为了保持和yolov3的正负样本分配规则一致,上述的anchor-free版本仅为每个对象选择一个正样本(中心位置),这同时会忽略很多高质量预测,优化这些高质量预测也可能会带来有益的梯度,这会缓解训练期间正负采样的极端不平衡,将中心的3x3区域作为正样本区域,有点像fcos的中心采样,和yolov5的三个临近区域也类似,map可以进一步提高。
simota
这一块是个重点,也是最终的yolox版本和之前的yolo版本区别最大的一块,也是之所以能够涨点的核心,simota直接涨了2.3%,这里江大白版本的知乎解析说的非常好。
如上所示这个图,最终输出是8400*85,这是三个特征图总共的输出,85是指80+1+4,是类别和边界框置信度以及位置坐标的回归,前面的8400是指在输入为640*640的前提下,一共有8400个网格单元,如果是anchor-free的方法的话,anchor-based,每个网格3个anchor的话,还要乘上3才是所有的样本数。8400中有正样本也有负样本,simota就是要给yolo分配正负样本,在之前的分析中也解释了正负样本的定义和分配是整个目标检测的核心,在atss中涨点就靠这个。
simota一共需要两步,1.初步筛选,2.simota
1.初步筛选
初步筛选中第一条是根据中心点判断:寻找预测框中心点落在gt范围内的所有anchor。第二条是根据目标框来判断:以gt中心点为基准,设置边长为5的正方形,挑选在正方形内的所有预测框。不过由于是anchor-free的方法,必须明确一点,上述所有的预测框都是8400中的一个维度的向量,它不是anchor,或者说一个网格单元就是一个anchor,和fcos一个思路。
2.simota
上面是初步筛选,假设一张图上3个gt,检测类别是2,共有8400个预测框,经过初步筛选之后留下了1000个预测框。
2.1 初筛正样本信息提取
在筛选出来的1000个正样本预测框位置都可以在8400中一一对应,根据位置mask可以将网络预测的候选框位置bbox_preds,维度为(1000,4),前背景目标分数obj_preds,维度为(1000,1),类别分数cls_preds,维度为(1000,2)。
2.2 loss计算
针对筛选出来的1000个候选预测框和3个gt计算loss,1.可以计算出3个gt和000个预测框,每个框相互之间的iou信息pair_wise_ious,维度为(3,1000),再通过-torch.log计算,得到位置损失,即pair_wise_iou_loss,2.是综合类别信息和目标信息的loss值,pair_wise_cls_loss,这里的pair_wise_cls_loss实际上还用到了obj_preds,有点像fcos中的centerness,将边界框置信度乘到了类别的条件概率上。
2.3 cost计算
有了reg_loss和cls_loss,可以将两个损失相加获取cost。
2.4 simota
2.4.1 设置候选框数量
此处设置候选框数量为10,从前面的pair_wise_ious中,给每个gt挑选出10个iou最大的预测框,此处的topk_ious的维度为(3,10),这里的10是个超参,有点像atss中的topk,其实选候选框的原理也基本相似,和正样本相关的要不然是l2距离近的,要不然就是iou大的。
2.4.2 通过cost挑选候选框
下面通过topk_ious动态选择候选框。这里的topk_ious是3个目标框中各自对应的最大iou的10个预测框。
此时,我们知道,gt1和gt3给他们分配3个候选框,gt2分配4个候选框,至于分配的个数由iou之和决定,atss中对于gt的正负样本由fpn各层中和gt中心l2距离近的预测框组成,topk=9,每层选9个,最后计算总共的anchor对应的iou的均值标准差之和,大于和的正样本,小于和的负样本,此时分配多少个也是取决于gt和10个预测框的iou之和,其实也有道理,相当于最大的是个周边框之和,就是iou小的对和的影响小,iou大的对和的影响大,他其实在算极差中的头部框,换句话说,用attention或者centernet中高斯核的思想来说,就是如果iou是权重值,大家都是1x1测框,那么在中心点附近的10个框中,离的近的给了一大的权重,离的远的给了一个小的权重。
确定了分几个,下面要怎么分,分哪个框?什么标准,这时就要利用前面计算的cost值,即(3,1000)的损失函数,在for训练中,针对每个gt挑选相应的cost最低的一些候选框,标准就是cost最小的值,在matching_matrix中,每行1的个数就是改行选出来对应的正样本的索引位置,gt1有3个1,gt2有4个1.
2.4.3 过滤共有的候选框
看上面matching_matrix有个问题,发现gt1和gt2共用了某个预测框,注意纵坐标确实有3个gt,但是横坐标却只有一组1000个预选框,3个gt都是在1000中选,一个候选框肯定不能对应两个gt,一个gt可以有多个预选框去预测,但是一个候选框对应多个gt是绝对不允许的,这也是fcos的分层fpn核心要处理的问题,多个像素点重叠问题。怎么处理这个问题呢?保留cost最小的,如上图中第五列中gt1和gt2共享的这个预测框,还要比较gt和这个预测框的cost值,保留最小的cost的值所对应的gt的预测框,注意cost的值是(3,1000)的,刚好是一一对应的。
首先将matching_matrix中的列进行相加,值大于1的就说明有共用情况,
将共用情况的cost值找出,假设gt1的是0.4,gt2的是0.3,
则将预测框分配给cost最小的gt。至此simota就全部结束了,这个方法实现了anchor-free和正负样本动态分配,正如作者所说,Anchor free and dynamic label assignment are all you need.下面放一下作者在知乎上的关于这块的思考。
至于为什么 Anchor Free 现在可以上 YOLO ,并且性能不降反升,这与样本匹配有密不可分的联系。与 Anchor Free 比起来,样本匹配在业界似乎没有什么关注度。但是一个好的样本匹配算法可以天然缓解拥挤场景的检测问题( LLA、OTA 里使用动态样本匹配可以在 CrowdHuman 上提升 FCOS 将近 10 个点),缓解极端长宽比的物体的检测效果差的问题,以及极端大小目标正样本不均衡的问题。甚至可能可以缓解旋转物体检测效果不好的问题,这些问题本质上都是样本匹配的问题。在我们的认知中,样本匹配有 4 个因素十分重要:
1) loss/quality/prediction aware :基于网络自身的预测来计算 anchor box 或者 anchor point 与 gt 的匹配关系,充分考虑到了不同结构/复杂度的模型可能会有不同行为,是一种真正的 dynamic 样本匹配。而 loss aware 后续也被发现对于 DeTR 和 DeFCN 这类端到端检测器至关重要。与之相对的,基于 IoU 阈值 /in Grid(YOLOv1)/in Box or Center(FCOS) 都属于依赖人为定义的几何先验做样本匹配,目前来看都属于次优方案。
2) center prior : 考虑到感受野的问题,以及大部分场景下,目标的质心都与目标的几何中心有一定的联系,将正样本限定在目标中心的一定区域内做 loss/quality aware 样本匹配能很好地解决收敛不稳定的问题。
3) 不同目标设定不同的正样本数量( dynamic k ):我们不可能为同一场景下的西瓜和蚂蚁分配同样的正样本数,如果真是那样,那要么蚂蚁有很多低质量的正样本,要么西瓜仅仅只有一两个正样本。Dynamic k 的关键在于如何确定k,有些方法通过其他方式间接实现了动态 k ,比如 ATSS、PAA ,甚至 RetinaNet ,同时,k的估计依然可以是 prediction aware 的,我们具体的做法是首先计算每个目标最接近的10个预测,然后把这个 10 个预测与 gt 的 iou 加起来求得最终的k,很简单有效,对 10 这个数字也不是很敏感,在 5~15 调整几乎没有影响。
4) 全局信息:有些 anchor box/point 处于正样本之间的交界处、或者正负样本之间的交界处,这类 anchor box/point 的正负划分,甚至若为正,该是谁的正样本,都应充分考虑全局信息。
我们在 CVPR 21 年的工作 OTA 充分考虑到了以上 4 点,通过把样本匹配建模成最优传输问题,求得了全局信息下的最优样本匹配方案,欢迎大家阅读原文。但是 OTA 最大的问题是会增加约 20~25 %的额外训练时间,对于动辄 300epoch 的 COCO 训练来说是有些吃不消的,此外 Sinkhorn-Iter 也会占用大量的显存,所以在 YOLOX 上,我们去掉了 OTA 里的最优方案求解过程,保留上面 4 点的前 3 点,简而言之: loss aware dynamic top k。由于相对 OTA 去掉了Sinkhorn-Iter 求最优解的过程,我们把 YOLOX 采用的样本匹配方案称为 SimOTA ( Simplified OTA )。
end-to-end yolo
会降低性能和推断速度。
2.2 other backbone
整体来看,yolox的核心还是在正负样本分配上,simota是其性能出色的一个非常重要的因素,通常来说数据增强和一些网络结构调整肯定是有效的,比如moscia,mixup等几何增强,spp,pan等网络上的增强,但是正负样本改造还是最为核心的,yolo之所以改改就能上升还是因为其正负样本分配本身就是简单且有效的,yolox的decoupled head,simota都是很有效的手段。
版权声明:本文为CSDN博主「Kun Li」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012193416/article/details/122195873
暂无评论