目标检测相关笔记(四)—— EfficientDet

目标检测相关笔记(四)—— EfficientDet

最近抽时间把近期顶会上值得关注的目标检测论文简单浏览了一下,对于感兴趣的算法也会过一下代码,详细了解一下具体实现。借着周末有时间在这里简单整理一下,时间有限,能整理一篇是一篇。
论文链接:https://arxiv.org/abs/1911.09070
官方源码:https://github.com/google/automl/tree/master/efficientdet
pytorch版复现代码:https://github.com/zylo117/Yet-Another-EfficientDet-Pytorch
本文介绍的代码为pytorch版复现代码:全网第一SoTA成绩却朴实无华的pytorch版efficientdet

概述

发表在CVPR2020上的一篇目标检测新标杆,去年年底刚出的时候就引起了广泛的关注,当时简单看了一下,性能的确没得说,但是参数众多,只能说丹炼的好!
算法主要提出了两个创新点:

  1. BiFPN:新的不同特征层融合方法
  2. Compound Scaling:模型复合缩放的方法
    算法的backbone则是ICML 2019 Oral 的Efficient。

BiFPN

目标检测相关笔记(四)—— EfficientDet_第1张图片

上图中分别是几种不同特征层之间的融合方式。其中,FPN应该是最经典的一种方法,在P3到P7使用一种自上而下的方式来进行融合,其中P3代表下采样3次,P7代表下采样7次。在融合过程中,采用的方法是将小的特征图上采样后与大的特征图相加。PANet则是在FPN的基础上添加了一条自底向上的分支进行融合。后来BAS-FPN则是使用了NAS自动搜索合适的融合方式。
在EfficientDet中,作者在PANet的基础上进行改进:

  1. 假设只有一个输入的节点相对不太重要,因此,移除掉只有一个输入的节点;
  2. 在相同level的输入和输出节点之间连一条边,使其能够融合更多特征;
  3. 在以上的基础上重复多次,也就是模型的Compound Scaling;
    同时,在BiFPN的基础上,作者提出了不同特征层融合的方式,即不再是简单相加,而是添加了权重进行融合。这是因为作者观察到不同特征层对应不同的分辨率,因此他们对输出特征层的贡献也就不同,所以在特征融合过程中,让网络自己学习每个特征层的重要程度作为权重,再进行特征融合。
    其中,作者比较了三种加权融合方式:
    1.方法1即直接学习wi,可以为一个scalar(feature维度),vector(channel维度)或者多维的tensor(pixel维度),但是,由于没有归一化,会导致训练不稳定,难以学习。
    在这里插入图片描述

2.方法2采用softmax进行归一化,但是指数运算导致计算复杂。
在这里插入图片描述

3.方法3也就是最终采用的方法如下,实验表明该方法在相同效果的前提下速度更快。
在这里插入图片描述

最终的BiFPN计算方式如下:
目标检测相关笔记(四)—— EfficientDet_第2张图片

Compound Scaling

结合EfficientNet中提出的联合调整策略,本文提出目标检测框架的联合调整策略,用复合系数φ统一调整目标检测的backbone、BiFPN层数、prediction网络以及分辨率。以下就是本文众多参数的介绍,具体的计算公式可以查阅论文。最终EfficientDet把 EfficientNet 拿来做 backbone,这样从 EfficientNet B0 ~ B6,就可以控制 Backbone 的规模;neck 部分,BiFPN 的 channel 数量、重复的 layer 数量也可以控制;此外还有 head 部分的层数,以及 输入图片的分辨率,这些组成了 EfficientDet 的 scaling config 。
目标检测相关笔记(四)—— EfficientDet_第3张图片
最终的网路结构如下图:
目标检测相关笔记(四)—— EfficientDet_第4张图片
论文提供的指标如下:可以看到指标还是相当高的。
目标检测相关笔记(四)—— EfficientDet_第5张图片

Pytorch版本代码

目标检测相关笔记(四)—— EfficientDet_第6张图片

数据集:COCO格式数据
需要的环境: pycocotools numpy opencv-python tqdm tensorboard tensorboardX pyyaml webcolors torch == 1.4.0 torchvision == 0.5.0
注意修改projects/coco.yml文件(如果自己的数据集叫其他名字,比如:abc,则应新建abc.yml)

project_name: coco  # also the folder name of the dataset that under data_path folder
train_set: train2017
val_set: val2017
num_gpus: 1

# mean and std in RGB order, actually this part should remain unchanged as long as your dataset is similar to coco.
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]

# this is coco anchors, change it if necessary
anchors_scales: '[2 ** 0, 2 ** (1.0 / 3.0), 2 ** (2.0 / 3.0)]'
anchors_ratios: '[(1.0, 1.0), (1.4, 0.7), (0.7, 1.4)]'

# must match your dataset's category_id.
# category_id is one_indexed,
# for example, index of 'car' here is 2, while category_id of is 3
obj_list: ['0']

前面的参数根据自己的数据集以及gpu数量修改即可,均值方差以及anchor可以不改,最后为类别列表。
数据集按照coco格式放到datasets目录下,结构参见coco数据集目录结构。
训练命令参照:
python train.py -c 2 -p coco --batch_size 8 --lr 1e-5 --num_epochs 10 --load_weights models/efficientdet-d2.pth
最后一个参数为预训练模型路径
测试命令参照:
python coco_eval.py -p coco -c 2 -w ./logs/coco/efficientdet-d2_199_33000.pth
最后一个参数为训练过程中保存的checkpoint路径。
这一版代码写的还是很规范,同时readme写的很详细,可以比照着自己调试。

你可能感兴趣的:(目标检测,人工智能,深度学习,计算机视觉)