VIA VAB-5000上にTensorFlow Lite for C++の開発環境を構築するために、x86-64 Ubuntu22.04上でTensorFlow Lite for C/C++のソースコードをaarch64向けにクロスコンパイルする

# TensorFlow Lite for C/C++ on VAB-5000

前回の記事で産業用Raspberry Piに代わるAPU搭載のシングルボードコンピュータ「VAB-5000」について紹介しました。このVAB-5000の **APU(AI Processing Unit)であるMDLA(MediaTek Deep Learning Accelerator)** を最大限に活用できるAIアプリケーションを開発するためには、TensorFlow Lite for C/C++を利用して **Delegate** と呼ばれる、アクセラレーターを呼び出すプログラムを書く必要があります。今回はその前段階となる **TensorFlow Lite for C/C++ (Delegate無し)** をビルドしてサンプルソースコードをコンパイルする手順をご紹介します。

https://qiita.com/xtrizeShino/items/cf2d44adea29a0b31050

![DSC01556.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/74a100ef-5451-4841-b02d-a33e0cc0076b.jpeg)

#### SoCベンダーのMediaTekが推奨するDelegateの記述例

C/C++で書かないとDelegateにアクセスできません...今回はそのための準備です！

https://mediatek.gitlab.io/genio/doc/tao/npu_acceleration.html

#### 本記事の目的

今回は以上の開発を行うべく、VIA VAB-5000環境上にTensorFlow Lite for C/C++の開発環境を構築する手順についてご紹介いたします。VAB-5000上でTensorFlow Lite for C++を直接ビルドすることはできないため、 **本手順では、x86-64 Ubuntu22.04上でTensorFlow Lite for C/C++のソースコードをaarch64向けにクロスコンパイル** します。

https://www.viatech.com/ja/edge-ja/vab-5000/

#### 参考：x86-64向けのTensorFlow Lite for C/C++をビルドする手順

x86-64版のTensorFlow Lite for C/C++を利用したい方はこちらをご覧ください。

https://qiita.com/xtrizeShino/items/4d521ebf06a3f40a9490

## 開発環境を準備をする

まず、 **OSのインストールや開発に便利なツールなどのインストールを行い、** TensorFlow Lite for C/C++をインストールするための土台を組み上げていきます。

- Core i5-14600K (14cores, 20threads)
- RAM 64GB
- On-Board Graphics (CPU)
- Ubuntu 22.04 LTS
  - Yocto Linux等、併設する他の開発環境も考慮しました

### Ubuntu 22.04 LTSをインストールする

まず、PCに「Ubuntu22.04 LTS」をインストールします。以下のインストーラーを利用し、インストールしました。今回はGPUを搭載せず、マザーボード上のオンボードのHDMIポートを利用しました。

https://releases.ubuntu.com/jammy/

![ubuntu2204](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F3919880%2F0b35301c-d7fd-4b4f-fdd8-d955714ce393.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=455a0326e98c3c5154ae2e5530e4c1ca)

## TensorFlow for C/C++をビルドする準備をする

それでは TensorFlow Lite for C/C++ のビルドをはじめていきましょう。ビルドには **`bazel`** 、 **`clang`**、**`その他いくつかのパッケージ`** が必要になるため、事前にインストールします。

### ビルドに必要なパッケージをインストールする

`apt` コマンドで以下のパッケージをインストールしましょう。

```bash
$ sudo apt update
$ sudo apt install -y vim 
$ sudo apt install -y linux-headers-$(uname -r) build-essential wget git cmake clang lldb lld
$ sudo apt install -y python3-dev python3-pip python3.10-venv
$ python3 -m pip install -U --user pip
$ sudo apt install -y libopencv-dev ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libxml2 libstdc++6
```

### ビルドツール「bazel」をインストールする

続いて、TensorFlow Liteをビルドするための `bazel` をインストールしましょう。

https://bazel.build/install/ubuntu?hl=ja

```bash
$ sudo apt install -y apt-transport-https curl gnupg
$ curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor >bazel-archive-keyring.gpg
$ sudo mv bazel-archive-keyring.gpg /usr/share/keyrings
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/bazel-archive-keyring.gpg] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
$ sudo apt update && sudo apt install bazel
```

### ビルドツール「clang」をインストールする

加えて、TensorFlow Liteをコンパイルするための `clang` をインストールします。

```bash
$ wget https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.2/clang+llvm-17.0.2-x86_64-linux-gnu-ubuntu-22.04.tar.xz
$ tar -xvf clang+llvm-17.0.2-x86_64-linux-gnu-ubuntu-22.04.tar.xz
$ sudo cp -r clang+llvm-17.0.2-x86_64-linux-gnu-ubuntu-22.04/* /usr
$ clang --version
# clang version 17.0.2 (https://github.com/llvm/llvm-project b2417f51dbbd7435eb3aaf203de24de6754da50e)
# Target: x86_64-unknown-linux-gnu
# Thread model: posix
# InstalledDir: /usr/bin
```

**以上で、クロスビルドするための準備は完了となります。**

## TensorFlow Lite for C/C++をクロスコンパイルする

それでは、TensorFlow Lite for C/C++をaarch64向けにビルドしてみましょう。

### GithubからTensorFlowの<font color="red">【v2.16.1】</font>を入手する。

まず、`tensorflow` のリポジトリから `git` コマンドを使ってソースコード一式を入手し、**`git checkout` コマンドで `v2.16.1` のソースコードへと切り替えます。** 私が試したところ、他のバージョンを利用するとエラーが発生してビルドの通らないことが頻発したため、下記の記事で実績のある `v2.16.1` を選択しました。

https://daisuke20240310.hatenablog.com/entry/raspi2

https://www.tensorflow.org/lite/guide/build_arm64?hl=ja

https://zenn.dev/079aefdf/articles/90cc6343532c35

```bash
### 作業用ディレクトリを作成する
$ mkdir cross_tensorflow
$ cd cross_tensorflow/

### tensorflowのソースコードを取得する
$ git clone https://github.com/tensorflow/tensorflow.git
$ cd tensorflow

### 今回はv2.16.1をビルドする
$ git checkout v2.16.1
```

### TensorFlow Lite for C/C++をビルドする

ビルドする前に **`./configure` を実行してビルドの構成を決定** します。今回はGPUアクセラレーションを利用しない、以下の構成としました。 `./configure` を行った後、 **`bazel build` コマンドでTensorFlow Lite for C/C++をビルド** します。なお、本手順には `bazel-6.5.0` が必要だったため、`apt` コマンドでバージョンを変更しました。

https://www.tensorflow.org/lite/guide/build_arm64?hl=ja

```bash
### ビルドの設定を行う
$ ./configure
# You have bazel 6.5.0 installed.
# Please specify the location of python. [Default is /home/shino/anaconda3/bin/python3]: 
# Found possible Python library paths:
#   /home/shino/anaconda3/lib/python3.12/site-packages
# Please input the desired Python library path to use.  Default is [/home/shino/anaconda3/lib/python3.12/site-packages]
# Do you wish to build TensorFlow with ROCm support? [y/N]: N
# No ROCm support will be enabled for TensorFlow.
# Do you wish to build TensorFlow with CUDA support? [y/N]: N
# No CUDA support will be enabled for TensorFlow.
# Do you want to use Clang to build TensorFlow? [Y/n]: Y
# Clang will be used to compile TensorFlow.
# Please specify the path to clang executable. [Default is /usr/bin/clang]: 
# You have Clang 17.0.2 installed.
# Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -Wno-sign-compare]: 
# Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]: N
# Not configuring the WORKSPACE for Android builds.
# 
# Preconfigured Bazel build configs. You can use any of the below by adding "--config=<>" to your build command. See .bazelrc for more details.
# 	--config=mkl         	# Build with MKL support.
# 	--config=mkl_aarch64 	# Build with oneDNN and Compute Library for the Arm Architecture (ACL).
# 	--config=monolithic  	# Config for mostly static monolithic build.
# 	--config=numa        	# Build with NUMA support.
# 	--config=dynamic_kernels	# (Experimental) Build kernels into separate shared objects.
# 	--config=v1          	# Build with TensorFlow 1 API instead of TF 2 API.
# Preconfigured Bazel build configs to DISABLE default on features:
# 	--config=nogcp       	# Disable GCP support.
# 	--config=nonccl      	# Disable NVIDIA NCCL support.
# Configuration finished

### ビルドができるか試してみる
$ bazel build --config=elinux_aarch64 -c opt //tensorflow/lite/c:libtensorflowlite_c.so
# ERROR: The project you're trying to build requires Bazel 6.5.0 (specified in /home/shino/tensorflow/.bazelversion), but it wasn't found in /usr/bin.
# 
# You can install the required Bazel version via apt:
#   sudo apt update && sudo apt install bazel-6.5.0
# ...

### bazelのバージョンを指定してインストールしなおす
$ sudo apt update && sudo apt install bazel-6.5.0

### 再度ビルドする
# C++ライブラリをクロスビルドする
$ bazel build --config=elinux_aarch64 -c opt //tensorflow/lite/c:libtensorflowlite_c.so

# Cライブラリをクロスビルドする
$ bazel build --config=elinux_aarch64 -c opt //tensorflow/lite:libtensorflowlite.so

# Delegateを呼び出す際に利用するライブラリもクロスビルドする
$ bazel build --config=elinux_aarch64 -c opt //tensorflow/lite/experimental/acceleration/compatibility:android_info
$ bazel build --config=elinux_aarch64 -c opt //tensorflow/lite/delegates/utils/experimental/stable_delegate:tflite_settings_json_parser
$ bazel build --config=elinux_aarch64 -c opt //tensorflow/lite/delegates/utils/experimental/stable_delegate:delegate_loader
```

### ビルド成果物を確認する

以下がビルドの成果物となります。 **正しく `aarch64` 向けにビルドされているか** を `file` コマンドを使って確認しておきましょう。

```bash
### C++ライブラリがArm用にビルドされていることを確認する
$ file bazel-bin/tensorflow/lite/libtensorflowlite.so
# bazel-bin/tensorflow/lite/libtensorflowlite.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[md5/uuid]=6dc411bc5ff781a5d77bec37cf4d46b3, stripped

### CライブラリがArm用にビルドされていることを確認する
$ file bazel-bin/tensorflow/lite/c/libtensorflowlite_c.so
# bazel-bin/tensorflow/lite/c/libtensorflowlite_c.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[md5/uuid]=1ffb549a913b1a1d161a8ab9ed3cc11f, stripped
```

### ビルド成果物をtensorflowのディレクトリ内にコピーする

本手順によるビルドでは、ビルドの成果物は `tensorflow` のディレクトリ内ではなく、`~/.cache/bazel` 以下に格納されます。ディレクトリ名はランダムで決まりますので、ビルド後の `tensorflow` ディレクトリで **`ls -al bazel-tensorflow`** をすると確認することができます。確認後、対象のディレクトリを `tensorflow` ディレクトリ以下へコピーし、シンボリックリンクを貼り直し `tensorflow` ディレクトリのみで完結するフォルダ構成にします。

```bash
### ビルド成果物を tensorflow ディレクトリ内にコピーする
### -->> ソースコードとまとめてVAB-5000にコピーするため
$ cp ~/.cache/bazel/_bazel_shino/6bb7e8b4bffe091da9c41eb8a1440c54/execroot/org_tensorflow ~/cross_tensorflow/tensorflow/org_tensorflow -r

### bazel-bin ディレクトリのシンボリックリンクを貼り直す
$ rm bazel-bin
$ ln -s org_tensorflow/bazel-out/aarch64-opt/bin/ ./bazel-bin
$ ls bazel-bin
# bin   external  tensorflow

### bazel-out ディレクトリのシンボリックリンクを貼り直す
$ rm bazel-out
$ ln -s org_tensorflow/bazel-out ./bazel-out
$ ls bazel-out
# _actions  aarch64-opt           stable-status.txt
# _tmp      k8-opt-exec-50AE0418  volatile-status.txt

### bazel-tensorflow ディレクトリのシンボリックリンクを貼り直す
$ rm bazel-tensorflow
$ ln -s org_tensorflow ./bazel-tensorflow
$ ls bazel-tensorflow
# bazel-out  external  tensorflow  third_party

### bazel-testlogsディレクトリのシンボリックリンクを貼り直す
$ rm bazel-testlogs
$ ln -s org_tensorflow/bazel-out/aarch64-opt/testlogs ./bazel-testlogs
$ ls bazel-testlogs
# empty
```

### ビルド成果物をtarに固めてUSBフラッシュメモリにコピーする

以上でaarch64(VAB-5000のアーキテクチャ)向けのTensorFlow Lite for C/C++の準備が整いましたので `tensorflow` ディレクトリを `tar` でまとめて、USBフラッシュメモリへ書き出しましょう。

```bash
### クロスコンパイルした成果物をtarに固めて、USBフラッシュへコピーする
$ tar -cvf tensorflow.tar ./tensorflow
$ ls ./tensorflow.tar
# tensorflow.tar
### USBフラッシュが "/media/shino/23D8-AF6D/" の場合の例
$ cp tensorflow.tar /media/shino/23D8-AF6D/
### 書き込み後umoundする
$ sudo umount /media/shino/23D8-AF6D
```

### VAB-5000上にTensorFlowを利用したアプリ開発によく利用されるパッケージをインストールする <font color="red">**(VAB-5000上での操作)**</font>

VAB-5000上にTensorFlow Lite for C++をインストールする前に、TensorFlowを使って推論するプログラムによく利用されるパッケージを `apt` でインストールします。 **特に、最後の `libabsl-dev` はTensorFlow Lite for C/C++でDelegateを利用する際に必要とされるパッケージです。**

https://packages.debian.org/unstable/libabsl-dev

https://github.com/abseil/abseil-cpp?tab=readme-ov-file

```bash
### 一般的な開発ツールをインストールする
$ sudo apt update
$ sudo apt install -y vim 
$ sudo apt install -y build-essential wget git curl cmake clang lldb lld
$ sudo apt install -y python3-dev python3-pip python3-venv
$ sudo apt install -y libopencv-dev ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libxml2 libstdc++6
$ sudo apt install -y libabsl-dev
$ sudo find / -type f | grep cleanup.h
# /usr/include/absl/cleanup/cleanup.h
```
 
### USBフラッシュメモリからクロスコンパイルしたTensorFlow Liteをホームディレクトリへコピーする <font color="red">**(VAB-5000上での操作)**</font>

クロスコンパイルの結果得られたTensorFlow Lite for C/C++をVAB-5000のホームディレクトリ(`/home/debian`)以下にUSBフラッシュメモリからコピーし `tar` で展開します。

```bash
### クロスコンパイルしたTensorFlowをVAB-5000上に展開する
$ cp /media/shino/23D8-AF6D/tensorflow.tar ~/
$ tar -xvf tensorflow.tar
```

### TensorFlow Lite for C++が利用するflatbuffersをソースコードからコンパイルする <font color="red">**(VAB-5000上での操作)**</font>

TensorFlow Lite for C/C++でTFLite形式のモデルを読み込む際に `flatbuffers` というライブラリが必要となります。`git` コマンドにより、FlatBuffersのソースコードを入手し、 `git checkout` コマンドでTensorFlowの要求するFlatBuffersのバージョンにソースコードを切り替えます。その後 `cmake` を利用してFlatBuffersをビルドします。


https://github.com/google/flatbuffers/releases/tag/v23.5.26

```bash
### FlatBuffers 23.5.26を入手する
$ cd ~
$ git clone https://github.com/google/flatbuffers.git
$ cd flatbuffers
$ git checkout v23.5.26

### FlatBuffersをビルドする
$ mkdir build
$ cd build/
$ cmake ..
$ make
```

# TensorFlow Lite for C/C++を利用する <font color="red">**(VAB-5000上での操作)**</font>


それでは実際に、ビルドしたTensorFlow Lite for C/C++を利用してみましょう。TensorFlow Lite for C/C++を呼び出すためのコードは、以下のサイトで非常にわかりやすく書かれていました。とても参考になりました、ありがとうございます。

https://qiita.com/iwatake2222/items/796ec8560563625ace34

https://qiita.com/iwatake2222/items/d63aa67e5c700fcea70a

https://qiita.com/iwatake2222/items/d998df1981d46285df62

https://www.tensorflow.org/lite/guide/inference?hl=ja

#### 以上のサイトを参考に収集したソースコード

以下のリポジトリが、以降の手順をまとめたソースコードとなります。 **`CMakeLists.txt`に含まれているディレクトリのパスは、実行環境に合わせて調整してください。**

https://github.com/xtrizeShino/qiita_mnist_with_tflite_cpp/blob/main/README.md

### ビルドしたTensorFlow Lite for C++を参照するCMakeLists.txt <font color="red">**(VAB-5000上での操作)**</font>

まず `CMakeLists.txt` を記述します。 `CMakeLists.txt` は `cmake` コマンドを実行した際に呼び出され、`Makefile` を自動的に生成するためのファイルです。 **ファイルパスに上記でビルドしたTensorFlow Lite for C/C++のフォルダ位置を記述してください。** 私の手順ではVAB-5000上の `/home/debian/tensorflow` にTensorFlow for C++を配置したため、以下のような記述となりました。

https://qiita.com/iwatake2222/items/d998df1981d46285df62

```cmake
cmake_minimum_required(VERSION 2.8)
project(NumberDetector)

# Create Main project
add_executable(NumberDetector
	main.cpp
)

# For OpenCV
find_package(OpenCV REQUIRED)
if(OpenCV_FOUND)
	target_include_directories(NumberDetector PUBLIC ${OpenCV_INCLUDE_DIRS})
	target_link_libraries(NumberDetector ${OpenCV_LIBS})
endif()

# For Tensorflow Lite
target_link_libraries(NumberDetector /home/debian/tensorflow/bazel-bin/tensorflow/lite/libtensorflowlite.so)
target_include_directories(NumberDetector PUBLIC /home/debian/tensorflow)
target_include_directories(NumberDetector PUBLIC /home/debian/tensorflow/tensorflow)
target_include_directories(NumberDetector PUBLIC /home/debian/tensorflow/tensorflow/lite)
target_include_directories(NumberDetector PUBLIC /home/debian/flatbuffers/include)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  -std=c++17 -lstdc++")

# Copy resouce
file(COPY ${CMAKE_SOURCE_DIR}/resource/ DESTINATION ${PROJECT_BINARY_DIR}/resource/)
add_definitions(-DRESOURCE_DIR="${PROJECT_BINARY_DIR}/resource/")
```

### TensorFlow for C++を呼び出すソースコード <font color="red">**(VAB-5000上での操作)**</font>

TensorFlowを呼び出すソースコードは、以下の記事よりお借りしました。実行には、**入力となる画像ファイル（ここでは `4.jpg`）** と **tflite形式のAIモデル** が必要になります。本ソースコードは、白地に黒で書かれた数字の画像が、0～9のうちいずれであるかを推論するプログラムです。実行には **画像ファイルとtflite形式のファイルが必要になります。**

https://qiita.com/iwatake2222/items/d998df1981d46285df62

入力画像 `4.jpg` とtflite形式のモデル `conv_mnist.tflite` は以下に格納してあります。

https://github.com/xtrizeShino/qiita_mnist_with_tflite_cpp/tree/main/resource

```cpp
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/optional_debug_tools.h"

#define MODEL_FILENAME RESOURCE_DIR"conv_mnist.tflite"

#define TFLITE_MINIMAL_CHECK(x)                              \
    if (!(x)) {                                                \
        fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); \
        exit(1);                                                 \
    }

int main()
{
    /* 入力となる画像データを読み込む "4.jpg" */
    printf("input image path : %s\n", RESOURCE_DIR"4.jpg");
    cv::Mat image = cv::imread(RESOURCE_DIR"4.jpg");
    /* ディスプレイに出力する */
    cv::imshow("InputImage", image);
    /* 画面表示が閉じられるまで待機 */
    cv::waitKey(0);
    
    /* 入力画像をgrayscaleへと変換する */
    cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
    /* 28px x 28pxにリサイズする */
    cv::resize(image, image, cv::Size(28, 28));
    /* 背景が黒、文字色が白にする */
    image = ~image;
    /* ディスプレイに出力する */
    cv::imshow("InputImage for CNN", image);
    /* Normalize: 0.0 ~ 1.0 する */
    image.convertTo(image, CV_32FC1, 1.0 / 255);
    /* 画面表示が閉じられるまで待機 */
    cv::waitKey(0);

    /* tfliteモデルのパス */
    printf("model file name : %s\n", MODEL_FILENAME);
    /* tfliteのモデルをFlatBufferに読み込む */
    std::unique_ptr<tflite::FlatBufferModel> model = tflite::FlatBufferModel::BuildFromFile(MODEL_FILENAME);
    /* 開けたかチェック */
    TFLITE_MINIMAL_CHECK(model != nullptr);
    
	/* インタープリタを生成する */
	tflite::ops::builtin::BuiltinOpResolver resolver;
	tflite::InterpreterBuilder builder(*model, resolver);
	std::unique_ptr<tflite::Interpreter> interpreter;
	builder(&interpreter);
    /* 生成できたかチェック */
	TFLITE_MINIMAL_CHECK(interpreter != nullptr);

	/* 入出力のバッファを確保する */
	TFLITE_MINIMAL_CHECK(interpreter->AllocateTensors() == kTfLiteOk);
	printf("=== Pre-invoke Interpreter State ===\n");
	tflite::PrintInterpreterState(interpreter.get());

	/* 入力テンソルに読み込んだ画像を格納する */
	float* input = interpreter->typed_input_tensor<float>(0);
	memcpy(input, image.reshape(0, 1).data, sizeof(float) * 1 * 28 * 28 * 1);

	/* 推論を実行 */
	TFLITE_MINIMAL_CHECK(interpreter->Invoke() == kTfLiteOk);
	printf("\n\n=== Post-invoke Interpreter State ===\n");
	tflite::PrintInterpreterState(interpreter.get());

	/* 出力テンソルから結果を取得して表示 */
	float* probs = interpreter->typed_output_tensor<float>(0);
	for (int i = 0; i < 10; i++) {
		printf("prob of %d: %.3f\n", i, probs[i]);
	}

    /* 終了 */
	return 0;
}
```

### ビルドと実行結果 <font color="red">**(VAB-5000上での操作)**</font>

以上を格納したディレクトリを作成し、これに対して **`cmake` と `make` を使ってビルドを実施すると `NumberDetector` というバイナリが生成** されます。これを実行することにより、画像に書かれた文字を認識することができます。

#### 実行結果（成功例）

```bash
### 作業用ディレクトリ(参考)
$ pwd
# /home/debian/sandbox/tensorflow_c/first

### ソースコードとCMakeLists.txtを準備する
$ ls
# CMakeLists.txt  main.cpp  resource

### resourceに画像とtfliteモデルを格納する
$ ls resource/
# 4.jpg  conv_mnist.tflite

### ビルドする
$ mkdir build
$ cd build
$ cmake ..
$ make 
# [ 50%] Building CXX object CMakeFiles/NumberDetector.dir/main.cpp.o
# [100%] Linking CXX executable NumberDetector
# [100%] Built target NumberDetector

### 実行する
$ ./NumberDetector 
# input image path : /home/debian/sandbox/first/tensorflow_c/build/resource/4.jpg
# model file name : /home/debian/sandbox/tensorflow_c/first/build/resource/conv_mnist.tflite
# ...
# prob of 0: 0.000
# prob of 1: 0.000
# prob of 2: 0.000
# prob of 3: 0.000
# prob of 4: 1.000
# prob of 5: 0.000
# prob of 6: 0.000
# prob of 7: 0.000
# prob of 8: 0.000
# prob of 9: 0.000
```

----

以上が **VIA VAB-5000** 向け (aarch64(64bit-Arm)向け) に
TensorFlow Lite for C/C++をx86_64上でビルドして
デバイス上から利用する手順です。やや複雑に感じられますが、
一度設定を行えば、以降は利用できますので、是非お試しください。

**お疲れさまでした！**

----