【Raspberry PiでDarknet with NNPACKの導入】

 

はじめに

前回の記事はこちらから

gangannikki.hatenadiary.jp

 

 今回は前回の予告通りYOLOを導入していきたいと思います。

YOLOとは、You Only Lock Onceの略称、物体検出手法の1つです。物体検出の分野ではR-CNNと合わせてよく耳にするのではないでしょうか。最新バージョンはYOLO v3でこちらのサイトなどを参考にして試すといいです。

新しくなったYOLOv3を使ってみよう | Sosogu LLC.

この記事によると高精度かつ高速度の物体検出と言えます(2018.4時点)。

 

Googleでラズパイ + 物体検出を調べてみると結構いっぱい出てきました。 どの記事を見ても通常のYOLOでは遅すぎて話にならないと書いてありました(1枚の画像に5分かかったりする)。

今後の展望として、ロボットに積んで物体検出をしたりしたいのでなるべく高速になってくれるとうれしい…

さらにいろいろ調べてみるとこちらの記事に出会いました。

yagitsawa.github.io

この記事の通りならばかなり速度を出せそうですね!とりあえず、こちらを参考にしながら導入を進めていきたいと思います。

本家さまも参考までに貼っておきます。

github.com

 

1. Darknet with NNPACKのインストール

上記のサイトを参考に進めていきます。pip3、gitはともに最新版でした。

Install PeachPy and confu

pip3でそれぞれインストールしていきます。


    sudo pip3 install --upgrade git+https://github.com/Maratyszcza/PeachPy
    sudo pip3 install --upgrade git+https://github.com/Maratyszcza/confu
    
Install Ninja

    git clone https://github.com/ninja-build/ninja.git
    cd ninja
    git checkout release
    ./configure.py --bootstrap
    export NINJA_PATH=$PWD
    
Install clang

    sudo apt-get install clang
    
Install NNPACK-darknet

    cd ~
    git clone https://github.com/thomaspark-pkj/NNPACK-darknet.git
    cd NNPACK-darknet
    confu setup
    python3 ./configure.py --backend auto
    $NINJA_PATH/ninja
    sudo cp -a lib/* /usr/lib/
    sudo cp include/nnpack.h /usr/include/
    sudo cp deps/pthreadpool/include/pthreadpool.h /usr/include/
    
Build darknet-nnpack

    cd ~
    git clone https://github.com/thomaspark-pkj/darknet-nnpack.git
    cd darknet-nnpack
    make
    
Test

    wget https://pjreddie.com/media/files/yolov2-tiny-voc.weights
    wget https://pjreddie.com/media/files/yolov2.weights
    

2. 実行結果

実際にYOLO v2、 Tiny YOLO v2で実行した結果をまとめていきます。

YOLO v2


$ ./darknet detector test cfg/coco.data cfg/yolo.cfg yolov2.weights data/person.jpg
layer     filters    size              input                output
    0 conv     32  3 x 3 / 1   608 x 608 x   3   ->   608 x 608 x  32
    1 max          2 x 2 / 2   608 x 608 x  32   ->   304 x 304 x  32
    2 conv     64  3 x 3 / 1   304 x 304 x  32   ->   304 x 304 x  64
    3 max          2 x 2 / 2   304 x 304 x  64   ->   152 x 152 x  64
    4 conv    128  3 x 3 / 1   152 x 152 x  64   ->   152 x 152 x 128
    5 conv     64  1 x 1 / 1   152 x 152 x 128   ->   152 x 152 x  64
    6 conv    128  3 x 3 / 1   152 x 152 x  64   ->   152 x 152 x 128
    7 max          2 x 2 / 2   152 x 152 x 128   ->    76 x  76 x 128
    8 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256
    9 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128
   10 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256
   11 max          2 x 2 / 2    76 x  76 x 256   ->    38 x  38 x 256
   12 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512
   13 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256
   14 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512
   15 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256
   16 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512
   17 max          2 x 2 / 2    38 x  38 x 512   ->    19 x  19 x 512
   18 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024
   19 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512
   20 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024
   21 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512
   22 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024
   23 conv   1024  3 x 3 / 1    19 x  19 x1024   ->    19 x  19 x1024
   24 conv   1024  3 x 3 / 1    19 x  19 x1024   ->    19 x  19 x1024
   25 route  16
   26 conv     64  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x  64
   27 reorg              / 2    38 x  38 x  64   ->    19 x  19 x 256
   28 route  27 24
   29 conv   1024  3 x 3 / 1    19 x  19 x1280   ->    19 x  19 x1024
   30 conv    425  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 425
   31 detection
mask_scale: Using default '1.000000'
Loading weights from yolov2.weights...Done!
data/person.jpg: Predicted in 9050 ms.
person: 86%
horse: 82%
dog: 86%

今回の実行結果は約9秒となりました。参考サイトでは約16秒だったので、それよりも速い結果です。

通常のDarknetではかなり遅いものの、NNPACKにより最適化されたことによる速度の向上がよく分かりますね。

精度に関しても人、馬、犬を80%以上の精度で認識できています。

v2-person

Tiny YOLO v2

$ ./darknet detector test cfg/voc.data cfg/tiny-yolo-voc.cfg yolov2-tiny-voc.weights data/person.jpg
layer     filters    size              input                output
    0 conv     16  3 x 3 / 1   416 x 416 x   3   ->   416 x 416 x  16
    1 max          2 x 2 / 2   416 x 416 x  16   ->   208 x 208 x  16
    2 conv     32  3 x 3 / 1   208 x 208 x  16   ->   208 x 208 x  32
    3 max          2 x 2 / 2   208 x 208 x  32   ->   104 x 104 x  32
    4 conv     64  3 x 3 / 1   104 x 104 x  32   ->   104 x 104 x  64
    5 max          2 x 2 / 2   104 x 104 x  64   ->    52 x  52 x  64
    6 conv    128  3 x 3 / 1    52 x  52 x  64   ->    52 x  52 x 128
    7 max          2 x 2 / 2    52 x  52 x 128   ->    26 x  26 x 128
    8 conv    256  3 x 3 / 1    26 x  26 x 128   ->    26 x  26 x 256
    9 max          2 x 2 / 2    26 x  26 x 256   ->    13 x  13 x 256
   10 conv    512  3 x 3 / 1    13 x  13 x 256   ->    13 x  13 x 512
   11 max          2 x 2 / 1    13 x  13 x 512   ->    13 x  13 x 512
   12 conv   1024  3 x 3 / 1    13 x  13 x 512   ->    13 x  13 x1024
   13 conv   1024  3 x 3 / 1    13 x  13 x1024   ->    13 x  13 x1024
   14 conv    125  1 x 1 / 1    13 x  13 x1024   ->    13 x  13 x 125
   15 detection
mask_scale: Using default '1.000000'
Loading weights from yolov2-tiny-voc.weights...Done!
data/person.jpg: Predicted in 1302 ms.
dog: 53%
person: 73%
sheep: 60%
sheep: 39%

実行結果は約1.3秒となり、参考サイトよりも1秒以上速い結果となりました。

精度に関しては参考サイト同様に低下していることが分かります。

速度が最大限に求められ、かつ、人くらいしか認識しないのであればTiny-YOLOでも十分に使えそうです。

v2_tiny-person

3. YOLO v3の導入

YOLOの最新バージョンは2018.6時点ではYOLO v3です。せっかくなら、YOLO v2ではなく、より精度の向上したYOLO v3を試してみたいものです。Darknet with NNPACKでは weightファイルをダウンロードしてから実行テストをしています。

ということは、YOLO v3のweightファイルをダウンロードすればいいのではないでしょうか?

 

思い立ったが吉日ということで実際にやってみました。すると、以下のようなことに…


$ wget https://pjreddie.com/media/files/yolov3.weights
--2018-06-13 05:07:56--  https://pjreddie.com/media/files/yolov3.weights
pjreddie.com (pjreddie.com) をDNSに問いあわせています... 128.208.3.39
pjreddie.com (pjreddie.com)|128.208.3.39|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 248007048 (237M) [application/octet-stream]
`yolov3.weights' に保存中

yolov3.weights                          35%[=========================>                                                 ]  83.31M   437KB/s    in 71s     


`yolov3.weights' へ書き込めません(デバイスに空き領域がありません)。

ここに来て空き領域不足によりダウンロードできませんでした。

 

SDカードを仕方なく8GBにした弊害がさっそく現れました。これはつらい…

とりあえず、現状を確認してみましょう。こちらのコマンドを実行すると


    df -h
    

以下のような結果となりました。


ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/root        5.4G  5.1G  6.9M  100% /
devtmpfs         434M     0  434M    0% /dev
tmpfs            438M   21M  418M    5% /dev/shm
tmpfs            438M  6.0M  432M    2% /run
tmpfs            5.0M  4.0K  5.0M    1% /run/lock
tmpfs            438M     0  438M    0% /sys/fs/cgroup
/dev/mmcblk0p6    68M   22M   47M   32% /boot
tmpfs             88M  4.0K   88M    1% /run/user/1000
/dev/mmcblk0p5    30M  398K   28M    2% /media/pi/SETTINGS

今回は8GBのSDカードを使用しているのでまだまだ使えるところがありそうですね。

次回

今回はラズパイでYOLOが動くことが分かったのでとりあえず良しとしましょう。

次回までにSDカードの容量を増やして、YOLO v3のweightファイルが実行できるかを調査していきたいと思います。

また、動画像中のオブジェクトを検出できるのかも試みてみようと思います。