Coral USB TPU Accelerator(EdgeTPU)をWindows端末で使う

## 【内容】
過去に[Windowsで擬似的にEdgeTPUを使う記事](https://qiita.com/rhene/items/e7574715844784b86a15)を投稿しましたが、Coralの公式のEdgeTPUの導入手順にWindows版が追加されていたので試してみました。
下記の公式手順を踏襲していますが、一部そのままでは実行できないので手を入れています。

[【Get started with the USB Accelerator On Windows - Coral】](https://coral.ai/docs/accelerator/get-started#on-windows)


## 【Requirements】
- Windows10 64bit
- python3.7 + pip
- git コマンド


## 【必要モジュールのダウンロード & インストール】
公式手順に従い以下のURLよりダウンロードします。
[【 download edgetpu_runtime_20200128.zip - Coral】](https://dl.google.com/coral/edgetpu_api/edgetpu_runtime_20200128.zip)
今回、このファイルが追加されたことで正式にWindowsからEdgeTPUにアクセスできるようになりました。

ダウンロードしたモジュールを解凍すると以下のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/dcf4ed0b-389d-29b4-974c-c6daa61259b5.png)

解凍したファイルの中の `install.bat` を管理者権限で実行します。
すると、お決まりの最大周波数で実行するかどうかを聞いてきますので `y` または `n` を入力して先に進みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/0cbd1717-2a36-c82c-0104-f8fd14b458cd.png)

先に進むと「UsbDk」のインストールが開始されます。
(UsbDKのインストール中はUSBマウスなどが効かなくなります)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/78f3f982-6432-d564-e0fb-fa79f3b36806.png)

続いて「EdgeTPUのドライバ」をインストールします。
下記画面で「インストール」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/4c0c8b6a-da2f-3d47-4a7a-19caacc68528.png)

以上でセットアップ完了です。

## 【デバイスの確認】
上記が完了したら、EdgeTPUをUSBコネクタに接続してみます。
うまくいっている場合はデバイスマネージャにて以下のように「Coral USB Accelerator」が認識されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/5a8a3e4e-8ca0-2ecf-c85b-e2af9aa29cea.png)


## 【TensorFlow Liteのインストール】
続いてTensorFlow Liteをインストールします。
インストール用のパッケージのURLは以下を参照して、環境に応じて変更してください。
[【TensorFlow Lite Python quickstart】](https://www.tensorflow.org/lite/guide/python)

本例の場合、「Windows10」で「Python3.7」ですので以下のようになります。

```tfliteのインストール.ps1
pip install https://dl.google.com/coral/python/tflite_runtime-2.1.0-cp37-cp37m-win_amd64.whl
```



## 【サンプルプログラムの実行】
まずは、下記コマンドを実行してサンプルプログラム用のリポジトリをクローンします。

なお、以降の操作は 「**PowerShell**」 を用いて実行することを想定していますが、途中の `wget` コマンドを使いたいだけですので、それ以外はコマンドプロンプトからでも実行可能です。

```リポジトリのクローン.ps1
cd (適当なフォルダ)
git clone https://github.com/google-coral/tflite.git
```

Linux環境ではクローンしたリポジトリの`tflite/python/examples/classification` 内の `install_requirements.sh`を実行すれば必要な環境ができあがりますがWindowsでは実行不能です。
そこで、以下のコマンドを実行して手動で環境を整えます。

まずはサンプルプログラムの依存モジュールをインストールします。

```依存モジュールのインストール.ps1
# 依存モジュールのインストール
pip install numpy Pillow
```

続いてモデルやラベルなど、必要なファイルをダウンロードします。
PowerShellでは `wget` コマンドを利用してファイルをダウンロードすることが可能です。

```モデルとラベルと画像の取得.ps1
cd tflite/python/examples/classification

# モデルのDL
wget https://github.com/google-coral/edgetpu/raw/master/test_data/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite -O mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite

# ラベルのDL
wget https://github.com/google-coral/edgetpu/raw/master/test_data/inat_bird_labels.txt -O inat_bird_labels.txt

# 推論用の画像のDL
wget https://github.com/google-coral/edgetpu/raw/master/test_data/parrot.jpg -O parrot.jpg
```

上記が完了したら、サンプルプログラムを動かして推論をしてみます。

```推論実行.ps1
python .\classify_image.py --model mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite --labels inat_bird_labels.txt --input parrot.jpg
```

下記のような結果が表示されたら正常に動いています。

```実行結果
----INFERENCE TIME----
Note: The first inference on Edge TPU is slow because it includes loading the model into Edge TPU memory.
12.5ms
4.4ms
3.5ms
4.1ms
4.3ms
-------RESULTS--------
Ara macao (Scarlet Macaw): 0.76562
```

## 【EdgeTPUのPython APIのインストール】 (2020/02/03 追記)
続いてPython APIをインストールします。
インストール用のwhlファイルは以下に置いてあります。
[【Edge TPU Python API for Mac and Windows 】](https://coral.ai/software/#edgetpu-python-api)

本例の場合、「Windows10」で「Python3.7」ですので以下のようになります。

```PythonAPIのインストール.ps1
pip install https://dl.google.com/coral/edgetpu_api/edgetpu-2.13.0-cp37-cp37m-win_amd64.whl
```

インストールが完了したら、バージョンを確認してみます。
2020/02/03時点では `2.13.0` になります。

```PythonAPIのバージョン確認.ps1
python -c "import edgetpu;print(edgetpu.__version__)"    
```
```
2.13.0
```

続いてPCが認識しているEdgeTPUを確認してみます。
以下のコマンドを実行すると、接続中のEdgeTPUが返ってきます。

```EdgeTPUデバイスリスト.ps1
python -c "from edgetpu.basic import edgetpu_utils;print(edgetpu_utils.ListEdgeTpuPaths(edgetpu_utils.EDGE_TPU_STATE_UNASSIGNED))" 
```
下記例では3つのEdgeTPUを認識しています。

```
('/sys/bus/usb/devices/1-13', '/sys/bus/usb/devices/1-3', '/sys/bus/usb/devices/1-14')                                   
```


## 【最後に】
とりあえず、正式にWinodws環境でEdgeTPUを使うことが出来るようになりました。
これでLinuxなどで稼働するEdgeデバイスにアレルギーのあるおじさん達を丸め込めるようになります。

もっともWindows端末でわざわざEdgeTPUを使うメリットがあるのか? という疑問は残りますが…