AI

ラズパイ3で物体検出(Darknet)

物体検出で有名な Darknet が、NNPACKによりラズパイ3でもそれなりの速度で動くそうなので試してみました。

Darknet は非常に高速に物体検出ができるのですが、GPUやCUDNNのビルドオプションを利用しないとかなり重たくなるため、ラズパイで動かすのはあまり現実的ではありませんでした。

Darknet with NNPACK

https://github.com/digitalbrain79/darknet-nnpack

NNPACKにより最適化したバージョンのDarknetを公開されている方がいらっしゃったので、参考にさせていただきました。

Raspberry Pi 3 Model B

今回使用したラズパイは 3 Model Bで、
OSは2018-03-13-raspbian-stretch-lite使いました。

準備としてgitとpip3をインストールしています。

1
2
$ sudo apt-get upgrade
$ sudo apt-get install git python3-pip

Build from Raspberry Pi 3

参考サイトとは一部異なり、pip3、python3で実行しているところがあります。

Install PeachPy and confu

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

Install Ninja

1
2
3
4
5
git clone https://github.com/ninja-build/ninja.git
cd ninja
git checkout release
./configure.py --bootstrap
export NINJA_PATH=$PWD

Install clang

1
sudo apt-get install clang

Install NNPACK-darknet

1
2
3
4
5
6
7
8
9
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

1
2
3
4
cd ~
git clone https://github.com/thomaspark-pkj/darknet-nnpack.git
cd darknet-nnpack
make

Test

weightファイルをダウンロードします。

Darknet 本家ではYOLOがv3になっていますが、ここではYOLOv2を使います。

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

実行結果

YOLOv2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$ ./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 15928 ms.
person: 86%
horse: 82%
dog: 86%

約16秒で推論ができました。
通常の Darknet をラズパイで実行すると数分かかるので、NNPACKによりかなり最適化されていると思います。
人、馬、犬をそれぞれ80%以上の値で認識できていました。

Tiny-YOLO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ ./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 2287 ms.
dog: 53%
person: 73%
sheep: 60%
sheep: 39%

Tiny-YOLO版では、約2.3秒とさらに速くなっています。
馬が羊と判定されるなど精度は少し落ちているのは通常の Darknet のTiny-YOLOでも同様です。

本家の Darknet ではYOLOがv3となりさらに速くなっているそうですので、darknet-nnpackでもv3対応がされることを期待したいと思います。