天天看點

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

雲栖号資訊:【 點選檢視更多行業資訊

在這裡您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!

EfficientDet 難複現,複現即趟坑。在此 Github 項目中,開發者 zylo117 開源了 PyTorch 版本的 EfficientDet,速度比原版高 20 餘倍。如今,該項目已經登上 Github Trending 熱榜。

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

去年 11 月份,谷歌大腦提出兼顧準确率和模型效率的新型目标檢測器 EfficientDet,實作了新的 SOTA 結果。前不久,該團隊開源了 EfficientDet 的 TensorFlow 實作代碼。

如此高效的 EfficientDet 還能更高效嗎?最近,有開發者在 GitHub 上開源了「PyTorch 版本的 EfficientDet」。該版本的性能接近原版,但速度是官方 TensorFlow 實作的近 26 倍!

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

目前,該項目在 GitHub 上獲得了 957 顆星,最近一天的收藏量接近 300。

GitHub 位址:

https://github.com/zylo117

EfficientDet 簡介

近年來,在面對廣泛的資源限制時(如 3B 到 300B FLOPS),建構兼具準确率和效率的可擴充檢測架構成為優化目标檢測器的重要問題。基于單階段檢測器範式,谷歌大腦團隊的研究者檢視了主幹網絡、特征融合和邊界框/類别預測網絡的設計選擇,發現了兩大主要挑戰并提出了相應的解決方法:

挑戰 1:高效的多尺度特征融合。研究者提出一種簡單高效的權重雙向特征金字塔網絡(BiFPN),該模型引入了可學習的權重來學習不同輸入特征的重要性,同時重複應用自上而下和自下而上的多尺度特征融合。

挑戰 2:模型縮放。受近期研究的啟發,研究者提出一種目标檢測器複合縮放方法,即統一擴大所有主幹網絡、特征網絡、邊界框/類别預測網絡的分辨率/深度/寬度。

谷歌大腦團隊的研究者發現,EfficientNets 的效率超過之前常用的主幹網絡。于是研究者将 EfficientNet 主幹網絡和 BiFPN、複合縮放結合起來,開發出新型目标檢測器 EfficientDet,其準确率優于之前的目标檢測器,同時參數量和 FLOPS 比它們少了一個數量級。

下圖展示了 EfficientDet 的整體架構,大緻遵循單階段檢測器範式。谷歌大腦團隊的研究者将在 ImageNet 資料集上預訓練的 EfficientNet 作為主幹網絡,将 BiFPN 作為特征網絡,接受來自主幹網絡的 level 3-7 特征 {P3, P4, P5, P6, P7},并重複應用自上而下和自下而上的雙向特征融合。然後将融合後的特征輸入邊界框/類别預測網絡,分别輸出目标類别和邊界框預測結果。

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

下圖展示了多個模型在 COCO 資料集上的性能對比情況。在類似的準确率限制下,EfficientDet 的 FLOPS 僅為 YOLOv3 的 1/28、RetinaNet 的 1/30、NASFPN 的 1/19,所有數字均為單個模型在單一尺度下所得。可以看到,EfficientDet 的計算量較其他檢測器少,但準确率優于後者,其中 EfficientDet-D7 獲得了目前最優性能。

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

「宅」是第一生産力

項目作者今年 1 月宅家為國出力時,開始陸續嘗試各類 EfficientDet PyTorch 版實作,期間趟過了不少坑,也流過幾把辛酸淚。但最終得出了非常不錯的效果,也是全網第一個跑出接近論文成績的 PyTorch 版。

我們先來看一下項目作者與 EfficientDet 官方提供代碼的測試效果對比。第一張圖為官方代碼的檢測效果,第二張為項目作者的檢測效果。項目作者的實作竟然透過汽車的前擋風玻璃檢測出了車輛裡面的人?!!這樣驚豔的檢測效果不愧是目前 EfficientDet 的霸榜存在。

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

接下來我們來看一下 coco 資料集上目标檢測算法的排名,多個屠榜的目标檢測網絡基于 EfficientDet 建構。一圖以言之:

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

來自 paperswithcode

前五裡包攬前四,屠榜之勢不言而喻,也難怪各類煉金術士們躍躍欲試。但是,EfficientDet 的實作難度貌似與其知名度「成正比」,衆煉金師紛紛表示「難訓練」「至今未訓練好」「誰複現誰被坑」。項目作者也表示「由于谷歌一直不發官方 repository,是以隻能民間發力,那些靠 paper 的内容實作出來的真的不容易」。

假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7

項目作者複現結果與論文中并沒完全一緻,但相較于其他同類複現項目來說,稱的上是非常接近了(詳細資訊可參考項目連結)。

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

值得注意的是,此次項目處理速度比原版快了 20 餘倍。

那麼為什麼之前都沒有人複現 EfficientDet 的成績?具體哪些細節需要注意?

「民間」EfficientDet 的取舍

作者前後試用了兩個 GitHub 項目進行實作,但效果并不理想。首先采用的 star 量最高的一個,同時可能也說明了一點,不是 star 越高就越适合。

針對第一個項目,作者表示:「因為 EfficientDet 的特性之一是 BiFPN,它會融合 backbone 輸出的任意相鄰兩層的 feature,但是由于有兩層尺寸的寬高是不同的,是以會進行 upsample 或者 pooling 來保證它們寬高一緻。而這個作者沒有意識到,他不知道從 backbone 抽哪些 feature 出來,他覺得是 backbone 有問題,改了人家的 stride,随便挑了幾層,去強迫 backbone 輸出他想要的尺寸」

「改了網絡結構,pretrained 權值基本就廢了,是以作者也發現了,發現訓練不下去了」。至此第一個項目畫上句号,同時作者提供了官方參數與試用項目作者改後的參數對比連結,有興趣的朋友可浏覽參考連結。

而面向第二個項目,雖然 star 不及前者一半,但顯然可靠度更甚前者。作者表示,第二個項目起碼在 D0 上有論文成績的支撐,同時 repo 也提供了 coco 的 pretrained 權值 31.4mAP。然而實操後作者得到 24mAP,同時社群普遍也在 20-22 範圍中。

那麼此次結果的原因是什麼?作者經過反複的思考檢測,得到以下 7 點總結,并就此 7 點複盤進行适當得調整,得到了目前項目不錯的效果。

一波三折後的答案

針對第二個測試項目的複盤,作者表示一共有 7 個關鍵點需要額外注意:

  1. 第二個項目的 BN 實作有問題:BatchNorm 是有一個參數,叫做 momentum,用來調整新舊均值的比例,進而調整移動平均值的計算方式的。
  2. Depthwise-Separatable Conv2D 的錯誤實作。
  3. 誤解了 maxpool2d 的參數,kernel_size 和 stride。
  4. 減少通道的卷積後面,沒有進行 BN
  5. backbone feature 抽頭抽錯了
  6. Conv 和 pooling,沒有用到 same padding
  7. 沒有能正确的了解 BiFPN 的流程
PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

來源于項目作者知乎賬号,詳情請見參考連結

作者還表示,其中有個非常關鍵點,「雞賊的官方并沒有表示這裡是兩個獨立的 P4_0」。

簡而言之,這篇知乎部落格非常詳細的介紹了各種複現注意事項,細節在此不再一一贅述。筆者認為對各煉金術師有一定參考價值,感興趣的可以直接檢視原文部落格。

同時,機器之心對此項目也進行了實測。

項目實測

測試

我們在 P100 GPU,Ubuntu 18.04 系統下對本項目進行了測試。

首先将項目克隆到本地,并切換到相關目錄下:

!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           

項目作者為我們提供了用于推斷測試的 Python 腳本 efficientdet_test.py,該腳本會讀取 weights 檔案夾下儲存的網絡權重,并對 test 檔案夾中的圖檔進行推斷,之後将檢測結果儲存到同一檔案夾下。首先,我們使用如下指令下載下傳預訓練模型:

!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 腳本即可檢測圖檔中的物體,輸出結果如下:

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

我們先用曾經爆火的共享單車,現如今倒了一大片淪為「共享單車墳場」測試一下效果如何。下圖分别為原圖與使用本項目的檢測結果。

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測
PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

效果很不錯,圖檔中的人與密密麻麻、橫七豎八擺放的共享單車大多都檢測了出來。接下來我們用一張國内常見的堵車場景來測試一下,車輛、非機動車、行人交錯出現在畫面中,可以說是非常複雜的場景了。從檢測結果可以看出,基本上所有的行人、車輛、背包、袋子等物體都較好地檢測了出來。

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測
PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

最後當然要在「開挂民族」坐火車的場景下測試一番,密集恐懼症慎入。雖然把旗子檢測成了風筝(很多目标檢測算法都容易出現這樣的問題),但總體來說檢測效果可以說是非常驚豔的。它檢測出了圖檔中大部分的人物,和機器之心此前報道過的高精度人臉檢測方法-DBFace 的準确率有得一拼。需要注意的是,DBFace 是專用于人臉檢測的方法,而本項目實作的是通用物體檢測。

PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測
PyTorch版EfficientDet比官方TF實作快25倍?這個GitHub項目數天狂攬千星EfficientDet 簡介「宅」是第一生産力假期三天,拿下 PyTorch 版 EfficientDet D0 到 D7「民間」EfficientDet 的取舍一波三折後的答案項目實測

訓練

項目作者同時也提供了訓練 EfficientDet 相關的代碼。我們隻需要準備好訓練資料集,設定好類似于如下代碼所示的訓練參數,運作 train.py 即可進行訓練。

# 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', ...]           

在 coco 資料集上訓練代碼如下:

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
           

項目作者知乎文章:

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

【雲栖号線上課堂】每天都有産品技術專家分享!

課程位址:

https://yqh.aliyun.com/live

立即加入社群,與專家面對面,及時了解課程最新動态!

【雲栖号線上課堂 社群】

https://c.tb.cn/F3.Z8gvnK

原文釋出時間:2020-04-14

本文來自:“

OpenCV學堂

”,了解相關資訊可以關注“