Coral USB TPU Accelerator(EdgeTPU)をとりあえず使う (Quick Start)

## 【目的】
Coral 社のUSB TPU Accelerator(EdgeTPU)をRaspberry Piにつないで、取りあえず動くかどうかを確認します。

## 【Coral USB TPU Accelerator(EdgeTPU)とは】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/56900ecd-cd5f-99f3-4172-bd735ed4f3f3.png)

Googleが開発したEdge TPU (Tensor Processing Unit)をパソコンやラズパイにUSBでアドオンで追加して、機械学習の推論などを高速に行おうというものです。
現時点ではUbuntuおよびRaspbian(ラズパイのOS )などDebianベースのOSでの動作のみ保証されています。
(いまのところWindowsなどでは動きません)

ラズパイの場合 2または3のModel B/B+が対応していますが、非公式にZeroにも対応しているとのことで、一応公式にも手順が載っています。(こちらは別途チャレンジします)

## 【Quick Start】
基本的には下記URLの「Get started」を実行することで動作確認が行なえます。
[【Coral - Get started with the USB Accelerator】](https://coral.withgoogle.com/docs/accelerator/get-started/)


### 【1. 環境構築】
下記のコマンドを実行します。

```bash

cd ~/

wget https://dl.google.com/coral/edgetpu_api/edgetpu_api_latest.tar.gz -O edgetpu_api.tar.gz --trust-server-names

tar xzf edgetpu_api.tar.gz

cd edgetpu_api

bash ./install.sh
```

内容的にはホームディレクトリに必要なファイルをダウンロードし解凍した後に、解凍したファイル内の```install.sh```を実行して環境構築を行います。
途中```Would you like to enable the maximum operating frequency? Y/N```(最大動作周波数を有効にしますか？)と聞かれますので```Y```を入力して先に進みます。
※ 最大周波数を有効にした場合、発熱でやけどなどする可能性があるとのことです。
　ただし、ラズパイ3の場合、USBが2.0のためEdgeTPUの最大性能を発揮できず、やけどするほど発熱したことはありません。

以下のような表示がでて、インストール作業が完了します。

```結果.txt
./install.sh: 行 51: 警告: command substitution: ignored null byte in input
Recognized as Raspberry Pi 3 B.
Warning: During normal operation, the Edge TPU Accelerator may heat up, depending
on the computation workloads and operating frequency. Touching the metal part of the
device after it has been operating for an extended period of time may lead to discomfort
and/or skin burns. As such, when running at the default operating frequency, the device is
intended to safely operate at an ambient temperature of 35C or less. Or when running at
the maximum operating frequency, it should be operated at an ambient temperature of
25C or less.

Google does not accept any responsibility for any loss or damage if the device is operated
outside of the recommended ambient temperature range.
.............................................................
Would you like to enable the maximum operating frequency? Y/N
y
Using maximum operating frequency.
Installing library dependencies...
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了

【... 中略 ...】

Installing device rule file [/etc/udev/rules.d/99-edgetpu-accelerator.rules]...
Done.
Installing Edge TPU runtime library [/usr/lib/arm-linux-gnueabihf/libedgetpu.so.1.0]...
Done.
Installing Edge TPU Python API...
Processing ./edgetpu-1.9.2-py3-none-any.whl
Installing collected packages: edgetpu
Successfully installed edgetpu-1.9.2
Done.
```

### 【2. ラズパイにEdgeTPUを接続する】
付属のUSBケーブルを使ってラズパイにEdgeTPUを接続します。
すでに接続済みの場合は一旦外して接続し直します。(← 一旦外さないとこの後の工程でエラーになります)

下記コマンドを実行し、接続状況を確認します。

```bash
lsusb
```

```出力結果.txt
Bus 001 Device 005: ID 045e:0737 Microsoft Corp. Compact Optical Mouse 500
Bus 001 Device 004: ID 0dc6:3100 Precision Squared Technology Corp.
Bus 001 Device 007: ID 18d1:9302 Google Inc.    (← これがEdgeTPU)
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
```
`18d1:9302 Google Inc.`の表示があれば、EdgeTPUを認識しています。


### 【3. サンプルモデルを使って推論を行う】
まずは以下のコマンドを実行して、必要なファイルを```~/Downloads```フォルダにダウンロードします。

```bash
cd ~/Downloads/

wget https://dl.google.com/coral/canned_models/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite \
https://dl.google.com/coral/canned_models/inat_bird_labels.txt \
https://coral.withgoogle.com/static/docs/images/parrot.jpg
```
- mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite  
学習済みのモデルファイルです。  
何を使っても良いですが、今回のモデルは鳥に特化したモデルです。  
下記のラベルファイル内を確認したところ965種類の鳥が区別できるようです。  
- inat_bird_labels.txt  
ラベルファイルです。  
推論結果は数値で返ってくるため、数値から名称に変換する際に使います。  
モデルファイルとセットで利用します。  
- parrot.jpg  
今回推論に使う画像ファイルです。  
本ファイルは以下の画像になります。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/5c305268-32b3-ad1c-8c8d-0f4c223904c6.png)


以下のコマンドを使って推論を行います。
内容的には```classify_image.py```というサンプルプログラムに対して、上記でダウンロードしたファイルをパラメータ```--model```、```--label```、```--image```にそれぞれに指定してを実行します。

```bash
cd /usr/local/lib/python3.5/dist-packages/edgetpu/demo

python3 classify_image.py \
--model ~/Downloads/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite \
--label ~/Downloads/inat_bird_labels.txt \
--image ~/Downloads/parrot.jpg
```

以下の結果が表示されれば推論できています。

```結果.txt
---------------------------
Ara macao (Scarlet Macaw)
Score :  0.761719
---------------------------
```
この場合、76%の確率で「Ara macao」(コンゴウインコ)と推論されています。

適当な画像をダウンロードしてきて、ダウンロードしたファイルを```--image```パラメータで指定すれば、他の画像でも推論できます。
フリー素材などをを使っていくつかの画像で検証検証してみましたが、ほぼ思い通りの結果が得られました。
Eurasian Tree Sparrow(スズメ)などのアジア圏の鳥も認識してくれました。

以上で動作確認は完了です。


##  【トラブルシュート】
サンプルプログラム「classify_image.py」実行時にエラーで失敗する場合があります。

### 【ケース1】
```エラーケース1.txt
Traceback (most recent call last):
  File "classify_image.py", line 67, in <module>
    main()
  File "classify_image.py", line 58, in main
    engine = ClassificationEngine(args.model)
  File "/usr/local/lib/python3.5/dist-packages/edgetpu/classification/engine.py", line 38, in __init__
    super().__init__(model_path)
  File "/usr/local/lib/python3.5/dist-packages/edgetpu/swig/edgetpu_cpp_wrapper.py", line 300, in __init__
    this = _edgetpu_cpp_wrapper.new_BasicEngine(*args)
RuntimeError: Failed to allocate tensors.
```
EdgeTPUを接続したまま環境構築を行い、そのままサンプルプログラムを実行した際に上記エラーが発生しました。
一度EdgeTPUを外して再接続したところ、うまく実行することができました。
(おそらく再起動でも良いと思われる)


### 【ケース2】
```エラーケース2.txt
Traceback (most recent call last):
  File "classify_image.py", line 67, in <module>
    main()
  File "classify_image.py", line 58, in main
    engine = ClassificationEngine(args.model)
  File "/usr/local/lib/python3.5/dist-packages/edgetpu/classification/engine.py", line 38, in __init__
    super().__init__(model_path)
  File "/usr/local/lib/python3.5/dist-packages/edgetpu/swig/edgetpu_cpp_wrapper.py", line 300, in __init__
    this = _edgetpu_cpp_wrapper.new_BasicEngine(*args)
RuntimeError: No Edge TPU device detected!
```
単純にEdgeTPUが接続されていない、または認識されていません。
USBに接続するか、再接続してみてください。

それでもダメな場合は…