北大和阿里提出:M2Det,基于多级特征金字塔网络的目标检测器,已开源

2019 年 5 月 25 日 CVer

点击上方“CVer”,选择加"星标"或“置顶”

重磅干货,第一时间送达

原作者:Wilbur529

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

本文已授权,未经允许,不得二次转载


M2Det


M2Det: A Single-Shot Object Detector based on Multi-Level Feature Pyramid Network》



arXiv: https://arxiv.org/abs/1811.04533

github: https://github.com/qijiezhao/M2Det

作者团队:北京大学和阿里巴巴

注:AAAI 2019


1.主要贡献

  • 提出多级特征金字塔网络MLFPN

  • 基于提出的MLFPN,结合SSD,提出一种新的Single-shot目标检测模型M2Det

  • 在MS-COCO benchmark上,M2Det的单尺度版本和多尺度版本AP分别达到41.044.2

这样的结果已经很不错了.

2.介绍

为了解决目标实例的尺度变化问题,主流做法有两种:

一是在测试阶段使用图像金字塔(如Cascade RCNN),即将原始图像进行一系列缩放,毫无疑问这会大幅增加内存和计算开销; (简单说就是对图像像素上下采样)

二是在从输入图像提取出的特征金字塔上进行检测,该方法可以同时用于训练和测试阶段中,相对开销较小,易于集成,适合end-to-end。

目前常用的四种特征金字塔有:SSD型,FPN型,STDN型,还有我们介绍的MLFPN型.并总结了前三种特征金字塔的缺点,主要有两点:一是均基于分类网络作为主干提取,对目标检测任务而言特征表示可能不够(特征提取的和特征融合还是太少);二是每个feature map仅由主干网络的single level给出,不够全面(一般来说,高层特征利于进行分类,低层特征利于回归目标位置)

四个特征金字塔介绍:

  • SSD型:使用了主干网络的最后两层,再加上4个使用stride=2卷积的下采样层构成;(特征融合太少)

  • FPN型:也称为U型网络,经过上采样操作,然后对应融合相同的scale;(先上采样,再下采样融合)

  • STDN型:基于DenseNet的最后一个dense block,通过池化和scale-transfer操作来构建;

  • MLFPN型:本文新提出,整体思想是Multi-level&Multi-scale,下文详述。

为了更好地解决目标检测中尺度变化带来的问题,本文提出一种更有效的特征金字塔结构MLFPN, 其大致流程如下图所示:首先,对主干网络提取到的特征进行融合;然后通过TUM和FFM提取更有代表性的Multi-level&Mutli-scale特征;最后通过SFAM融合多级特征,得到多级特征金字塔用于最终阶段的预测。

所提方法

M2Det使用主干网络+MLFPN来提取图像特征,然后采用类似SSD的方式预测密集的包围框和类别得分,通过NMS得到最后的检测结果。

MLFPN详解

如上图所示,MLFPN主要有3个模块组成:

1)特征融合模块FFM;

2)细化U型模块TUM;

3)尺度特征聚合模块SFAM.

首先, FFMv1对主干网络提取到的浅层和深层特征进行融合,得到base feature;

其次,堆叠多个TUM和FFMv2,每个TUM可以产生多个不同scale的feature map,每个FFMv2融合base feature和上一个TUM的输出,并给到下一个TUM作为输入(更高level)。每个level的输出如下公式所述;

最后,SFAM通过scale-wise拼接和channel-wise attention来聚合multi-level&multi-scale的特征。

特征融合模块FFM

FFM用于融合M2Det中不同级别的特征,先通过1x1卷积压缩通道数,再进行拼接。具体而言:

FFMv1使用两种不同scale的feature map作为输入,所以在拼接操作之前加入了上采样操作来调整大小;

FFMv2的两个输入的scale相同,所以比较简单。两种FFM的细节如下图所示。

细化U型模块TUM

TUM使用了比FPN和RetinaNet更薄的U型网络。在上采样和元素相加操作之后加上1x1卷积来加强学习能力和保持特征平滑度。TUM中每个解码器的输出共同构成了该TUM的multi-scale输出。每个TUM的输出共同构成了multi-level&multi-scale特征,前面的TUM提供low level feature,后面的TUM提供high level feature.TUM的细节如下图所示:

尺度特征聚合模块SFAM

SFAM旨在聚合TUMs产生的多级多尺度特征,以构造一个多级特征金字塔。在first stage,SFAM沿着channel维度将拥有相同scale的feature map进行拼接,这样得到的每个scale的特征都包含了多个level的信息。然后在second stage,借鉴SENet的思想,加入channel-wise attention,以更好地捕捉有用的特征。SFAM的细节如下图所示:

网络配置

M2Det的主干网络采用VGG-16和ResNet-101

MLFPN的默认配置包含有8个TUM,每个TUM包含5个跨步卷积核5个上采样操作,所以每个TUM的输出包含了6个不同scale的特征。

在检测阶段,为6组金字塔特征每组后面添加两个卷积层,以分别实现位置回归和分类。

后处理阶段,使用soft-NMS来过滤无用的包围框。

实验部分

贴一张效率VS精度的对比图。

github:https://github.com/qijiezhao/M2Det

Preparation

the supported version is pytorch-0.4.1

  • Prepare python environment using Anaconda3.

  • Install deeplearning framework, i.e., pytorch, torchvision and other libs.

准备工作,支持pytorch版本是0.4.1和1.0

推荐使用anaconda进行配置,用以下指令安装pytorch,torchvision,opencv-python,tqdm等包;

conda install pytorch torchvision -c pytorch
pip install opencv-python,tqdm

Clone this repository.

下载M2Det工程

git clone https://github.com/qijiezhao/M2Det.git

Compile the nms and coco tools:

使用如下指令编译nms和coco工具

以下是编译结果

chensq@chensq-Ciky:~/M2Det$ sh make.sh 
running build_ext
cythoning nms/cpu_nms.pyx to nms/cpu_nms.c
/home/chensq/anaconda3/lib/python3.7/site-packages/Cython/Compiler/Main.py:367: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: /home/chensq/M2Det/utils/nms/cpu_nms.pyx
tree = Parsing.p_module(s, pxd, full_module_name)
building 'nms.cpu_nms' extension
creating build
creating build/temp.linux-x86_64-3.7
creating build/temp.linux-x86_64-3.7/nms
{'gcc': ['-Wno-cpp', '-Wno-unused-function']}
gcc -pthread -B /home/chensq/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/chensq/anaconda3/lib/python3.7/site-packages/numpy/core/include -I/home/chensq/anaconda3/include/python3.7m -c nms/cpu_nms.c -o build/temp.linux-x86_64-3.7/nms/cpu_nms.o -Wno-cpp -Wno-unused-function
nms/cpu_nms.c: In function ‘__pyx_pf_3nms_7cpu_nms_2cpu_soft_nms’:
nms/cpu_nms.c:3459:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
__pyx_t_8 = ((__pyx_v_pos < __pyx_v_N) != 0);
^
nms/cpu_nms.c:3970:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
__pyx_t_8 = ((__pyx_v_pos < __pyx_v_N) != 0);
^
gcc -pthread -shared -B /home/chensq/anaconda3/compiler_compat -L/home/chensq/anaconda3/lib -Wl,-rpath=/home/chensq/anaconda3/lib -Wl,--no-as-needed -Wl,--sysroot=/ build/temp.linux-x86_64-3.7/nms/cpu_nms.o -o /home/chensq/M2Det/utils/nms/cpu_nms.cpython-37m-x86_64-linux-gnu.so
cythoning nms/gpu_nms.pyx to nms/gpu_nms.cpp
/home/chensq/anaconda3/lib/python3.7/site-packages/Cython/Compiler/Main.py:367: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: /home/chensq/M2Det/utils/nms/gpu_nms.pyx
tree = Parsing.p_module(s, pxd, full_module_name)
building 'nms.gpu_nms' extension
{'gcc': ['-Wno-unused-function'], 'nvcc': ['-arch=sm_52', '--ptxas-options=-v', '-c', '--compiler-options', "'-fPIC'"]}
/usr/local/cuda-10.1/bin/nvcc -I/home/chensq/anaconda3/lib/python3.7/site-packages/numpy/core/include -I/usr/local/cuda-10.1/include -I/home/chensq/anaconda3/include/python3.7m -c nms/nms_kernel.cu -o build/temp.linux-x86_64-3.7/nms/nms_kernel.o -arch=sm_52 --ptxas-options=-v -c --compiler-options '-fPIC'
ptxas info : 0 bytes gmem
ptxas info : Compiling entry function '_Z10nms_kernelifPKfPy' for 'sm_52'
ptxas info : Function properties for _Z10nms_kernelifPKfPy
0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info : Used 24 registers, 1280 bytes smem, 344 bytes cmem[0], 12 bytes cmem[2]
{'gcc': ['-Wno-unused-function'], 'nvcc': ['-arch=sm_52', '--ptxas-options=-v', '-c', '--compiler-options', "'-fPIC'"]}
gcc -pthread -B /home/chensq/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/chensq/anaconda3/lib/python3.7/site-packages/numpy/core/include -I/usr/local/cuda-10.1/include -I/home/chensq/anaconda3/include/python3.7m -c nms/gpu_nms.cpp -o build/temp.linux-x86_64-3.7/nms/gpu_nms.o -Wno-unused-function
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
In file included from /home/chensq/anaconda3/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1823:0,
from /home/chensq/anaconda3/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:18,
from /home/chensq/anaconda3/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,
from nms/gpu_nms.cpp:627:
/home/chensq/anaconda3/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:15:2: warning: #warning "Using deprecated NumPy API, disable it by " "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
#warning "Using deprecated NumPy API, disable it by " \
^
g++ -pthread -shared -B /home/chensq/anaconda3/compiler_compat -L/home/chensq/anaconda3/lib -Wl,-rpath=/home/chensq/anaconda3/lib -Wl,--no-as-needed -Wl,--sysroot=/ build/temp.linux-x86_64-3.7/nms/nms_kernel.o build/temp.linux-x86_64-3.7/nms/gpu_nms.o -L/usr/local/cuda-10.1/lib64 -Wl,-R/usr/local/cuda-10.1/lib64 -lcudart -o /home/chensq/M2Det/utils/nms/gpu_nms.cpython-37m-x86_64-linux-gnu.so
cythoning pycocotools/_mask.pyx to pycocotools/_mask.c
/home/chensq/anaconda3/lib/python3.7/site-packages/Cython/Compiler/Main.py:367: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: /home/chensq/M2Det/utils/pycocotools/_mask.pyx
tree = Parsing.p_module(s, pxd, full_module_name)
building 'pycocotools._mask' extension
creating build/temp.linux-x86_64-3.7/pycocotools
{'gcc': ['-Wno-cpp', '-Wno-unused-function', '-std=c99']}
gcc -pthread -B /home/chensq/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/chensq/anaconda3/lib/python3.7/site-packages/numpy/core/include -Ipycocotools -I/home/chensq/anaconda3/include/python3.7m -c pycocotools/maskApi.c -o build/temp.linux-x86_64-3.7/pycocotools/maskApi.o -Wno-cpp -Wno-unused-function -std=c99
{'gcc': ['-Wno-cpp', '-Wno-unused-function', '-std=c99']}
gcc -pthread -B /home/chensq/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/chensq/anaconda3/lib/python3.7/site-packages/numpy/core/include -Ipycocotools -I/home/chensq/anaconda3/include/python3.7m -c pycocotools/_mask.c -o build/temp.linux-x86_64-3.7/pycocotools/_mask.o -Wno-cpp -Wno-unused-function -std=c99
gcc -pthread -shared -B /home/chensq/anaconda3/compiler_compat -L/home/chensq/anaconda3/lib -Wl,-rpath=/home/chensq/anaconda3/lib -Wl,--no-as-needed -Wl,--sysroot=/ build/temp.linux-x86_64-3.7/pycocotools/maskApi.o build/temp.linux-x86_64-3.7/pycocotools/_mask.o -o /home/chensq/M2Det/utils/pycocotools/_mask.cpython-37m-x86_64-linux-gnu.so

Prepare dataset (e.g., VOC, COCO), refer to sss.pytorch for detailed instructions.

如果需要训练,则需要参考对应链接,准备数据集

Demo展示

作者目前(20190325)提供了 M2Det512_vgg 预训练模型作为验证测试(支持结果可视化):

首先,下载预训练模型 m2det512_vgg.pth (baidu cloud) 文件. 然后新建一个文件夹 weights/. 将模型文件移至该目录下;

运行如下指令即可对它自带的图片做测试了。

python demo.py -c=configs/m2det512_vgg.py -m=weights/m2det512_vgg.pth --show

如果弹出如下错误:

chensq@chensq-Ciky:~/M2Det$ python demo.py -c=configs/m2det512_vgg.py -m=weights/m2det512_vgg.pth --show
Traceback (most recent call last):
File "demo.py", line 8, in <module>
from configs.CC import Config
File "/home/chensq/M2Det/configs/CC.py", line 7, in <module>
from addict import Dict
ModuleNotFoundError: No module named 'addict'

表示你未安装addict库,用下面指令进行安装(基于我用anaconda来配置的方式)

pip install addict

再次运行,如果弹出如下错误;

表示你未安装termcolor,同理用如下指令安装即可;

pip install termcolor

如下,运行成功了!

chensq@chensq-Ciky:~/M2Det$ python demo.py -c=configs/m2det512_vgg.py -m=weights/m2det512_vgg.pth --show
----------------------------------------------------------------------
| M2Det Demo Program |
----------------------------------------------------------------------
The Anchor info:
{'feature_maps': [64, 32, 16, 8, 4, 2], 'min_dim': 512, 'steps': [8, 16, 32, 64, 128, 256], 'min_sizes': [30.72, 76.8, 168.96, 261.12, 353.28, 445.44], 'max_sizes': [76.8, 168.96, 261.12, 353.28, 445.44, 537.6], 'aspect_ratios': [[2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3]], 'variance': [0.1, 0.2], 'clip': True}
===> Constructing M2Det model
Loading resume network...
===> Finished constructing and loading model
pos:(2.0,146.5,36.2,273.8), ids:person, score:0.972
pos:(41.9,124.6,118.1,344.2), ids:person, score:0.913
pos:(123.3,142.2,181.3,355.8), ids:person, score:0.667
pos:(94.8,148.4,134.6,264.5), ids:person, score:0.506
pos:(43.7,141.8,70.7,191.0), ids:person, score:0.447
pos:(94.2,145.9,111.8,166.7), ids:person, score:0.128
pos:(38.6,127.3,111.5,342.4), ids:person, score:0.124
pos:(32.5,146.8,65.7,286.9), ids:person, score:0.120
.....
pos:(878.1,82.3,891.9,146.8), ids:tie, score:0.006
pos:(578.5,96.9,595.2,142.5), ids:tie, score:0.003

测试中其中一张图片检测效果如下;终端打印出目标物的坐标,id,置信度等信息;

你也可以运行实时的demo,它会调用你的摄像头,如果有多个相机,你可以通过传入参数--cam=相机ID 来指定相机;如下指令是调用摄像头的,我指定了相机ID=0;

python demo.py -c=configs/m2det512_vgg.py -m=weights/m2det512_vgg.pth --show --cam=0

测试效果如上,大致FPS : 约为4.5吧,这是GPU上的结果~~~~我的电脑是GeForce 1050ti的GPU

       pos:(179.8,146.8,665.3,473.3), ids:person, score:0.002
pos:(324.1,302.9,372.3,368.0), ids:cell_phone, score:0.372
pos:(325.1,302.0,375.9,370.7), ids:cell_phone, score:0.035
pos:(321.7,304.2,366.5,366.8), ids:cell_phone, score:0.006
pos:(148.5,94.4,628.4,475.8), ids:person, score:0.992
pos:(208.2,119.8,650.3,469.3), ids:person, score:0.089
pos:(128.1,101.0,622.1,472.6), ids:person, score:0.011
pos:(176.7,158.0,613.0,487.2), ids:person, score:0.002
pos:(121.1,94.4,623.6,471.6), ids:person, score:0.994
pos:(116.6,103.3,621.6,468.5), ids:person, score:0.041
pos:(151.7,103.7,597.4,467.2), ids:person, score:0.002
...............


CVer-目标检测交流群


扫码添加CVer助手,可申请加入CVer-目标检测交流群。一定要备注:目标检测+地点+学校/公司+昵称(如目标检测+上海+上交+卡卡),不根据格式申请,一律不通过。

▲长按加群


这么硬的论文精读,麻烦给我一个在在看


▲长按关注我们

麻烦给我一个在看

登录查看更多
0

相关内容

基于改进卷积神经网络的短文本分类模型
专知会员服务
26+阅读 · 2020年7月22日
深度学习目标检测方法及其主流框架综述
专知会员服务
148+阅读 · 2020年6月26日
3D目标检测进展综述
专知会员服务
193+阅读 · 2020年4月24日
专知会员服务
164+阅读 · 2020年4月21日
CVPR2020 | 商汤-港中文等提出PV-RCNN:3D目标检测新网络
专知会员服务
44+阅读 · 2020年4月17日
【CVPR2020-百度】用于视觉识别的门控信道变换
专知会员服务
13+阅读 · 2020年3月30日
【ICLR-2020】网络反卷积,NETWORK DECONVOLUTION
专知会员服务
39+阅读 · 2020年2月21日
总结-CNN中的目标多尺度处理
极市平台
17+阅读 · 2019年7月24日
最全综述 | 图像目标检测
计算机视觉life
31+阅读 · 2019年6月24日
FCOS: 最新的one-stage逐像素目标检测算法
极市平台
15+阅读 · 2019年4月14日
目标检测论文阅读:DetNet
极市平台
9+阅读 · 2019年1月28日
《pyramid Attention Network for Semantic Segmentation》
统计学习与视觉计算组
44+阅读 · 2018年8月30日
基于深度学习的图像目标检测(下)
机器学习研究会
12+阅读 · 2018年1月1日
论文 | 基于CNN的目标检测算法
七月在线实验室
9+阅读 · 2017年12月7日
专栏 | CVPR 2017论文解读:特征金字塔网络FPN
机器之心
8+阅读 · 2017年7月25日
S4Net: Single Stage Salient-Instance Segmentation
Arxiv
10+阅读 · 2019年4月10日
Arxiv
6+阅读 · 2018年7月9日
Arxiv
8+阅读 · 2018年5月17日
Arxiv
5+阅读 · 2018年4月17日
Arxiv
3+阅读 · 2018年3月5日
Arxiv
7+阅读 · 2018年1月24日
Arxiv
5+阅读 · 2016年12月29日
VIP会员
相关VIP内容
基于改进卷积神经网络的短文本分类模型
专知会员服务
26+阅读 · 2020年7月22日
深度学习目标检测方法及其主流框架综述
专知会员服务
148+阅读 · 2020年6月26日
3D目标检测进展综述
专知会员服务
193+阅读 · 2020年4月24日
专知会员服务
164+阅读 · 2020年4月21日
CVPR2020 | 商汤-港中文等提出PV-RCNN:3D目标检测新网络
专知会员服务
44+阅读 · 2020年4月17日
【CVPR2020-百度】用于视觉识别的门控信道变换
专知会员服务
13+阅读 · 2020年3月30日
【ICLR-2020】网络反卷积,NETWORK DECONVOLUTION
专知会员服务
39+阅读 · 2020年2月21日
相关资讯
总结-CNN中的目标多尺度处理
极市平台
17+阅读 · 2019年7月24日
最全综述 | 图像目标检测
计算机视觉life
31+阅读 · 2019年6月24日
FCOS: 最新的one-stage逐像素目标检测算法
极市平台
15+阅读 · 2019年4月14日
目标检测论文阅读:DetNet
极市平台
9+阅读 · 2019年1月28日
《pyramid Attention Network for Semantic Segmentation》
统计学习与视觉计算组
44+阅读 · 2018年8月30日
基于深度学习的图像目标检测(下)
机器学习研究会
12+阅读 · 2018年1月1日
论文 | 基于CNN的目标检测算法
七月在线实验室
9+阅读 · 2017年12月7日
专栏 | CVPR 2017论文解读:特征金字塔网络FPN
机器之心
8+阅读 · 2017年7月25日
相关论文
S4Net: Single Stage Salient-Instance Segmentation
Arxiv
10+阅读 · 2019年4月10日
Arxiv
6+阅读 · 2018年7月9日
Arxiv
8+阅读 · 2018年5月17日
Arxiv
5+阅读 · 2018年4月17日
Arxiv
3+阅读 · 2018年3月5日
Arxiv
7+阅读 · 2018年1月24日
Arxiv
5+阅读 · 2016年12月29日
Top
微信扫码咨询专知VIP会员