AWS SageMaker JumpStartで転移学習した画像分類モデルを「AE2100」で推論してみよう

# 要約
この記事では、AWSのSageMaker JumpStartで転移学習を行った画像分類のAIモデルをOpenVINO上で推論実行できるようにするためにModel Optimizerを使用してモデル変換する方法を説明します。
また、変換後のモデルをAE2100のUbuntu + OpenVINOコンテナへデプロイし、推論を実行します。


# はじめに
AE2100はディープラーニングモデルの推論をエッジで高速に実行可能なコンピューターであり、学習済みモデルを推論する記事がいくつか掲載されています。
ですが、PoCや実際の運用では、目的とするユースケースに応じてユーザー側で独自のモデルを用意するというケースも多々あると思います。

モデルを自分で作るとなると、なんだか難しく感じられるかもしれませんが、今日では簡単にAIモデルが作れてしまう様々なサービスが登場してきています。
今回はそれらのなかからAWS（Amazon Web Services）のサービスであるAmazon SageMaker JumpStart（以下、JumpStart）をご紹介し、JumpStartで転移学習したAIモデルをAE2100で実行する方法について説明します。


# 環境
本記事ではAWSのアカウントをお持ちであること、下記の記事に従ってAE2100の環境と開発環境が既に用意されていることを前提としています。

* [OKI AI エッジコンピューター「AE2100」でOpenVINOのサンプルプログラムを動かしてみようUbuntuコンテナ版 (1)](https://qiita.com/TWAT/items/7398105a9e64178a84d7)
* [OKI AI エッジコンピューター「AE2100」でOpenVINOのサンプルプログラムを動かしてみよう Ubuntuコンテナ版 (2)](https://qiita.com/TWAT/items/e7cd34f8c97f895c39b2)

なお、AE2100および開発環境は以下のものを前提としています。
**【開発環境】**
OS：Ubuntu20.04 LTS　　　OpenVINO：2021.4.1 LTS
**【AE2100】**
本体ファーム：V3.6.0（HDDL Daemon：OpenVINO 2021.4.1 LTS）
標準コンテナ：OpenVINO有（Ubuntu20.04版）2021年10月版

:::note info
AE2100ファームウェアv3.7.0およびv3.8.0でも動作確認しています。
v3.7.0/v3.8.0を使用する場合、HDDLデーモンは OpenVINO 2021.4.2 LTSを適用し、標準コンテナは「OpenVINO有（Ubuntu20.04版）2022年4月版」を使用してください。
HDDLデーモンの更新方法は、AE2100ファームウェアに同梱のリリースノートを参照してください。
:::


# Amazon Sagemaker JumpStartでの転移学習（AWS側）
JumpStartはTensorFlow Hub や PyTorch Hub に公開されているモデルをGUIから簡単にデプロイしたり、自前で用意したデータで転移学習をすることができる非常に便利なサービスです。

今回はTensorFlowの画像分類モデルであるResnet 50の転移学習をJumpStartにて行い、AE2100で推論を実行していきます。

転移学習の方法については、[Amazon SageMaker JumpStart でうちの猫を見分けるモデルを作ってみた](https://qiita.com/mariohcat/items/dab9ffaa5cf7189a0165)に分かりやすく記載されているので、そちらをご参照ください。
GUI操作のみで簡単に転移学習ができることが分かると思います。

転移学習したモデルはAmazon S3に「model.tar.gz」という名称で格納されているので、ローカルの開発環境にダウンロードしておいてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660784/0580fcbe-e4d9-c9f9-6468-bc0b2f028849.png)
ちなみに本記事ではマヨネーズとケチャップとソースを分類するモデルを作成しています。
以降の章では、皆さんが転移学習した分類内容に読み替えて進めていただければと思います。

※AE2100で推論評価するための画像データも数枚用意しておいてください。


# Model Optimizerでの変換（開発環境側）
前章で作成したモデル(model.tar.gz)をOpenVINOの環境で推論するために、Model OptimizerにてIR形式に変換します。
Model Optimizerでの変換については、[OKI「AE2100」向け OpenVINO Model Optimizerの使い方 (画像分類モデル編)](https://qiita.com/sa9moto/items/5cd935ec76bffe7d4767)にて詳しく解説をしています。

まず、model.tar.gzを開発環境で展開します。

```
# tar xzf model.tar.gz
```
「1」、「code」というディレクトリと「class_label_to_prediction_index.json」というファイルが生成されます。

Model OptimizerはPythonにより実行するため、Pythonの仮想環境を起動します。

```
# source /opt/intel/openvino_2021/deployment_tools/model_optimizer/venv/bin/activate
```

下記のコマンドで/opt/intel/openvino/deployment_tools/model_optimizer/mo_tf.pyを実行し、モデルファイルをIRへ変換します。

```
# python3 /opt/intel/openvino_2021/deployment_tools/model_optimizer/mo_tf.py \
> --data_type FP16 \
> --reverse_input_channels \
> --saved_model_dir 1 \
> --input_shape=[1,224,224,3] \
> --scale_values=[255.0]
```

Model Optimizerの実行が成功すると、IRとして.xml形式のファイルと.bin形式のファイルが得られます。
今回の変換では変換後のIRとして以下の2つのファイルが生成されます。
・saved_model.xml
・saved_model.bin

なお、Model Optimizerで変換する際のパラメーターは使用するモデルや推論用のデモプログラムに何を使用するかによって異なるため、事前に調べる必要があります。
本記事での説明は下記表の説明に留めますが、詳しく知りたい方は以下のURLを参考に必要となるパラメーターを確認してみてください。

引数|説明|今回の設定
:--|:--|:--|
--data_type {FP16,FP32,half,float}|IRのデータ型|**FP16**<br>→Myriad X VPUで推論を行うため、データ型としてFP16を指定|
--reverse_input_channels|入力チャネルの並びをRGBからBGRへ(またはその逆へ)入れ替える|inference.py(※)にRGBである旨の記述有<br>classification_demoはBGRチャネルの順序での入力|
--saved_model_dir|Saved Modelが格納されているディレクトリ名|**1**<br>→saved_model.pbの格納ディレクトリ名を指定|
--input_shape INPUT_SHAPE|入力データの形状|**[1,224,224,3]**<br>→inference.pyに記述有|
--scale_values SCALE_VALUES|入力画像のチャネルごとのスケール値|**[255,0]**<br>→inference.pyに記述有|

※ model.tar.gz内に含まれる「code」フォルダ内に格納

【参考】
・[Model Optimizerの引数等の詳細](https://docs.openvino.ai/2021.4/openvino_docs_MO_DG_prepare_model_convert_model_Converting_Model.html)
・[Model OptimizerでTensorFlowモデルを変換する方法の詳細](https://docs.openvino.ai/2021.4/openvino_docs_MO_DG_prepare_model_convert_model_Convert_Model_From_TensorFlow.html)
・[Classification C++ Demoの詳細](https://docs.openvino.ai/2021.4/omz_demos_classification_demo_cpp.html)


# デモプラグラムの用意（開発環境側）
Model Optimizerで変換したモデルを、今回はOpenVINOに含まれているデモプログラム（Classification C++ Demo）を使用して推論します。

開発環境でOpenVINO付属のデモプログラムのビルドを行います。
OpenVINOをデフォルトのままインストールした場合、デモプログラム一式は以下の場所に存在します。
/opt/intel/openvino/inference_engine/demos

OpenVINOの環境変数を設定します。

```
# source /opt/intel/openvino/bin/setupvars.sh
```

build_demos.shを実行し、ビルドを行います。

```
# cd /opt/intel/openvino/inference_engine/demos
# ./build_demos.sh
```

ビルドを行うと実行ファイルが以下のディレクトリに出力され、今回はその中にある「classification_demo」を使用します。
/root/omz_demos_build/intel64/Release


# ラベルファイルの用意（開発環境側）
classification_demoのラベルファイルはimagenet_2012.txtを使用するよう、以下URLにて指定されています。（モデルによってはimagenet_2015.txtを使用）
https://docs.openvino.ai/2021.4/omz_demos_classification_demo_cpp.html

imagenet_2012.txtは開発環境の以下に格納されているので、ホームディレクトリ等にコピーをしてください。
/opt/intel/openvino/deployment_tools/open_model_zoo/data/dataset_classes/

なお、imagenet_2012.txtの中身は今回転移学習をしたラベル内容に合うように書き換える必要があります。
テキストエディタでimagenet_2012.txtを開いて先頭の3行以外を削除し、ラベルを「ketchup」、「mayonnaise」、「tonkatsu」に書き換えます。

※ラベル内容は皆さんの作成したモデルに合わせて、適宜読み替えてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660784/b40062a8-9a72-f124-a7fb-1c84c0b3c64e.png)


# AE2100へのファイルコピー（開発環境側／AE2100側）
ここでは開発環境で用意した実行ファイルやラベルファイルを、AE2100へ移動します。

ディレクトリを１つ用意し、その中に以下のファイルを格納してください。

* saved_model.xml
* saved_model.bin
* classification_demo
* imagenet_2012.txt　　  ※ラベル内容を書き換えたもの
* 推論に使用する画像ディレクトリ又はファイル（本記事ではケチャップ、マヨネーズ、ソースの画像が入った「inference_sample」というディレクトリを作成）

以下のようにディレクトリに必要なファイルを格納します。

```
# cd
# ls sources_classification
saved_model.xml		saved_model.bin		classification_demo
imagente_2012.txt	inference_sample			　
```

AE2100へファイルを転送するため、tarコマンドで1つのファイルにまとめます。

```
# cd
# tar cvf sources_classification.tar sources_classification
```

以上が開発環境側での手順となります。
以降はAE2100側での手順です。

TeraTermのファイル転送などでAE2100にログインし、上記のtarファイル「sources_classification.tar」を開発環境からAE2100へ転送します。

転送が行えたら、AE2100上で下記コマンドを実行し、ホストからコンテナへ「sources_classification.tar」をコンテナ内の/rootディレクトリにコピーします。
※あらかじめOpenVINOがインストールされた標準コンテナを起動しておいてください。

```
root@ae2100:~# docker cp sources_classification.tar ubuntu-openvino:/root/
```

コンテナへ入り、tarファイルを展開します。

```
root@ae2100:~# docker exec -it ubuntu-openvino /bin/bash
# cd /root
# tar xvf sources_classification.tar
# cd sources_classification
```

# AE2100での推論実行（AE2100側）
いよいよ、転移学習した画像分類モデルをIR形式に変換したモデルを、AE2100上で推論実行します

以下に従って事前にXlaunchの起動、依存パッケージのインストールをしておいてください。

* [「OKI AI エッジコンピューター「AE2100」でOpenVINOのサンプルプログラムを動かしてみよう Ubuntuコンテナ版 (1)」](https://qiita.com/TWAT/items/7398105a9e64178a84d7)
* [OKI AI エッジコンピューター「AE2100」でOpenVINOのサンプルプログラムを動かしてみよう Ubuntuコンテナ版 (2)](https://qiita.com/TWAT/items/e7cd34f8c97f895c39b2)

環境変数の設定、検出結果の画面表示先の指定を行います。

```
# source /opt/intel/openvino/bin/setupvars.sh
# export DISPLAY=192.168.100.2:0.0
```

※DISPLAYで指定するIPアドレスは、XLaunchをインストールしたWindowsPCのIPアドレスに適宜読み替えて下さい。

実行準備が整いましたので、プログラムを実行します。

```
# ./classification_demo -m saved_model.xml -i inference_sample/tonkatsu/ -d HDDL -labels imagenet_2012.txt -nt 3
```

各オプションについて下表にて説明します。

オプション|説明|今回の入力
:--|:--|:--|
-m|xmlファイルへのパスを指定|**saved_model.xml**|
-i|推論用の画像ファイル（ディレクトリ）へのパスを指定|**推論用の画像ファイル又はディレクトリへのパス**|
-d|推論に使用するデバイスを指定|**Myriad X VPU：HDDL**<br>CPU：CPU<br>GPU：GPU|
-labels|ラベルファイルへのパスを指定|**imagenet_2012.txt**|
-nt|結果の出力数|**本記事では3種類の分類モデルであるため、「3」を指定**<br>【注】デフォルトは「5」になっており、4種類以下の分類モデルの場合はエラー発生|

下図は実行結果のウィンドウです。（マヨネーズ、ケチャップの画像の実行結果も併せて掲載しています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660784/2ee752fa-5138-34b4-9379-61249ddb5fe7.png)
多少の誤分類はあるものの、全体で90％程度の精度で分類することが出来ました。

※精度は元のモデルやハイパーパラメータ、学習に用いる画像の量や撮像環境によって変わってくるため、精度が出ない場合は色々と試してみてください。


# まとめ
今回はAmazon SageMaker JumpStartで転移学習した画像分類モデルをAE2100で推論しました。自分で転移学習したモデルをエッジで推論するのも、意外と簡単に出来るのだと感じていただけたのではないでしょうか。
今後もAWSの他のサービスを活用した記事や、Azure等の他のクラウドサービスを使用した記事を投稿予定です。

なお、本記事の内容は2021年12月開催の「AWS×OKI共催の体験型セミナー」にて実機を操作しながら解説をしています。AWSの方によるご講演を含め、アーカイブ動画を掲載しておりますので是非こちらもご参照ください。
アーカイブ動画は[こちら](https://www.oki.com/jp/AIedge/event_v/211222.html)。