【Raspberry PiでDarknet with NNPACKの導入】
はじめに
前回の記事はこちらから
今回は前回の予告通りYOLOを導入していきたいと思います。
YOLOとは、You Only Lock Onceの略称、物体検出手法の1つです。物体検出の分野ではR-CNNと合わせてよく耳にするのではないでしょうか。最新バージョンはYOLO v3でこちらのサイトなどを参考にして試すといいです。
新しくなったYOLOv3を使ってみよう | Sosogu LLC.
この記事によると高精度かつ高速度の物体検出と言えます(2018.4時点)。
Googleでラズパイ + 物体検出を調べてみると結構いっぱい出てきました。 どの記事を見ても通常のYOLOでは遅すぎて話にならないと書いてありました(1枚の画像に5分かかったりする)。
今後の展望として、ロボットに積んで物体検出をしたりしたいのでなるべく高速になってくれるとうれしい…
さらにいろいろ調べてみるとこちらの記事に出会いました。
この記事の通りならばかなり速度を出せそうですね!とりあえず、こちらを参考にしながら導入を進めていきたいと思います。
本家さまも参考までに貼っておきます。
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%以上の精度で認識できています。
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でも十分に使えそうです。
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ファイルが実行できるかを調査していきたいと思います。
また、動画像中のオブジェクトを検出できるのかも試みてみようと思います。