#1.この記事の内容
darknetのYOLOv4,YOLOv4-tinyをRaspberryPi上で動作させ,COCO Evaluation Serverを用いてmAP算出しようと試みましたが,YOLOv4はRaspberryPiのメモリ不足による強制終了,YOLOv4-tinyは処理時間が長すぎることで断念しました.
代わりに,PC上(Windows Subsystem for Linux)での推論及びCOCO Evaluation ServerでのmAP算出までを実施しました.
環境構築からmAP算出までの内容をまとめます.
##1-1.使用環境
- darknet
- YOLOv4
- YOLOv4-tiny
- Raspberry Pi 3 Model B+
- Windows10
- WSL2
- Ubuntu 18.04
#2.darknetの取得・ビルドからCOCO Evaluation Serverまで
MS COCO test-dev2017 datasetの推論結果をCOCO Evaluation Server上でmAP算出する手順を紹介します.
本説明で記載する各ディレクトリは下記の表記とします.
$ export WORK_DIR=\
$ export DATASET_DIR=\
$ export PRETRAINED_MODEL_DIR=\
##2-1.darknetコードの準備とPretrainedモデルの取得(RaspberryPi, WSL共通)
darknetコードの取得
$ mkdir -p ${WORK_DIR}
$ cd ${WORK_DIR}
$ git clone https://github.com/AlexeyAB/darknet.git
ビルド
$ cd darknet
※GPU, CUDNN, OPENCV等を有効にする場合は,Makefileを編集する
RaspberryPi上ではすべて0のまま.PC上で動作する場合に1にセットする
GPU=0
CUDNN=0
OPENCV=0
↓
GPU=1
CUDNN=1
OPENCV=1
$ make
Pretrainedモデルの取得
- YOLO v4
${PRETRAINED_MODEL_DIR}へYOLOv4 model zooからダウンロードしたモデルを格納する.
YOLOv4 model zooではGoogle Drive上でモデルが公開されており,wgetで取得ができない. - YOLOv4-tiny
YOLOv4-tinyのPretrainedモデルはgithub上で公開されており,wgetで取得することができます.
wget https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov4-tiny.cfg
wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.weights
2-2.MS COCO dataset の準備(RaspberryPi, WSL共通)
Windows PC上で,公式サイトのダウンロードページから,「2017 Test images [41K/6GB]」をダウンロードして解凍します.解凍したフォルダは共有フォルダに設定します(2-3でRaspberryPiからマウントできるようにします).
「2017 Test images [41K/6GB]」ファイルサイズ及びファイル数が大きいため,FAT32フォーマットのストレージで扱うことができず,RaspberryPiに接続するmicroSDカードやUSBメモリには格納できません.
共有フォルダの設定方法及びRaspberryPi上でのマウント方法については,2-3を参照してください.
2-3.RaspberryPiでWindowsの共有フォルダをマウントする(RaspberryPiのみの手順)
RaspberryPiでWindowsの共有フォルダをマウントするに記載の手順で,2-2で解凍した「2017 Test images [41K/6GB]」をマウントします.
2-4.推論実行(RaspberryPi, WSL共通)
- 推論対象画像リストの取得とパスの変更
githubからtestdev2017.txtを取得して,ファイル内のパスを自身の環境に合わせて変更します
$ cd ${DATASET_DIR}
$ wget https://raw.githubusercontent.com/AlexeyAB/darknet/master/scripts/testdev2017.txt
- cfg/coco.dataの編集
cfg/coco.dataのvalid(testdev2017.txtのパス)を自身の環境に合わせて変更します - 推論実行
下記コマンドで推論処理を実行します.
処理が完了するとresults以下に推論結果(jsonファイル)が格納されます.
RaspberryPiでは推論結果が得られず,2-5のmAP算出はWindows PCでの実行結果を用いたものとなります.
- YOLOv4
$ mkdir results
$ ./darknet detector valid cfg/coco.data ${PRETRAINED_MODEL_DIR}/yolov4.cfg ${PRETRAINED_MODEL_DIR}/yolov4.weights
- YOLOv4-tiny
$ mkdir results
$ ./darknet detector valid cfg/coco.data ${PRETRAINED_MODEL_DIR}/yolov4-tiny.cfg ${PRETRAINED_MODEL_DIR}/yolov4-tiny.weights
2-5.mAP算出(COCO Evaluation Serverへのアップロード)
resultsディレクトリ以下に出力されるjsonファイルをzip圧縮して,COCO Evaluation ServerへSubmitします.
- jsonファイルのzip圧縮
$ cd results
$ mv coco_results.json detections_test-dev2017_yolov4_results.json
$ zip detections_test-dev2017_yolov4_results.zip detections_test-dev2017_yolov4_results.json
- COCO Detection Challenge (Bounding Box)へのアップロード
- ユーザ登録します(未登録の人)
- Participateタブから必要事項を記入してSubmitをクリックします
- ファイル選択画面が開くので,detections_test-dev2017_yolov4_results.zipを指定します
- 一覧表に追加されて,STATUSがRunningと表記され,評価中の状態になります
- サーバ上で評価が完了するとSTATUSがFinishedに変わり,SCOREが得られます
Finishedには自動では変わらないので,10分程度経過後にブラウザをリロードして確認します - "View scoring output log"をクリックすると,評価結果の詳細を確認できます
overall performance
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.436
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.644
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.479
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.247
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.468
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.557
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.340
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.557
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.597
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.389
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.641
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.757
Done (t=404.87s)
#3.補足:推論処理実行結果について
RaspberryPi上で推論結果を出力できなかった件について,補足として記載します.
RaspberryPi上でのYOLOv4動作について
RaspberryPi上でYOLOv4の推論を実行すると「強制終了」のメッセージとともに,darknetが落ちました.
$ ./darknet detector valid cfg/coco.data pretrained_model/yolov4/yolov4.cfg pretrained_model/yolov4/yolov4.weights
GPU isn't used
OpenCV isn't used - data augmentation will be slow
results: Using default 'results'
mini_batch = 1, batch = 8, time_steps = 1, train = 0
layer filters size/strd(dil) input output
0 conv 32 3 x 3/ 1 512 x 512 x 3 -> 512 x 512 x 32 0.453 BF
1 conv 64 3 x 3/ 2 512 x 512 x 32 -> 256 x 256 x 64 2.416 BF
2 conv 64 1 x 1/ 1 256 x 256 x 64 -> 256 x 256 x 64 0.537 BF
3 route 1 -> 256 x 256 x 64
4 conv 64 1 x 1/ 1 256 x 256 x 64 -> 256 x 256 x 64 0.537 BF
5 conv 32 1 x 1/ 1 256 x 256 x 64 -> 256 x 256 x 32 0.268 BF
6 conv 64 3 x 3/ 1 256 x 256 x 32 -> 256 x 256 x 64 2.416 BF
・・・(中略)
Loading weights from pretrained_model/yolov4/yolov4.weights...
seen 64, trained: 0 K-images (0 Kilo-batches_64)
Done! Loaded 162 layers from weights-file
Learning Rate: 0.00261, Momentum: 0.949, Decay: 0.0005
Detection layer: 139 - type = 28
Detection layer: 150 - type = 28
Detection layer: 161 - type = 28
4
強制終了
Netdataでモニタリングするとメモリ消費により落ちている傾向があり,メモリ不足により実行できなかったと考えられます.
RaspberryPiでのYOLOv4-tiny動作について
YOLOv4-tinyはメモリ不足による強制終了は発生しませんが,画像1枚あたり約36秒かかる(約0.028[fps])為,全20288枚に要する推論時間は約8日となります.
私の都合で8日間連続動作させることができませんでしたので,推論結果は出さずに保留しました.連続動作させれば推論結果を得ることができると思いますので,可能な方は実施してみてもらえればと思います.
diff --git a/src/detector.c b/src/detector.c
index a2fdf0b..b6f1368 100644
--- a/src/detector.c
+++ b/src/detector.c
@@ -662,7 +662,7 @@ void validate_detector(char *datacfg, char *cfgfile, char *weightfile, char *out
layer lk = net.layers[k];
if (lk.type == YOLO || lk.type == GAUSSIAN_YOLO || lk.type == REGION) {
l = lk;
\- printf(" Detection layer: %d - type = %d \n", k, l.type);
\+ printf(" Detection layer: %d - type = %d (in validate_detector())\n", k, l.type);
}
}
int classes = l.classes;
@@ -747,8 +747,9 @@ void validate_detector(char *datacfg, char *cfgfile, char *weightfile, char *out
thr[t] = load_data_in_thread(args);
}
time_t start = time(0);
\+ printf("m + nthreads = %d\n", m + nthreads);
for (i = nthreads; i < m + nthreads; i += nthreads) {
\- fprintf(stderr, "%d\n", i);
\+ fprintf(stderr, "i %d, elapsed_time %f [sec]\n", i, (double)time(0) - start);
for (t = 0; t < nthreads && i + t - nthreads < m; ++t) {
pthread_join(thr[t], 0);
val[t] = buf[t];
#4.さいごに
推論結果はWindows PC(WSL, RTX 2070 SUPER)で出力したもので,YOLOv4 model zooと推論実行環境が異なる為,結果の一致はしませんでしたが,YOLOv4 model zoog記載の数値(AP=43.0,AP_50=64.9,AP_75=46.5,…)とほぼ同程度の結果が得られましたので,環境構築手順及び実行手順,結果は妥当なものと思います.
Raspberry Pi 3 Model B+上での推論結果算出は断念しましたが,Raspberry Pi 4B メモリ8GB版などを購入した際に試行できれば,追記したいと思います.
#5.関連リンク
- darknet
- YOLOv4 model zoo
- Pre-trained models
- Training and Evaluation of speed and accuracy on MS COCO
- How to evaluate accuracy and speed of YOLOv4
- COCO dataset; Detection Evaluation
- Upload Results to Evaluation Server
- RaspberryPiでWindowsの共有フォルダをマウントする
- COCO Detection Challenge (Bounding Box)
- ファイルシステム別の制限事項まとめ
- Raspberry Piのシステムモニタリング