エッジデバイスでTensorFlow Liteをビルドしてインストールする

# はじめに
今回はエッジデバイスでTensorFlow Liteをビルドしてインストールする方法を紹介します。ビルド済みのwheelファイルが用意されていないエッジデバイスでも、実機でビルドすることでTensorFlow Liteを使えるようになります。

# 動作確認済みデバイス
動作確認済デバイス（OS）

- e-RT3 Plus F3RP70-2L[^ert3]（Ubuntu 18.04 32bit）

このデバイスでは armhf アーキテクチャのパッケージが動作します。

# 準備
TensorFlow Liteのビルドに必要なツールをインストールします。
## CMakeのインストール
必要なパッケージをインストールします。

```bash
sudo apt update
sudo apt install libssl-dev
```

>**Note**
>デバイスがproxy環境下にある場合は[proxy設定](https://qiita.com/Yokogawa_Mita/items/f7996d539b29618d7159#proxy%E8%A8%AD%E5%AE%9A)が必要です。

CMakeをダウンロードしてインストールします。[^cmake]
ビルドには数十分~数時間かかります。

```bash
#ダウンロード
wget https://github.com/Kitware/CMake/releases/download/v3.26.1/cmake-3.26.1.tar.gz
tar zxvf cmake-3.26.1.tar.gz

#ビルド
cd cmake-3.26.1
./bootstrap
make

#インストール
sudo make install
cd ..

#再起動
sudo reboot
```

インストールが完了したら以下のコマンドを実行してインストールの成功を確認します。

```bash
username@ubuntu:~$ cmake --version
cmake version 3.26.1

CMake suite maintained and supported by Kitware (kitware.com/cmake).
```

## パッケージのインストール
以下のコマンドでインストールします。[^tflite_dependancy]

```bash
sudo apt install swig libjpeg-dev zlib1g-dev python3-dev python3-numpy
python3 -m pip install pybind11
```

# TensorFlow Liteのビルド
ソースコードをダウンロードし、タグv2.8.0に切り替えます。

```bash
git clone https://github.com/tensorflow/tensorflow.git tensorflow_src
cd tensorflow_src
git checkout v2.8.0
```

>**Note**
>今回はv2.8.0のビルドを行います。
>最新版ではありませんのでご注意ください。

ビルド用のスクリプト`tensorflow_src/tensorflow/lite/tools/pip_package/build_pip_package_with_cmake.sh`を編集します。
ファイル先頭に以下の行を追加してビルド時のジョブ数を1とし、ビルド時のメモリ不足を防ぎます。

```bash:build_pip_package_with_cmake.sh
BUILD_NUM_JOBS=1
```

`-DTFLITE_ENABLE_XNNPACK=OFF \`を以下のように追記して、今回使用するエッジデバイスで使用不可能な機能のビルドを行わないようにします。

```bash:build_pip_package_with_cmake.sh
native)
BUILD_FLAGS=${BUILD_FLAGS:-"-march=native -I${PYTHON_INCLUDE} -
I${PYBIND11_INCLUDE}"}
cmake \
    -DCMAKE_C_FLAGS="${BUILD_FLAGS}" \
    -DCMAKE_CXX_FLAGS="${BUILD_FLAGS}" \
    -DTFLITE_ENABLE_XNNPACK=OFF \ #追記
    "${TENSORFLOW_LITE_DIR}"
;;
```

ビルドを実行します。wheelファイルが`tensorflow/lite/tools/pip_package/gen/tflite_pip/python3/dist/`に作成されます。

```bash
PYTHON=python3 tensorflow/lite/tools/pip_package/build_pip_package_with_cmake.sh native
cd ..
```

>**Note**
>ビルドしたwheelファイルを保存しておけば、ほかのデバイスへのインストールは[TensorFlow Liteのインストール](#tensorflow-liteのインストール)の手順のみで行えます。

# TensorFlow Liteのインストール
仮想環境を作成してTensorFlow Liteをインストールします。
必要なパッケージをインストールして仮想環境を作成、有効化します。

```bash
sudo apt install python3-venv
python3 -m venv tf-env --system-site-packages
source tf-env/bin/activate
```

インストールを行います。`<TF_WHEEL_FILE>`の部分はビルドで作成されたTensorFlow Liteのwheelファイルの名前で置き換えてください。

```bash
(tf-env)  pip install wheel
(tf-env)  pip install cython numpy tensorflow_src/tensorflow/lite/tools/pip_package/gen/tflite_pip/python3/dist/<TF_WHEEL_FILE> --no-cache-dir
```

# 動作確認
サンプルプログラム[^tflitedemo]を実行してTensorFlow Liteのインストールの成功を確認します。

ディレクトリを作成して必要なファイルをダウンロードします。

```bash
(tf-env)  mkdir tmp

#推論する画像のダウンロード
(tf-env)  curl https://raw.githubusercontent.com/tensorflow/tensorflow/master/tensorflow/lite/examples/label_image/testdata/grace_hopper.bmp > tmp/grace_hopper.bmp

#学習済みモデルのダウンロード
(tf-env)  curl https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_1.0_224.tgz | tar xzv -C tmp

#ラベル情報のダウンロード
(tf-env)  curl https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_1.0_224_frozen.tgz | tar xzv -C tmp mobilenet_v1_1.0_224/labels.txt
mv tmp/mobilenet_v1_1.0_224/labels.txt tmp/

#サンプルコードのダウンロード
(tf-env)  curl https://raw.githubusercontent.com/tensorflow/tensorflow/master/tensorflow/lite/examples/python/label_image.py > label_image.py
```

ダウンロードしたサンプルコード`label_image.py`をTensorFlow Lite用に書き換えます。

```python:label_image.py
#変更前
import tensorflow as tf
#変更後
import tflite_runtime.interpreter as tflite

#変更前
interpreter = tf.lite.Interpreter(model_path=args.model_file, num_threads=args.num_threads)
#変更後
interpreter = tflite.Interpreter(model_path=args.model_file, num_threads=args.num_threads)
```

プログラムを実行します。以下のような出力があれば成功です。

```bash
(tf-env)  python label_image.py \
  --model_file tmp/mobilenet_v1_1.0_224.tflite \
  --label_file tmp/labels.txt \
  --image tmp/grace_hopper.bmp

0.792127: 653:military uniform
0.084584: 907:Windsor tie
0.021034: 458:bow tie, bow-tie, bowtie
0.009951: 668:mortarboard
0.007782: 514:cornet, horn, trumpet, trump
time: 2637.867ms
```

結果より、military uniformのスコアが最も高く0.79となっていることから、画像をうまく認識できていることが分かります。
![grace_hopper.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/90d6f842-c333-224c-f2c2-6ef03f953492.jpeg)


# まとめ
今回はエッジデバイスでのTensorFlow Liteのインストールとサンプルプログラムの実行を行いました。エッジデバイスでTensorFlowによる機械学習の推論を行うことができ、アプリケーションの幅が広がります。是非お試しください。

[^ert3]: [産業用AIプラットフォーム | 横河電機株式会社](https://www.yokogawa.co.jp/solutions/products-platforms/control-system/real-time-os-controller/ert3-ai-platform/)
[^cmake]: [GitHub - Kitware/CMake: Mirror of CMake upstream repository](https://github.com/Kitware/CMake#building-cmake-from-scratch)
[^tflitedemo]: [tensorflow/tensorflow/lite/examples/python at master · tensorflow/tensorflow · GitHub](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/examples/python/)
[^tflite_dependancy]: [tensorflow/tensorflow/lite/tools/pip_package at master · tensorflow/tensorflow · GitHub](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/tools/pip_package#building-tensorflow-lite-standalone-pip)