EfficientDet 难复现,复现即趟坑。在此 Github 项目中,开发者 zylo117 开源了 PyTorch 版本的 EfficientDet,速度比原版高 20 余倍。如今,该项目已经登上 Github Trending 热榜。
如此高效的 EfficientDet 还能更高效吗?最近,有开发者在 GitHub 上开源了「PyTorch 版本的 EfficientDet」。该版本的性能接近原版,但速度是官方 TensorFlow 实现的近 26 倍!
下图展示了 EfficientDet 的整体架构,大致遵循单阶段检测器范式。谷歌大脑团队的研究者将在 ImageNet 数据集上预训练的 EfficientNet 作为主干网络,将 BiFPN 作为特征网络,接受来自主干网络的 level 3-7 特征 {P3, P4, P5, P6, P7},并重复应用自上而下和自下而上的双向特征融合。然后将融合后的特征输入边界框/类别预测网络,分别输出目标类别和边界框预测结果。
下图展示了多个模型在 COCO 数据集上的性能对比情况。在类似的准确率限制下,EfficientDet 的 FLOPS 仅为 YOLOv3 的 1/28、RetinaNet 的 1/30、NASFPN 的 1/19,所有数字均为单个模型在单一尺度下所得。可以看到,EfficientDet 的计算量较其他检测器少,但准确率优于后者,其中 EfficientDet-D7 获得了当前最优性能。
我们先来看一下项目作者与 EfficientDet 官方提供代码的测试效果对比。第一张图为官方代码的检测效果,第二张为项目作者的检测效果。项目作者的实现竟然透过汽车的前挡风玻璃检测出了车辆里面的人?!!这样惊艳的检测效果不愧是目前 EfficientDet 的霸榜存在。
接下来我们来看一下 coco 数据集上目标检测算法的排名,多个屠榜的目标检测网络基于 EfficientDet 构建。一图以言之:
项目作者复现结果与论文中并没完全一致,但相较于其他同类复现项目来说,称的上是非常接近了(详细信息可参考项目链接)。
第二个项目的 BN 实现有问题:BatchNorm 是有一个参数,叫做 momentum,用来调整新旧均值的比例,从而调整移动平均值的计算方式的。
Depthwise-Separatable Conv2D 的错误实现。
误解了 maxpool2d 的参数,kernel_size 和 stride。
减少通道的卷积后面,没有进行 BN
backbone feature 抽头抽错了
Conv 和 pooling,没有用到 same padding
没有能正确的理解 BiFPN 的流程
!git clone https://github.com/zylo117/Yet-Another-EfficientDet-Pytorch
import os
os.chdir('Yet-Another-EfficientDet-Pytorch')
!pip install pycocotools numpy opencv-python tqdm tensorboard tensorboardX pyyaml
!pip install torch==1.4.0
!pip install torchvision==0.5.0
!mkdir weights
os.chdir('weights')
!wget https://github.com/zylo117/Yet-Another-Efficient-Pytorch/releases/download/1.0/efficientdet-d0.pth
之后把需要检测的图片放在 test 文件夹下,这里别忘了还要把 efficientdet_test.py 中对应的图像名称修改为我们想要检测图片的名称,运行 efficientdet_test.py 脚本即可检测图片中的物体,输出结果如下:
我们先用曾经爆火的共享单车,现如今倒了一大片沦为「共享单车坟场」测试一下效果如何。下图分别为原图与使用本项目的检测结果。
效果很不错,图片中的人与密密麻麻、横七竖八摆放的共享单车大多都检测了出来。接下来我们用一张国内常见的堵车场景来测试一下,车辆、非机动车、行人交错出现在画面中,可以说是非常复杂的场景了。从检测结果可以看出,基本上所有的行人、车辆、背包、袋子等物体都较好地检测了出来。
最后当然要在「开挂民族」坐火车的场景下测试一番,密集恐惧症慎入。虽然把旗子检测成了风筝(很多目标检测算法都容易出现这样的问题),但总体来说检测效果可以说是非常惊艳的。它检测出了图片中大部分的人物,和机器之心此前报道过的高精度人脸检测方法-DBFace 的准确率有得一拼。需要注意的是,DBFace 是专用于人脸检测的方法,而本项目实现的是通用物体检测。
# create a yml file {your_project_name}.yml under 'projects'folder
# modify it following 'coco.yml'
# for example
project_name: coco
train_set: train2017
val_set: val2017
num_gpus: 4 # 0 means using cpu, 1-N means using gpus
# 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)]'
# objects from all labels from your dataset with the order from your annotations.
# its index 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: ['person', 'bicycle', 'car', ...]
# train efficientdet-d0 on coco from scratch
# with batchsize 12
# This takes time and requires change
# of hyperparameters every few hours.
# If you have months to kill, do it.
# It's not like someone going to achieve
# better score than the one in the paper.
# The first few epoches will be rather unstable,
# it's quite normal when you train from scratch.
python train.py -c 0 --batch_size 12
# train efficientdet-d1 on a custom dataset
# with batchsize 8 and learning rate 1e-5
python train.py -c 1 --batch_size 8 --lr 1e-5
# train efficientdet-d2 on a custom dataset with pretrained weights
# with batchsize 8 and learning rate 1e-5 for 10 epoches
python train.py -c 2 --batch_size 8 --lr 1e-5 --num_epochs 10 \
--load_weights /path/to/your/weights/efficientdet-d2.pth
# with a coco-pretrained, you can even freeze the backbone and train heads only
# to speed up training and help convergence.
python train.py -c 2 --batch_size 8 --lr 1e-5 --num_epochs 10 \
--load_weights /path/to/your/weights/efficientdet-d2.pth \
--head_only True
转自:Python开发者
微信扫一扫分享