Amazon Web Services ブログ

ONNX Runtime を使った AWS IoT Greengrass 上での画像分類の最適化

はじめに

クラウドで学習したモデルを用いてエッジデバイス上で機械学習の推論を行うことは、低レイテンシー、スケーラビリティ、コスト削減のメリットをもたらすため、モノのインターネット(IoT)におけるよく知られたユースケースになっています。演算能力とメモリが限られているエッジデバイスにモデルを展開する場合、開発者は、望ましいパフォーマンスを達成するためにモデルを手動でチューニングするという課題を抱えています。このブログポストでは、AWS IoT Greengrass 上の ONNX Runtime を使用して、エッジでの画像分類を最適化する方法の例について紹介します。

ONNX は、あらゆるタイプの機械学習や深層学習モデルを表現するために構築されたオープンフォーマットで、ハードウェア最適化を容易にするものです。異なる機械学習フレームワーク間の相互運用性のための標準フォーマットを提供します。お好みのフレームワーク (TensorFlowPyTorchMxNet など)を使って画像分類モデルを学習し、ONNX フォーマットにエクスポートすることができます。パフォーマンスを最大化するために、ONNX モデルを ONNX Runtime のような最適化された推論フレームワークと一緒に使用することができます。ONNX Runtime は、様々なフレームワーク、オペレーティングシステム、ハードウェアプラットフォームにおいて、単一の API セットで機械学習推論を高速化するために設計されたオープンソースプロジェクトです。このブログ記事では画像分類の例を取り上げていますが、物体検出、画像セグメンテーション、話声・音声処理、機械読解・翻訳など、幅広いユースケースで ONNX を利用することができます。

AWS IoT Greengrass は、オープンソースの IoT 向けのエッジランタイムとクラウドサービスで、デバイス上の IoT アプリケーションの構築、デプロイ、管理を支援します。AWS IoT Greengrass では、コンポーネントと呼ばれるソフトウェアモジュールを使用してエッジアプリケーションを構築し、エッジデバイスを AWS またはサードパーティサービスに接続することができます。AWS が提供する機械学習コンポーネントがいくつか準備されており、クラウドで学習したモデルと、ローカルで生成されたデータを使って、リモートデバイス上で推論を実行するために使用することができます。また、機械学習のカスタムコンポーネントを作成することもできます。これは、エッジに機械学習モデルやランタイムを配置・更新するためのコンポーネントと、機械学習推論に必要なアプリケーションロジックを含むコンポーネントの 2 種類に分類されます。

ソリューションの概要

このブログでは、AWS IoT Greengrass 上で画像分類のためのカスタムコンポーネントを構築し、デプロイする方法を学習します。このソリューションは、以下のアーキテクチャと手順で実装しています。

Solution Architecture Diagram

1. お好みのフレームワークを使用してモデルをトレーニングし、ONNX 形式にエクスポートするか、または事前にトレーニングされた ONNX モデルを使用します。Amazon SageMaker StudioAmazon SageMaker Pipelines を使用して、このプロセスを自動化することができます。

このブログでは、ONNX Model Zoo から入手できる、ONNX フォーマットで事前にトレーニングされた画像分類用の ResNet-50 モデルを使用することにします。ResNet-50 は50層からなる畳み込みニューラルネットワークで、このモデルのトレーニング済みバージョンは、画像をキーボード、マウス、鉛筆、多くの動物など、1000のオブジェクトカテゴリに分類できます。

2. 下記の AWS IoT Greengrass コンポーネントをビルドし、パブリッシュします。

  • ONNX モデルを実行するために必要なライブラリを含む ONNX Runtime コンポーネント。
  • 必要なコード、ONNX 形式の ResNet-50 モデル、分類に使用されるラベルやサンプル画像を含む推論用コンポーネント。このコンポーネントは、ONNX Runtime コンポーネントに依存しています。

3. ターゲットデバイスにコンポーネントを配置します。コンポーネントが実行されると、サンプル画像を分類し、その結果を AWS IoT Core に対して、demo/onnx というトピックにパブリッシュします。AWS IoT Core は、インフラストラクチャを管理することなく、何十億もの IoT デバイスを接続し、何兆ものメッセージを AWS サービスにルーティングすることができるマネージドな AWS サービスです。

前提条件

このブログのステップを実行するためには、以下が必要となります。

導入の概要

初期設定

環境の初期設定の一環として、プロビジョニングする必要のあるリソースがいくつかあります。すべてのリソースは、同じリージョンでプロビジョニングする必要があります。このガイドでは、eu-central-1 リージョンを使用しています。以下のステップに従って、開始します。
1. コンポーネントのアーティファクトは、Amazon Simple Storage Service (Amazon S3) バケットに保存されます。Amazon S3 バケットの作成方法は、ユーザーガイドをご参照ください。
2. コンポーネントをデプロイするデバイスをエミュレートするために、AWS Cloud9 環境を使用し、次に AWS IoT Greengrass クライアントソフトウェアをインストールします。これらの手順を実行するためには、AWS IoT Greengrass v2 ワークショップのセクション 23.1の内容を実行します。
3. AWS Cloud9 環境に python 3.6.9 と pip 23.0 以降がインストールされていることを確認します。

ONNX Runtime と推論コンポーネントのビルドとパブリッシュ

次のセクションでは、ローカルマシンのターミナルか、または AWS Cloud9 環境のいずれかで、AWS CLI を使用してカスタムコンポーネントをビルドし、パブリッシュします。

初期設定の一部として作成した Amazon S3 バケットにアーティファクトをアップロードするには、次のステップに従います。
1. コンポーネントのアーティファクトやレシピを含む git リポジトリをクローンします。

git clone https://github.com/aws-samples/aws-iot-gg-onnx-runtime.git
Bash

2. artifacts フォルダに移動し、ファイルを zip 形式で圧縮します。

cd aws-iot-gg-onnx-runtime/artifacts/com.demo.onnx-imageclassification/1.0.0 
zip -r greengrass-onnx.zip .
Bash

3. 初期設定で作成した Amazon S3 バケットに、zip ファイルをアップロードします。

aws s3 cp greengrass-onnx.zip s3://{YOUR-S3-BUCKET}/greengrass-onnx.zip
Bash

コンポーネントをパブリッシュするには、次の手順を実行します。
1. aws-iot-gg-onnx-runtime/recipes/com.demo.onnx-imageclassification-1.0.0.json というレシピファイルをテキストエディタで開いてください。以下に、recipes ディレクトリに移動するためのコマンドを記載します。

cd aws-iot-gg-onnx-runtime/recipes/
Bash

2. Artifacts の URI の Amazon S3 バケット名を、初期設定で作成した Amazon S3 バケット名に置き換えます。

"Artifacts": [
    {
      "URI": "s3://{YOUR-S3-BUCKET}/greengrass-onnx.zip",
      "Unarchive": "ZIP"
    }
  ]
JSON

3. コンポーネントをパブリッシュする前に、初期設定でリソースを作成したリージョンと同じリージョンを使用していることを確認してください。以下のコマンドを使用して、デフォルトのリージョンを設定できます。

aws configure set default.region eu-central-1
Bash

4. ONNX Runtime コンポーネントをパブリッシュします。

aws greengrassv2 create-component-version --inline-recipe fileb://com.demo.onnxruntime-1.0.0.json
Bash

5. 画像分類を実行するコンポーネントで、ONNX Runtime に依存するコンポーネントをパブリッシュします。

aws greengrassv2 create-component-version --inline-recipe fileb://com.demo.onnx-imageclassification-1.0.0.json
Bash

6. コンポーネントが正常にパブリッシュされたことを確認するには、AWS IoT のコンソールに移動して、画面左メニューの Greengrass デバイス >> コンポーネントを選択します。マイコンポーネントタブに、先ほどパブリッシュした2つのコンポーネントが表示されていることを確認します。
Screenshot - My Components tab

ターゲットデバイスにコンポーネントをデプロイする

1. コンポーネントをターゲットデバイスにデプロイするために、AWS IoT Greengrass クライアントソフトウェアが AWS Cloud9 環境にプロビジョニングされていることを確認します。
2. Greengrass デバイスに必要な権限を付与するために、Greengrass デバイスに関連するサービスロールの設定を確認します。このロールに対して、作成した Amazon S3 バケットからオブジェクトを取得する権限と、AWS IoT Core の demo/onnx トピックにパブリッシュする権限が付与されていることを確認します。
3. コンポーネントをターゲットデバイスにデプロイするには、AWS IoT コンソールに移動し、画面左メニューの Greengrass デバイス >> デプロイを選択し、作成をクリックします。
4. デプロイメント名と、デプロイ先のコアデバイスの名前を記入します。
Screenshot - Deployment Information
5. コンポーネントの選択画面のマイコンポーネントセクションで、コンポーネント com.demo.onnx-imageclassification を選択します。
6. その他のオプションはすべてデフォルトのままにして、レビュー画面に到達するまで次へをクリックし、最後にデプロイをクリックします。
7. コンポーネントのデプロイのログと進捗状況を監視するには、AWS Cloud9 環境上の Greengrass コアデバイスのログファイルを以下のコマンドで確認することができます。

sudo tail -f /greengrass/v2/logs/greengrass.log
Bash

8. なお、ONNX Runtime のコンポーネント com.demo.onnxruntime は、デプロイ用に選択した画像分類コンポーネントに依存関係があるため、自動的にインストールされます。

ONNX 画像分類コンポーネントのデプロイメントをテストする

画像分類コンポーネントが実行状態になると、images フォルダ内のファイルをループして、画像を分類します。結果は AWS IoT Core の demo/onnx というトピックにパブリッシュされます。

このプロセスを理解するために、画像分類コンポーネントのコードをいくつか見てみましょう。
1. サンプル画像を確認し、予測されたラベルと比較するために、aws-iot-gg-onnx-runtime/artifacts/com.demo.onnx-imageclassification/1.0.0/images フォルダにある画像を開いてみてください。
2. 以下に示す predict 関数では、ONNX Runtime と ONNX 形式で事前にトレーニングされた ResNet-50 ニューラルネットワークを使って推論セッションを開始します。

def predict(modelPath, labelsPath, image):
    labels = load_labels(labelsPath)
    # Run the model on the backend
    session = onnxruntime.InferenceSession(modelPath, None)
Python

3. 画像は最初に前処理され、その後推論セッションの入力パラメータとして渡されます。ResNet-50 モデルは 224×224 ピクセルの画像を使用することに留意してください。

image_data = np.array(image).transpose(2, 0, 1)
input_data = preprocess(image_data)
start = time.time()
raw_result = session.run([], {input_name: input_data})
end = time.time()
Python

4. 推論結果から画像のラベルを抽出し、推論時間をミリ秒単位で算出します。

inference_time = np.round((end - start) * 1000, 2)
idx = np.argmax(postprocess(raw_result))
inferenceResult = {
	"label": labels[idx],
	"inference_time": inference_time
}
Python

5. 画像分類コンポーネントは、images フォルダに存在するファイルをループして、predict 関数を呼び出します。結果は5秒ごとに AWS IoT Core の demo/onnx トピックにパブリッシュされます。

for img in os.listdir(imagesPath):
        request = PublishToIoTCoreRequest()
        request.topic_name = topic
        image = Image.open(imagesPath + "/" + img)
        pred = predict(modelPath, labelsPath, image)
        request.payload = pred.encode()
        request.qos = qos
        operation = ipc_client.new_publish_to_iot_core()
        operation.activate(request)
        future_response = operation.get_response().result(timeout=5)
        print("successfully published message: ", future_response)
        time.sleep(5)
Python

結果がトピックに正常にパブリッシュされたことを確認するには、AWS IoT コンソールにアクセスし、画面左メニューのテスト >> MQTT テストクライアントを選択し、トピック demo/onnx をサブスクライブします。以下のスクリーンショットのように、推論結果が表示されることを確認します。
Screenshot - Inference results from the MQTT Client

クリーンアップ

使用しなくなったリソースを削除することは、ベストプラクティスです。AWS アカウントで追加コストが発生しないように、以下の手順を実行します。
1. AWS IoT Greengrass ソフトウェアがインストールされていた AWS Cloud9 環境を削除します。

aws cloud9 delete-environment --environment-id <your environment id>
Bash

2. Greengrass のコアデバイスを削除します。

aws greengrassv2 delete-core-device --core-device-thing-name <thing-name>
Bash

3. アーティファクトが保存されている Amazon S3 バケットを削除します。

aws s3 rb s3://{YOUR-S3-BUCKET} --force
Bash

まとめ

このブログポストでは、ONNX Runtime を使って画像を分類するカスタムコンポーネントを AWS IoT Greengrass 上に構築してデプロイする方法を紹介しました。画像を追加したり、ONNX 形式の異なるモデルを使用して予測を行うなど、このコンポーネントをカスタマイズすることができます。

カスタムコンポーネントの構築方法を含め、AWS IoT Greengrass をより深く理解するには、AWS IoT Greengrass Workshop v2 をご確認ください。 また、機械学習コンポーネントをカスタマイズする方法については、開発者ガイドをお読みください。

この記事は Costin Bădici によって書かれた Optimize image classification on AWS IoT Greengrass using ONNX Runtime の日本語訳です。この記事は プロフェッショナルサービス本部 IoT コンサルタントの宮本 篤が翻訳しました。

著者

Costin Badici.jpg

Costin Bădici は、ルーマニアのブカレストに拠点を置く Amazon Web Services (AWS) のソリューションアーキテクトで、企業のお客様に対して AWS デプロイメントの最適化、ベストプラクティスの順守、AWS サービスを使ってより速くイノベーションを起こすことを支援しています。IoT と機械学習に情熱を持ち、複数の業界の顧客向けに拡張性の高い IoT と予測分析ソリューションを設計、実装しています。