Coral Edge TPU (USB type) を Pi4 + Ubuntu Server 19.10.1 (64 bit) で動作させる : 後編

* [前編](https://qiita.com/andromedroid/items/d29072d807e24d2dbfbd) にて UbuntuServer 19.10.1 (eoan) for Pi4 の準備が終わったので、
ここからは [Coral Edge TPU](https://coral.ai/products/accelerator) の setup を行います。

* と言っても、やることは Raspbian buster (32 bit OS)
の場合と全く変わりませんでした。
	* 今年の Advent Calendar でも[こちら](https://qiita.com/3attoC/items/6fae9dc70526e1da9ff6) で紹介されています。
	* もう少しハマるかと思ったのですが…  
	これまで setup 手順を洗練してきた Google さんに感謝です。

## Setup : Coral Edge TPU

* Pi4 のターミナルで以下を実行。
	* 変わりばえしないので、サックリと。

~~~
$ export URL='https://packages.cloud.google.com/apt'
$ export FILE='/etc/apt/sources.list.d/coral-edgetpu.list'
$ echo "deb $URL coral-edgetpu-stable main" | sudo tee $FILE
$ export GPG='https://packages.cloud.google.com/apt/doc/apt-key.gpg'
$ curl $GPG | sudo apt-key add -
$ sudo apt update
$ sudo apt install libedgetpu1-std edgetpu-examples
~~~

* udev service の restart が必要だった気がするので、
service udev restart か、もしくは reboot します。

* 終わったら Edge TPU を Pi4 の USB 3.0（青い方）に接続

## workspace の準備

* 作業ディレクトリを準備していきます。
	* benchmark には **classify_image.py** を使います。

~~~
$ mkdir -p ~/workspace/edgetpu && cd $_/
$ ln -s /usr/share/edgetpu/examples
$ ln -s examples/images
$ ln -s examples/models
$ cp -a examples/classify_image.py ./
$ touch classify_bird.sh
$ chmod a+x classify_bird.sh
~~~

## 計測に利用する model と画像

* 今回はこちらの内容で計測を行います。

	| items | values |
	|:-----:|:------:|
	| classes | inat_bird_labels.txt |
	| model | mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite |
	| photo | parrot.jpg **(1688 x 3064)** |

## classify_image.py の修正

* benchmark のためにコードを少しだけ変更します。
	* inference を **10000 回**繰り返します。
	* model 読み出しや画像データの準備にかかる initialize 処理時間を、  
	inference 回数を増やすことで相対的に薄めています。
		* 適当な計測ですみません。
	* progress bar の代わりに `.` を inference 1 回毎に  
	表示するようにしていますが、無くても問題ありません。

~~~diff
--- examples/classify_image.py	2019-10-05 05:37:16.000000000 +0000
+++ classify_image.py	2019-12-15 13:26:16.598803945 +0000
@@ -19,6 +19,17 @@
 from PIL import Image
 
 
+def classify( engine, labels, img):
+  for result in engine.classify_with_image(img, top_k=3):
+    '''
+    print('---------------------------')
+    print(labels[result[0]])
+    print('Score : ', result[1])
+    '''
+    print( '.', end = '')
+#   '''
+
+
 def main():
   parser = argparse.ArgumentParser()
   parser.add_argument(
@@ -34,10 +45,13 @@
   engine = ClassificationEngine(args.model)
   # Run inference.
   img = Image.open(args.image)
-  for result in engine.classify_with_image(img, top_k=3):
-    print('---------------------------')
-    print(labels[result[0]])
-    print('Score : ', result[1])
+
+  '''
+  classify( engine, labels, img)
+  '''
+  for ii in range( 10000) :
+    classify( engine, labels, img)
+# '''
 
 
 if __name__ == '__main__':
~~~

## 実行スクリプトの作成

* 各測定環境で毎回コマンドを作るのは面倒なので、実行する内容を  
shellscript で **classify_bird.sh** として作っておきます。

~~~
#!/bin/bash

time python3 classify_image.py \
--model models/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite \
--label models/inat_bird_labels.txt \
--image images/parrot.jpg
~~~

## 実行する

* inference を実行し、ログを残します。

~~~
$ ./classify_bird.sh 2>&1 | tee log_pi4_classify_bird_10000.txt
~~~

* 所要時間が表示されたら終了です。

## 計測した環境

* 3 パターン測りました。

	| No. | board | OS | version | architecture |
	|:---:|:-----:|:--:|:-------:|:------------:|
	| 1. | Pi 3B+| Raspbian | stretch | armv7l (32 bit) |
	| 2. | **Pi 4B** | Raspbian | buster  | armv7l (32 bit) |
	| 3. | Pi 4B | **Ubuntu Server** | eoan | aarch64 **(64 bit)** |

## 計測結果の比較

* それぞれの所要時間を見ていきます。

### Pi3 + Raspbian stretch

~~~
log_pi3_classify_bird_10000.txt.gz

real    2m41.553s
user    0m45.873s
sys     0m18.487s
~~~

* 10000 回の inference 完了まで 161.553 秒かかりました。

### Pi4 + Raspbian buster

~~~
log_pi4-buster_classify_bird_10000.txt.gz

real    1m22.209s
user    0m22.376s
sys     0m17.929s
~~~

* USB 3.0 はダテじゃない！約半分の時間で完了しました。

### Pi4 + Ubuntu Server 19.10.1 (eoan)

~~~
log_pi4-eoan_classify_bird_10000.txt.gz

real    1m15.942s
user    0m27.545s
sys     0m15.496s
~~~

* なぜか user 時間は逆に余計に所要していますが、  
実時間としては buster よりも 6 秒ほど早く完了しました。

## 結果一覧

* buster と eoan の性能差はわりと僅差 (1:1.0825) でしたね。
	* 別の機会に Object Detection でやった際も 10 % 程度の良化でした。

	| No. | 所要時間（秒） | 処理回数／秒 | 処理性能比 |
	|:--:|--------:|--------:|--------:|
	| 1. | 161.553 |  61.899 | 1.00000 |
	| 2. |  82.209 | 121.641 | 1.96515 |
	| 3. |  75.942 | 131.679 | 2.12732 |

	* 画像のサイズを VGA 程度に縮小していれば、  
	Pi3 と Pi4 の性能差ももっと開いたかもしれません。

---

## おわりに

* 2019 年は Edge TPU と Pi4 のおかげで、  
Edge AI 環境が安価に、かつ超高速に実行できるようになりました。  
お勉強も Colaboratory でとても手軽に学習を回すことができます。  
さすがは Tech Giant、そして **"AI First"** を標榜する Google 様ですね。  
来年も私たちに未来を見せつけてくれることを期待しています :smiley:

---

## EOF