【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ファイルが実行できるかを調査していきたいと思います。

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

【Raspberry Piの導入~セットアップまで】

はじめまして

今日からブログをはじめていきます、がんがんと言います。電子工作とか人工知能とかを勉強してる工学部学生です。このブログは自分が何をしたか忘れないようにメモ程度に書いていきます。

間違っている点やコメントなどあればお待ちしております。あくまでメモ程度なのでよろしくお願いします。

1. Raspberry Piの準備

 ラズパイで物体検出をやってみたかったのでラズパイを用意しました。今回はRaspberryの準備・セットアップについてまとめます。

使用するRaspberry Piは「Raspberry Pi 3 Model B ver1.2」です。運よく研究室に余っていたものを拝借しました。

手元に電源とSDカードがなかったのでそちらを購入しました。

SDカードはkingston社製の32GBのMicro SDを購入。今回はRaspberry Pi 3を使用するため、5V 2.5AのUSB電源アダプタを購入。

 必要な物がすべて揃ったのでセットアップ開始!

2. Raspberry Piの環境構築

 まずはSDカードのフォーマット、Raspbianのインストールから行っていきます。

今回はこちらを参考にさせてもらいました。

 

deviceplus.jp

 SDカードフォーマッターを用いて無事にフォーマットし、Raspbianをインストールしていきます。

今回はとりあえずRaspbianをインストールし、今後ほかのOSも試していきます。

OSを無事にインストールし、完成後の環境はこんな感じです。

全体図

環境構築図

ケースがないのが残念ですがそこはおいおい追加していくこととしましょう。

さてOSのインストールをして遊んでいきたいと思います。OSは上記通りRaspbianを使用します。

無事にインストール完了しました(写真を撮り忘れました)。さっそくRaspbianを日本語化しようとして、いろいろいじっていると問題が発生しました…

なんとOS起動時の緑のランプが点灯せず、起動してくれません。SDが熱くなっているように感じて一度電源を落としたのですが、その際に電源コードをきちんと終了せずに抜いたようです…

慌ててSDカードを抜き差ししたりしてみましたがビクともしません。SDカードはやけどするわ!ってくらいに高熱になっていました。

 解決策をいろいろ調べたり、パソコンに接続して再インストールも試みましたがどれも出来ず…(SDカードがそもそも読み込めなくなった)

 

仕方なく、予備のSDカードにOSをインストールし直しました。はたしてついてくれるか…

デスクトップ画面

 よかったー!無事に起動してくれました。これで改めてセットアップを進めていきます。

3. Raspberry Piのセットアップ

 セットアップや日本語化などを以下のサイトを参考に行っていきます。

ai-coordinator.jp

 サイトを見ながら順調に手順を進めていきました。Picameraの手順を進めていくと無事に起動できました。うちのACアダプタちゃんもしっかりと映っています。

 しっかり起動も確認し、安心安心。さあ、続きの工程を進めていこうか…どう切るのかな?

プログラム上ではsleep(10)となっていたため、すでに元の画面に戻っていてもいい頃なのにまったく戻ってくれません。

電源を抜いたせいでSDカードが死んだことがトラウマにあるため、どうにかコマンドで解決できないかを捜索。

捜索すること30分…

sshを用いて別のPCから切ることが出来ると判明したものの、enableにしてないことを思い出し絶望しました…

仕方なく電源を抜き、再びつくことを全力で祈ります。

 

結果、つきましたー!コードを確認してみると、


    from picamera import PiCamera
    from time import sleep
    
    camera = PiCamera()
    
    camera.start_preview()
    sleep(10)
    camera.stop_preview
    

camera.stop_preview()の()を忘れてました。超絶凡ミス…。

()を修正して再びトライすると、無事についてくれて非常に安堵した午前2時半でした。

 残りのチュートリアルは気が向いたときにでもトライしていきます。

 

次回

次回は、ついにやってみたかったラズパイ + 物体検出(YOLO)をやっていきます。