论文地址:https://arxiv.org/pdf/2203.16250.pdf
发表时间:2022
PP-YOLOE基于PP-YOLOv2改进实现,其中PP-YOLOv2的整体架构包含了具有可变形卷积的ResNet50-vd的主干,使用带有SPP层和DropBlock的PAN做neck,以及轻量级的IoU感知头。在PPYOLOv2中,ReLU激活功能用于主干,而mish激活功能用于颈部。PP-YOLOv2只为每个GT对象分配一个锚定框。除了分类损失、回归损失和目标损失外,PP-YOLOv2还使用IoU损失和IoU感知损失来提高性能。PP-YOLOE的网络结构如下所示

1、模型基本结构

1.1 结构说明

PP-YOLOE使用宽度系数α和深度系数β控制网络中backbone和neck的结构。backbone的默认宽度设置为[64、128、256、512、1024],深度设置为[3,6,6,3]。neck的默认宽度设置和深度设置分别为[192,384,768]和3。针对s、m、l和x模型的结构缩放系数如下所示

1.2 Backbone

CSPNet是YOLOv5和YOLOX中流行的backbone,基于该启发设计了RepResBlock集成了residual连接和dense连接的特点。Block的设计如下所示,先简化concat操作为add操作(a
图->b图),然后在推理阶段将b图结构转化为c图(RepResBlock的结构)。所设计的CSPRepResStage结构如图d所示,使用了ESE(Effective Squeeze and Extraction)进行通道上的attention。其实现代码可参考3.2,其中的激活函数为swish。

1.3 Neck

使用CSPPAN做Neck,其中的block也是CSPRepResStage,但是删除了shortcut和和ESE层(因为在Neck中特征已经提取的很极值了,不需要再度attention)。其中的激活函数为SiLU(Swish)=f (x) = x · sigmoid (x)

1.4 Head

为提升速度与性能,基于TOOD中的T-head进行改进,提出了ET-head。使用ESE层替换了T-head中的layer attention(?存疑,T-head也是SE层),并将回归分支的对齐简化为Distribution Focal Loss(DFL)层,其使用的的激活函数为SiLU(Swish)。通过这些改变,ET-Head在V100上提升了0.9ms。

1.5 PPYOLOE+

PPYOLOE+表示在object365中进行了预训练(其模型结构配置文件与PPYOLOE一模一样,只是在backbone中block分支中增加alpha参数)的PPYOLOE模型。两个模型在ATSSAssigner与TaskAlignedAssigner的epoch数上存在不同,ppyoloe的static_assigner_epoch为100,ppyoloe+的为30【经过预训练后ppyoloe+对ATSSAssigner的依赖降低】.

2、模型特点

2.1 锚框机制

Anchor-free(Anchor-base模型引入超参数,依赖手工设计,对不同的数据集需要单独聚类),在每个像素上放置一个锚点,为三个检测头设置GT尺寸的上届和下界。计算GT的中心,选择最近的锚点做正样本。Anchor-free方式使mAP比Anchor-base下降0.3,但是速度有所提升,具体如下表所示。

2.2 标签分配

使用TOOD中的TAL(Task Aligned Learing),显性的对齐分类最优点和位置回归最优点。注TOOD论文中,提出任务对齐头部(T-Head)和任务对齐学习(TAL)。T-head在学习任务交互特征和任务特定特征之间提供了更好的平衡,并通过任务对齐预测器学习对齐的灵活性提高,TAL通过设计的样本分配方案和任务对齐损失,明确地拉近(甚至统一)两个任务的最优锚点 TAL包含任务对齐指标、正样本选择标准,并将任务对齐指标与原先的的分类损失、回归损失进行联立[其本质就是根据任务对齐指标调节不同样本在反向传播时loss的权重,具体可以参考https://hpg123.blog.csdn.net/article/details/128725465]。PP-YOLOE其实也尝试过多种标签对齐方式,具体如下所示,可见TAL效果是最佳的。

2.3 loss设计

对于分类和定位任务,分别选择了varifocal loss(VFL)和distribution focal loss(DFL)。PP-Picodet成功将VFL和DFL语义到目标检测中。VFL与quality focal(QFL)不同,VFL使用目标评分来衡量正样本loss的权重(可提升正样本loss的贡献,使模型更多关注高质量正样本,解决了NMS过程中classification score 和 IoU/centerness score 训练测试不一致【训练时两个孤立,nms时两个联立】),两者都使用带有IOU感知的分类评分作为预测目标。整体loss设计如下所示,其中t^\hat{t}t^表示标准化的目标分数,使用ET-head提升了0.5的map
Loss=α⋅loss⁡VFL+β⋅loss⁡GIoU+γ⋅loss⁡DFL∑iNpost^L o s s=\frac{\alpha \cdot \operatorname{loss}_{V F L}+\beta \cdot \operatorname{loss}_{G I o U}+\gamma \cdot \operatorname{loss}_{D F L}}{\sum_{i}^{N_{p o s}} \hat{t}} Loss=∑iNpos​​t^α⋅lossVFL​+β⋅lossGIoU​+γ⋅lossDFL​​

DFL(distribution focal loss):为了解决bbox不灵活的问题,提出使用distribution[将迪克拉分布转化为一般分布]预测bbox[预测top、left、right、bottom]。

2.4 训练细节

使用带动量的SGD,其中momentum为0.9,权重衰减为5e-4,使用余弦学习率调度器,总共epoch为300,预热epoch为5。学习率为0.01,batchsize为64,8个32G的V100多卡训练。训练过程中使用decay=0.9998的EMA策略(可以参考)。只使用了基本的数据增强,包括随机裁剪、随机水平翻转、颜色失真和多尺度(尺度范围为320到768,步长为32),测试尺度为640。具体性能对比如下标所示。

3、关键步骤实现

3.1 网络细节与TODO的差异

ppyoloe的下采样倍数为32, 16, 8,可以修改backbone、neck、head的输出chanel,增加输出级别以适应不同尺度的目标检测。其所设计的backbone、neck、head本质上是可以替换的,只是区别于TODO(其在resnetXt101上最佳map为48.3,在resnetXt101-dcn上最佳map为51.1,预计是没有使用PAN[PAN论文中可以将MAsk R-CNN提升3-5个点],且resnetXt101与CSPReResnet存在差异[CSPReResNet在参数量上分别有CSP和REP上的优势],然后再bbox回归中ppyoloe使用的dfl和GIOU),在backbone上做了修改,在T-head上做了轻量化。

architecture: YOLOv3
norm_type: sync_bn
use_ema: true
ema_decay: 0.9998
ema_black_list: ['proj_conv.weight']
custom_black_list: ['reduce_mean']YOLOv3:backbone: CSPResNetneck: CustomCSPPANyolo_head: PPYOLOEHeadpost_process: ~CSPResNet:layers: [3, 6, 6, 3]channels: [64, 128, 256, 512, 1024]return_idx: [1, 2, 3]use_large_stem: True CustomCSPPAN:out_channels: [768, 384, 192]stage_num: 1block_num: 3act: 'swish'spp: truePPYOLOEHead:fpn_strides: [32, 16, 8]grid_cell_scale: 5.0grid_cell_offset: 0.5static_assigner_epoch: 100use_varifocal_loss: Trueloss_weight: {class: 1.0, iou: 2.5, dfl: 0.5}static_assigner:name: ATSSAssignertopk: 9assigner:name: TaskAlignedAssignertopk: 13alpha: 1.0beta: 6.0nms:name: MultiClassNMSnms_top_k: 1000keep_top_k: 300score_threshold: 0.01nms_threshold: 0.7

3.2 SMLX版本

PPYOLOE存在S、M、L、X等版本,是由depth_mult和width_mult两个参数控制模型的深度,故此可以通过修改depth_mult和width_mult得到其他版本的PPYOLOE模型。

在以下配置文件中,depth_mult用于控制layers内(backbone中stage的深度,默认为[3,6,6,3])的参数(故其最小值为1/3),width_mult用于控制channels内(stem和backbone中stages的宽度)的参数。

CSPResNet:layers: [3, 6, 6, 3]channels: [64, 128, 256, 512, 1024]return_idx: [1, 2, 3]use_large_stem: Trueuse_alpha: TrueCustomCSPPAN:out_channels: [768, 384, 192]stage_num: 1block_num: 3act: 'swish'spp: trueuse_alpha: Truedepth_mult: 0.33
width_mult: 0.50

其版backbone的实现代码为:

@register
@serializable
class CSPResNet(nn.Layer):__shared__ = ['width_mult', 'depth_mult', 'trt']def __init__(self,layers=[3, 6, 6, 3],channels=[64, 128, 256, 512, 1024],act='swish',return_idx=[1, 2, 3],depth_wise=False,use_large_stem=False,width_mult=1.0,depth_mult=1.0,trt=False,use_checkpoint=False,use_alpha=False,**args):super(CSPResNet, self).__init__()self.use_checkpoint = use_checkpointchannels = [max(round(c * width_mult), 1) for c in channels]layers = [max(round(l * depth_mult), 1) for l in layers]act = get_act_fn(act, trt=trt) if act is None or isinstance(act,(str, dict)) else actif use_large_stem:self.stem = nn.Sequential(('conv1', ConvBNLayer(3, channels[0] // 2, 3, stride=2, padding=1, act=act)),('conv2', ConvBNLayer(channels[0] // 2,channels[0] // 2,3,stride=1,padding=1,act=act)), ('conv3', ConvBNLayer(channels[0] // 2,channels[0],3,stride=1,padding=1,act=act)))else:self.stem = nn.Sequential(('conv1', ConvBNLayer(3, channels[0] // 2, 3, stride=2, padding=1, act=act)),('conv2', ConvBNLayer(channels[0] // 2,channels[0],3,stride=1,padding=1,act=act)))n = len(channels) - 1self.stages = nn.Sequential(*[(str(i), CSPResStage(BasicBlock,channels[i],channels[i + 1],layers[i],2,act=act,use_alpha=use_alpha)) for i in range(n)])self._out_channels = channels[1:]self._out_strides = [4 * 2**i for i in range(n)]self.return_idx = return_idxif use_checkpoint:paddle.seed(0)def forward(self, inputs):x = inputs['image']x = self.stem(x)outs = []for idx, stage in enumerate(self.stages):if self.use_checkpoint and self.training:x = paddle.distributed.fleet.utils.recompute(stage, x, **{"preserve_rng_state": True})else:x = stage(x)if idx in self.return_idx:outs.append(x)return outs@propertydef out_shape(self):return [ShapeSpec(channels=self._out_channels[i], stride=self._out_strides[i])for i in self.return_idx]

3.3 cls loss实现

ppdet/modeling/heads/ppyoloe_head.py#L337,默认使用varifocal_loss,

        if self.use_varifocal_loss:one_hot_label = F.one_hot(assigned_labels,self.num_classes + 1)[..., :-1]loss_cls = self._varifocal_loss(pred_scores, assigned_scores,one_hot_label)else:loss_cls = self._focal_loss(pred_scores, assigned_scores, alpha_l)assigned_scores_sum = assigned_scores.sum()if paddle.distributed.get_world_size() > 1:paddle.distributed.all_reduce(assigned_scores_sum)assigned_scores_sum /= paddle.distributed.get_world_size()assigned_scores_sum = paddle.clip(assigned_scores_sum, min=1.)loss_cls /= assigned_scores_sum

_varifocal_loss的具体实现如下,为正样本设置的权重为assigned_scores【同时训练目标也为assigned_scores】,为负样本设置的权重为alpha * pred_score.pow(gamma)。与focal loss相比【正负样本中难易样本都是对等的】,VFL中正负样本中的难易样本是不对等的。

    def _varifocal_loss(pred_score, gt_score, label, alpha=0.75, gamma=2.0):weight = alpha * pred_score.pow(gamma) * (1 - label) + gt_score * labelloss = F.binary_cross_entropy(pred_score, gt_score, weight=weight, reduction='sum')return loss

3.4 bbox loss实现

bbox loss包含边框的l1 loss、iou loss和新增的dfl loss,其使用的iou_loss 为GIoULoss()

        loss_l1, loss_iou, loss_dfl = \self._bbox_loss(pred_distri, pred_bboxes, anchor_points_s,assigned_labels, assigned_bboxes, assigned_scores,assigned_scores_sum)loss = self.loss_weight['class'] * loss_cls + \self.loss_weight['iou'] * loss_iou + \self.loss_weight['dfl'] * loss_dflout_dict = {'loss': loss,'loss_cls': loss_cls,'loss_iou': loss_iou,'loss_dfl': loss_dfl,'loss_l1': loss_l1,}

bbox loss中各类loss的关键计算代码如下,其中loss_dfl设计较为复杂,或可将bbox loss替换为SIOU、EIOU等。

            bbox_mask = mask_positive.unsqueeze(-1).tile([1, 1, 4])pred_bboxes_pos = paddle.masked_select(pred_bboxes,bbox_mask).reshape([-1, 4])assigned_bboxes_pos = paddle.masked_select(assigned_bboxes, bbox_mask).reshape([-1, 4])bbox_weight = paddle.masked_select(assigned_scores.sum(-1), mask_positive).unsqueeze(-1)loss_l1 = F.l1_loss(pred_bboxes_pos, assigned_bboxes_pos)loss_iou = self.iou_loss(pred_bboxes_pos,assigned_bboxes_pos) * bbox_weightloss_iou = loss_iou.sum() / assigned_scores_sumdist_mask = mask_positive.unsqueeze(-1).tile([1, 1, (self.reg_max + 1) * 4])pred_dist_pos = paddle.masked_select(pred_dist, dist_mask).reshape([-1, 4, self.reg_max + 1])assigned_ltrb = self._bbox2distance(anchor_points, assigned_bboxes)assigned_ltrb_pos = paddle.masked_select(assigned_ltrb, bbox_mask).reshape([-1, 4])loss_dfl = self._df_loss(pred_dist_pos,assigned_ltrb_pos) * bbox_weightloss_dfl = loss_dfl.sum() / assigned_scores_sum

其中_df_loss考虑到真实的分布通常不会距离标注的位置太远,希望网络能够快速地聚焦到标注位置附近的数值,使得他们概率尽可能大。
DFL⁡(Si,Si+1)=−((yi+1−y)log⁡(Si)+(y−yi)log⁡(Si+1))\operatorname{DFL}\left(\mathcal{S}_{i}, \mathcal{S}_{i+1}\right)=-\left(\left(y_{i+1}-y\right) \log \left(\mathcal{S}_{i}\right)+\left(y-y_{i}\right) \log \left(\mathcal{S}_{i+1}\right)\right)DFL(Si​,Si+1​)=−((yi+1​−y)log(Si​)+(y−yi​)log(Si+1​))

    def _df_loss(self, pred_dist, target):target_left = paddle.cast(target, 'int64')target_right = target_left + 1weight_left = target_right.astype('float32') - targetweight_right = 1 - weight_leftloss_left = F.cross_entropy(pred_dist, target_left, reduction='none') * weight_leftloss_right = F.cross_entropy(pred_dist, target_right, reduction='none') * weight_rightreturn (loss_left + loss_right).mean(-1, keepdim=True)

其详细理论介绍可以参考https://zhuanlan.zhihu.com/p/147691786,有益效果为:QFL和DFL的作用是正交的,他们的增益互不影响,所以结合使用更香(我们统一称之为GFL)。在基于Resnet50的backbone的ATSS(CVPR20)的baseline上1x训练无multi-scale直接基本无cost地提升了一个点,在COCO validation上从39.2 提到了40.2 AP。实际上QFL还省掉了原来ATSS的centerness那个分支,不过DFL因为引入分布表示需要多回归一些变量,所以一来一去inference的时间基本上也没什么变化。

论文解读: PP-YOLOE: An evolved version of YOLO相关推荐

  1. Paper:《A Unified Approach to Interpreting Model Predictions—解释模型预测的统一方法》论文解读与翻译

    Paper:<A Unified Approach to Interpreting Model  Predictions-解释模型预测的统一方法>论文解读与翻译 导读:2017年11月25 ...

  2. 知识图谱最新权威综述论文解读:时序知识图谱部分

    从最近一两年有关知识图谱的顶会论文中可以发现,越来越多的国内外研究者开始关注动态时序知识图谱,可见时序知识图谱已经成为了一大研究趋势,相信之后会有更多相关研究出来.因此,这期我们对综述论文的时序知识图 ...

  3. 论文解读:DETR 《End-to-end object detection with transformers》,ECCV 2020

    论文解读:DETR <End-to-end object detection with transformers>,ECCV 2020 0. 论文基本信息 1. 论文解决的问题 2. 论文 ...

  4. 论文解读|存储集中化对多地点报童问题中预期成本的影响

    论文解读|存储集中化对多地点报童问题中预期成本的影响 作者信息: 马玺渊(爱丁堡大学在读博士) 钟子俊(中国科学院大学在读硕士) 白静(东北财经大学在读博士) 1 概览 本文将通过解析 Eppen(1 ...

  5. 论文解读:《Learning Linear Transformations for Fast Image and Video Style Transfer》,CVPR 2019

    论文解读:<Learning Linear Transformations for Fast Image and Video Style Transfer>,CVPR 2019 0. 论文 ...

  6. 部署高效及泛化能力强的Osnet论文解读

    Building Computationally Efficient and Well-Generalizing Person Re-Identification Models with Metric ...

  7. Bigtable论文解读

    Bigtable论文解读 1 简介 Bigtable是一种用于管理结构化数据的分布式存储系统,旨在扩展到非常大的尺寸:对数千台商品服务器上的PB数据进行服务.Bigtable不支持完整的关系数据模型, ...

  8. 论文解读《PScL-HDeep:基于图像的蛋白质利用集成在人体组织中的亚细胞预测定位》

    论文解读<PScL-HDeep:基于图像的蛋白质利用集成在人体组织中的亚细胞预测定位> 期刊名: BRIEFINGS IN BIOINFORMATICS 期刊名缩写:BRIEF BIOIN ...

  9. 自监督学习(Self-Supervised Learning)多篇论文解读(下)

    自监督学习(Self-Supervised Learning)多篇论文解读(下) 之前的研究思路主要是设计各种各样的pretext任务,比如patch相对位置预测.旋转预测.灰度图片上色.视频帧排序等 ...

最新文章

  1. centos7 安装Git
  2. 始于TensorFlow ,终于PyTorch
  3. 【Linux】一步一步学Linux——init命令(138)
  4. 使用继承思想,去开发一款组件(element-ui collapse组件为例子)
  5. Jmeter-Ant 生成测试报告
  6. GDAL C#版本 安全透明方法问题解决方案
  7. Android中native进程内存泄露的调试技巧
  8. 数据库与表的操作之重命名、删除表
  9. 【优化算法】鲸鱼优化算法(WOA)【含Matlab源码 1243期】
  10. php实现读写ic卡,diy用PIC单片机实现的IC卡读写器
  11. 坑爹的matlab除法
  12. win7计算机自动关机设置在哪里设置方法,win7系统怎么设置每天自动关机|win7创建定时关机计划的方法...
  13. 2019年电子设计国赛综合测评回顾
  14. Gmail邮件客户端pop3和smtp服务器配置
  15. 【脚本小子狂喜】日常实用脚本推荐
  16. 计算机如何操作补考,关于计算机Excel补考试题
  17. keep-alive用法
  18. 鸟哥LINUX操作练习(8):Linux 磁盘与文件系统管理
  19. 堆和栈的区别 之 数据结构和内存
  20. Windows中文键盘消失

热门文章

  1. 小米手机qq或者微信分享时 不能选取双开应用。提示任何个人应用都无法打开此内容解决办法!
  2. 淘宝的ITEST框架
  3. 7-2 输油管道问题
  4. 预览word,excel,ppt,pdf、图片————使用vue实现
  5. 右斜杠 java chr_PHP(5.3+)中的\(反斜杠)有什么作用?
  6. OSChina 周六乱弹 ——快来看美国总统候选人怎么被打脸
  7. html表格不随字数变化,设置table中的宽度不随文字改变让其固定
  8. 带分数(全排列详解)
  9. 少年,我看你骨骼惊奇,必是练武奇才,将来维护宇宙正义
  10. OpenGL(十八)Gamma校正 色域 与 HDR