前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >YOLOX | MMDetection 复现保姆级解析

YOLOX | MMDetection 复现保姆级解析

作者头像
OpenMMLab 官方账号
发布2022-01-17 15:48:16
8980
发布2022-01-17 15:48:16
举报
文章被收录于专栏:OpenMMLab

首先感谢本次参与YOLOX算法复现工作的社区贡献者们 (Github 账号名):

HAOCHENYE、xiaohu2015、zhiqwang、HsLOL、shinya7y

最近 YOLOX 火爆全网,速度和精度相比 YOLOv3、v4 都有了大幅提升,并且提出了很多通用性的 trick,同时提供了部署相关脚本,实用性极强。

近期,MMDetection 开源团队成员也组织进行了相关复现。通过与社区成员的协同开发,不仅让复现过程更加高效,而且社区成员在参与过程中可以不断熟悉算法,熟悉 MMDetection 开发模式。

后续我们也会再次组织相关复现活动,希望社区成员积极参与,共同成长,共同打造更加优异的目标检测框架。

本文内容

1. YOLOX 算法简介

2.YOLOX 复现流程全解析

1. YOLOX 算法简介

官方开源地址:

https://github.com/Megvii-BaseDetection/YOLOX

MMDetection 开源地址(欢迎 star):

GitHub - open-mmlab/mmdetection: OpenMMLab Detection Toolbox and Benchmark

复现相关 projects:

Support of YOLOX · open-mmlab/mmdetection

YOLOX 的主要特性可以归纳为:

· Anchor-free,无需设计 anchor,更少先验,减少复杂超参,推理较高效;

· 提出了 Decoupled Head,参考 FCOS 算法设计解耦了分类和回归分支,同时新增 objectness 回归分支;

· 为了加快收敛以及提高性能,引入了 SimOTA 标签分配策略,其包括两部分 Multi positives 和 SimOTA,Multi positives 可以简单的增加每个 gt 所需的正样本数,SimOTA 基于 CVPR2021 最新的 OTA 算法,采用最优传输理论全局分配每个 gt 的正样本,考虑到 OTA 带来的额外训练代价,作者提出了简化版本的 OTA ,在长 epoch 训练任务中 SimOTA 和 OTA 性能相当,且可以极大的缩小训练代价;

· 参考 YOLOV4 的数据增强策略,引入了 Mosaic 和 MixUp,并且在最后 15 个 epoch 时候关闭这两个数据增强操作,实验表明可以极大地提升性能;

· 基于上述实践,参考 YOLOV5 网络设计思路,提出了 YOLOX-Nano、YOLOX-Tiny、YOLOX-S、YOLOX-M、YOLOX-L 和 YOLOX-X 不同参数量的模型。

2. YOLOX 复现流程全解析

本节目录

2.1 推理精度对齐

2.2 训练精度对齐

2.2.1 优化器和学习率调度器

2.2.2 EMA策略

2.2.3 Dataset

2.2.4 Loss

2.2.5 其他训练 trick

由于篇幅有限,本篇文章将详细呈现【2.1 推理精度对齐】部分,其余内容请关注知乎【OpenMMLab】同步推出的完整内容 ~

本期知乎链接:

https://zhuanlan.zhihu.com/p/398545304

我们简单将 YOLOX 复现过程拆分为 3 个步骤,分别是:(1)推理精度对齐(2)训练精度对齐(3)重构。

#(偷偷注释掉)为了方便将官方开源权重迁移到 MMDetection 中,在推理精度对齐过程中,我们没有修改任何模型代码,而且简单的复制开源代码,分别插入 MMDetection 的 backbone 和 head 文件夹下,这样就只需要简单的替换模型 key 即可重复段落请忽略小编已哭晕。

2.1 推理精度对齐

为了方便将官方开源权重迁移到 MMDetection 中,在推理精度对齐过程中,我们没有修改任何模型代码,而且简单的复制开源代码,分别插入 MMDetection 的 backbone 和 head 文件夹下,这样就只需要简单的替换模型 key 即可。

一个特别需要注意的点:BN 层参数不是默认值 eps=1e-5, momentum=0.1,而是eps=1e-3, momentum=0.03,这个应该是直接参考 YOLOV5。

排除了模型方面的问题(后处理策略我们暂时也没有改),对齐推理精度核心就是分析图片前处理代码。其处理流程非常简单——

代码语言:javascript
复制
# 前处理核心操作
def preproc(image, input_size, mean, std, swap=(2, 0, 1)):
    # 预定义输出图片大小
    padded_img = np.ones((input_size[0], input_size[1], 3)) * 114.0
    
    # 保持宽高比的 resize
    img = np.array(image)
    r = min(input_size[0] / img.shape[0], input_size[1] / img.shape[1])
    resized_img = cv2.resize(
        img,
        (int(img.shape[1] * r), int(img.shape[0] * r)),
        interpolation=cv2.INTER_LINEAR,
    ).astype(np.float32)
    
    # 右下 padding
    padded_img[: int(img.shape[0] * r), : int(img.shape[1] * r)] = resized_img
    
    # bgr -> rgb
    padded_img = padded_img[:, :, ::-1]
    
    # 减均值,除方差
    padded_img /= 255.0
    if mean is not None:
        padded_img -= mean
    if std is not None:
        padded_img /= std
    padded_img = padded_img.transpose(swap)
    return padded_img, r

滑动可见完整代码

可以发现,其前处理流程比较简单:先采用保持宽高比的 resize,然后右下 padding 成指定大小输出,最后是归一化。

在 MMDetection 中可以直接通过修改配置文件来支持上述功能:

代码语言:javascript
复制
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(
        type='MultiScaleFlipAug',
        img_scale=img_scale,
        flip=False,
        transforms=[
            dict(type='Resize', keep_ratio=True),
            dict(type='RandomFlip'),
            dict(type='Pad', size=(640, 640), pad_val=114.0),
            dict(type='Normalize', **img_norm_cfg),
            dict(type='DefaultFormatBundle'),
            dict(type='Collect', keys=['img'])
        ])
]

相关的后处理阈值为:

代码语言:javascript
复制
test_cfg=dict(  
    score_thr=0.001, 
    nms=dict(type='nms', iou_threshold=0.65)))

分别对 YOLOX-S 和 YOLOX-Tiny 模型权重在官方源码和 MMDetection 中进行评估,验证是否对齐,结果如下:

注意:由于官方开源代码一直处于更新中,现在下载的最新权重,可能 mAP 不是上表中的值。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenMMLab 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档