当前位置: 首页 > 科技观察

PyTorch版EfficientDet比官方TF实现快25倍?这个GitHub项目连续几天吸引了成千上万的star

时间:2023-03-15 16:53:05 科技观察

EfficientDet。很难重现,重现是一个陷阱。在这个Github项目中,开发者zylo117开源了EfficientDet的PyTorch版本,比原来的版本快了20多倍。今日,该项目已登上GithubTrending热榜。去年11月,GoogleBrain提出了兼顾精度和模型效率的新型目标检测器EfficientDet,并取得了新的SOTA结果。不久前,团队开源了EfficientDet的TensorFlow实现。如此高效的EfficientDet还能更高效吗?近日,有开发者在GitHub上开源了“EfficientDet的PyTorch版”。这个版本的性能接近原始版本,但比官方的TensorFlow实现快了近26倍!目前,该项目在GitHub上有957颗星,最近一天的收藏接近300颗。GitHub地址:https://github.com/zylo117EfficientDet简介近年来,面对大范围的资源限制(例如3B到300BFLOPS),构建一个兼具准确性和效率的可扩展检测架构成为目标优化目标检测器。重要的问题。基于单阶段检测器范式,GoogleBrain团队的研究人员回顾了主干网络、特征融合和边界框/类别预测网络的设计选择,发现了两大挑战并提出了相应的解决方案:挑战一:高效多级尺度特征融合。研究人员提出了一种简单高效的加权双向特征金字塔网络(BiFPN),它引入可学习的权重来学习不同输入特征的重要性,同时重复应用自上而下和自下而上的多尺度特征融合。挑战2:模型缩放。受近期研究的启发,研究人员提出了一种用于对象检测器的复合缩放方法,该方法统一扩展所有主干网络、特征网络和边界框/类别预测网络的分辨率/深度/宽度。GoogleBrain团队的研究人员发现,EfficientNets比以前使用的主干网络更高效。因此研究人员将EfficientNet骨干网络与BiFPN和复合缩放相结合,开发了一种新的目标检测器EfficientDet,其精度比以往的目标检测器更高,而参数数量和FLOPS都比它们少一个数量级。下图展示了EfficientDet的整体架构,大致遵循了one-stagedetector范式。GoogleBrain团队的研究人员使用在ImageNet数据集上预训练的EfficientNet作为主干网络,BiFPN作为特征网络,接受来自主干网络的3-7级特征{P3,P4,P5,P6,P7},并重复应用自上而下和自下而上的双向特征融合。然后将融合后的特征输入边界框/类别预测网络,该网络分别输出目标类别和边界框预测结果。下图展示了多个模型在COCO数据集上的性能对比。在相似精度限制下,EfficientDet的FLOPS仅为YOLOv3的1/28、RetinaNet的1/30、NASFPN的1/19,而且所有数字都是单一模型在单一尺度下得到的。可以看出,EfficientDet相比其他检测器计算量较少,但精度优于后者,其中EfficientDet-D7取得了目前最好的性能。更详细的介绍可以参考机器之心文章:比现在的SOTA小4倍,计算量少9倍,谷歌最新目标检测器EfficientDet“House”是第一个生产力项目的作者。我开始陆续尝试各种EfficientDetPyTorch版本。这期间,我走过许多坎坷,也流过几滴辛酸的泪水。不过最后还是得到了一个很好的结果,也是全网第一个跑的接近论文结果的PyTorch版本。我们来看看项目作者的测试结果和EfficientDet官方提供的代码的对比。第一张图是官方代码的检测效果,第二张图是项目作者的检测效果。项目作者的实现竟然能透过汽车前挡风玻璃检测到车内人员?!!如此惊人的检测效果,不愧为EfficientDet目前的佼佼者。接下来我们来看看目标检测算法在coco数据集上的排名。基于EfficientDet构建了多个屠宰名单的目标检测网络。一张图就能看出来:从paperswithcode来看,前五名中的前四名,屠榜之势不言而喻,也难怪各类炼金术士跃跃欲试。不过,EfficientDet的实现难度似乎与其受欢迎程度“成正比”,众炼丹师纷纷表示“难练”、“练不好”、“谁重现谁被骗”。该项目的作者还表示,“由于谷歌没有发布官方存储库,它只能供人们使用。纸上的内容真的很不容易实现。”三天假期,我拿下了EfficientDetD0到D7的PyTorch版。作者的复现结果与论文中的不完全相同,但与其他类似的复现项目相比,已经非常接近了(详见项目链接)。值得注意的是,这个项目的处理速度比原来的版本快了20多倍。那么为什么以前没有人复制EfficientDet的性能呢?需要注意哪些具体细节?选择“民间”EfficientDet的作者曾尝试过两个GitHub项目来实现,但效果并不理想。星数最高的优先使用,这也能说明一点,并不是说星数越高越合适。对于第一个项目,作者说:“因为EfficientDet的一个特点是BiFPN,它会融合backbone输出的任意两个相邻层的特征,但是因为两层的宽高不同,所以会执行upsample或者pooling来保证它们的宽高相同。但是作者没有意识到不知道从backbone中抽取哪些特征,他以为是backbone有问题,所以改了strideofothers,随便挑几层,强制backbone输出他想要的size""改变网络结构,pretrainedweights基本没用,所以作者也发现训练不下去了”至此,第一个项目告一段落。同时作者提供了官方参数与试用项目作者修改参数的对比链接。感兴趣的朋友可以浏览参考链接。第二个项目,虽然星级不到前者的一半,但明显比前者靠谱。作者说第二个项目至少有D0上papergrades的支持,repo也提供了coco的pretrainedweight31.4mAP。不过笔者实际运行后得到了24mAP,社区一般在20-22的范围内。那么造成这个结果的原因是什么?经过反复思考和测试,笔者得到了以下7点总结,并在这7点的基础上进行了适当的调整,取得了目前项目的良好效果。几经周折,答案针对的是二试项目的复习。作者说有7个关键点需要额外注意:第二个项目的BN实现有问题:BatchNorm有一个参数叫做momentum,用来调整新旧均值,从而调整方式计算移动平均值。Depthwise-SeparableConv2D的错误实现。误解了maxpool2d、kernel_size和stride的参数。减少channel的卷积后,没有用到BNbackbonefeature,错误的挖掘了Conv和pooling,没有用同样的padding,没有正确理解BiFPN的过程。其中有一个很关键的地方,“吃鸡贼官方并没有说明这里有两个独立的P4_0”。总之,本知乎博客对各种复制注意事项进行了非常详细的介绍,这里不再赘述。笔者认为对各位炼丹师都有一定的参考价值,有兴趣的可以直接查看原博客。同时,机器之心也对这个项目进行了实际测试。项目实测我们在P100GPU和Ubuntu18.04系统下对本项目进行了测试。先把项目克隆到本地,切换到相关目录:!gitclonehttps://github.com/zylo117/Yet-Another-EfficientDet-Pytorchimportosos.chdir('Yet-Another-EfficientDet-Pytorch')安装如下依赖环境:!pipinstallpycocotoolsnumpyopencv-pythontqdmtensorboardtensorboardXpyyaml!pipinstalltorch==1.4.0!pipinstalltorchvision==0.5.0项目作者为我们提供了一个用于推理测试的Python脚本efficientdet_test.py,会读取weights文件夹中保存的网络权重,并进行推理测试文件夹中的图片,然后将检测结果保存在同一个文件夹中。首先,我们使用以下命令下载预训练模型:!mkdirweightsos.chdir('weights')!wgethttps://github.com/zylo117/Yet-Another-Efficient-Pytorch/releases/download/1.0/efficientdet-d0.pth然后把要检测的图片放到test文件夹下。不要忘记将efficientdet_test.py中对应的图片名称改为我们要检测的图片名称。运行efficientdet_test.py脚本对图片中的物体进行检测,输出结果如下:我们先用曾经火爆的共享单车,现在大面积沦为“共享单车坟场”来测试效果。以下图片为原图和使用该项目的测试结果。效果很好。图中大部分人和排成一排的共享单车都被检测到了。接下来我们以国内常见的堵车场景来测试一下。车辆、非机动车、行人交替出现在画面中,可以说是一个非常复杂的场景。从检测结果可以看出,基本上所有的行人、车辆、背包、包包等物体都检测的很好。当然最后还是要在“开挂民族”坐火车的场景下测试,有密集恐惧症的要慎重。虽然把旗子检测成风筝(很多目标检测算法都容易出现这样的问题),但是整体的检测效果可以说是非常惊人的。它检测出了图片中的大部分人,其准确率堪比机器之心此前报道的高精度人脸检测方法DBFace。需要注意的是,DBFace是专用于人脸检测的方法,而本项目实现的是一般物体检测。训练项目的作者也提供了训练EfficientDet相关的代码。我们只需要准备好训练数据集,设置类似如下代码的训练参数,运行train.py进行训练即可。#createaymlfile{your_project_name}.ymlunder'projects'folder#modifyitfollowing'coco.yml'#forexampleproject_name:cocotrain_set:train2017val_set:val2017num_gpus:4#0meansusingcpu,1-Nmeansusinggpus#meanandstdinRGBorder,actuallythispartshouldremainunchangedaslongasyourdatasetissimilartococo.mean:[0.485,0.456,0.406]std:[0.229,0.224,0.225]#thisiscocoanchors,changeitifnecessaryanchors_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)]'#objectsfromalllabelsfromyourdatasetwiththeorderfromyourannotations.#itsindexmustmatchyourdataset'scategory_id.#category_idisone_indexed,#forexample,indexof'car'hereis2,whilecategory_idofis3obj_list:['person','bicycle','car',...]在coco数据集中培训代码如下:#trainefficientdet-d0oncocofromscratch#withbatchsize12#Thistakestimeandrequireschange#ofhyperparameterseveryfewhours.#Ifyouhavemonthstokill,doit.#It'snotlikesomeonegoingtoachieve#betterscorethantheoneinthepaper.#Thefirstfewepocheswillberatherrunstable,#it'squitenormalwhenyoutrainfromscratch.py??thontrain.py-c0--batch_size12在自定义数据集上训练:#trainefficientdet-d1onacustomdataset#withbatchsize8andlearningrate1e-5pythontrain.py-c1--batch_size8--lr1e-5项目作者强烈推荐预训练Trainthe权重网络:#trainefficientdet-d2onacustomdatasetwithpretrainedweights#withbatchsize8andlearningrate1e-5for10epochespythontrain.py-c2--batch_size8--lr1e-5--num_epochs10--load_weights/path/to/your/weights/efficientdet-d2.pth#withaco-pretrained,youcanevenfreezethebackboneandtrainheadsonly#tospeeduptrainingandhelpconvergence.pythontrain.py-c2--batch_size8--lr1e-5--num_epochs10--load_weights/path/to/your/weights/efficientdet-d2.pth--head_onlyTrue[编辑推荐]Github也可以帮老师在线批改作业,Github上线了Classroom功能8小时系列失败的罪魁祸首是:DatabaseInfrastructure三月份Github上的热门开源项目使用清单丰富的GitHub存储库,帮助您深入了解程序员所需的知识这可能是Github上最全面的Flutter教程