LoginSignup
3
2

More than 3 years have passed since last update.

YOLOv4をRaspberryPi上で動かせなかった件まとめ

Posted at

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=<path to your work dir>
$ export DATASET_DIR=<path to your dataset dir>
$ export PRETRAINED_MODEL_DIR=<path to your 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共通)

  1. 推論対象画像リストの取得とパスの変更
    githubからtestdev2017.txtを取得して,ファイル内のパスを自身の環境に合わせて変更します
    
    $ cd ${DATASET_DIR}
    $ wget https://raw.githubusercontent.com/AlexeyAB/darknet/master/scripts/testdev2017.txt
    
  2. cfg/coco.dataの編集
    cfg/coco.dataのvalid(testdev2017.txtのパス)を自身の環境に合わせて変更します
  3. 推論実行
    下記コマンドで推論処理を実行します.
    処理が完了すると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します.

  1. 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
    
  2. COCO Detection Challenge (Bounding Box)へのアップロード
    1. ユーザ登録します(未登録の人)
    2. Participateタブから必要事項を記入してSubmitをクリックします
    3. ファイル選択画面が開くので,detections_test-dev2017_yolov4_results.zipを指定します
    4. 一覧表に追加されて,STATUSがRunningと表記され,評価中の状態になります
    5. サーバ上で評価が完了するとSTATUSがFinishedに変わり,SCOREが得られます
      Finishedには自動では変わらないので,10分程度経過後にブラウザをリロードして確認します
    6. "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でモニタリングするとメモリ消費により落ちている傾向があり,メモリ不足により実行できなかったと考えられます.

メモリモニタリング_YOLOv4.png

RaspberryPiでのYOLOv4-tiny動作について

YOLOv4-tinyはメモリ不足による強制終了は発生しませんが,画像1枚あたり約36秒かかる(約0.028[fps])為,全20288枚に要する推論時間は約8日となります.
私の都合で8日間連続動作させることができませんでしたので,推論結果は出さずに保留しました.連続動作させれば推論結果を得ることができると思いますので,可能な方は実施してみてもらえればと思います.

  • モニタリングの結果
    メモリモニタリング_YOLOv4-tiny.png
  • 推論時間計測結果
    YOLOv4-tiny_実行時間計測.png
    時間計測用のコード変更内容は下記のとおりです.
    
    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.関連リンク

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2