catch-img

CONEXIOBlackBearで機械学習モデルを動かす(2) AWS Greengrassでデプロイ

はじめに

こんにちは。コネクシオIoTブログ 技術記事担当のHです。

前回はCONEXIOBlackBearで機械学習モデルを動かしました。

今回は、前回作成したプログラムをAWS IoT Greengrassを用いて、クラウドからCONEXIOBlackBearにデプロイし、動作させてみることにします。


0. 実施環境

  • CONEXIOBlackBear OSバージョン 1.1.5
  • Python3.7
  • tensorflow 2.0.0(keras 2.2.4)
  • USB接続のWebカメラ


1. CONEXIOBlackBearへのAWS IoT Greengrass Coreソフトウェアのインストール

以前の記事において、CONEXIOBlackBearへAWS IoT Greengrass Coreソフトウェアv1.9.2をインストールしました。しかし今回は、使用するPythonバージョンの関係上、v1.11.0が必要であるため、以前の手順に従い再インストールしました。


2. プログラムをLambdaへデプロイ

プログラムのソースコードは、前回の記事を少し編集して使用しますが、基本的なロジックは全く同様で、一部のみ変更します。


2.1 Lambda関数作成

Lambdaコンソールにて、新たにGreengrass_HelloWorld2というLambda関数およびエイリアスGG_HellowWorld2を作成しました。


2.2 前回からのコード変更部分

まず、モデルの読み込み先パスを、後述の3.3.2におけるデバイス配置先設定と一致させるように変更しました。

また、whileループの内容を5秒ごとのタイマーで繰り返し実行するように置き換え、推論の結果を、AWS IoTテスト用ゲートウェイにパブリッシュするようにしました。ハンドラ関数lambda_handlerは、3.2で実行時間無制限としているため、中身は空です。

def greengrass_hello_world_run():

    # 画像の取り込み
    frame = capture_image()

    # 形状の変換
    input_array = convert_shape(frame)

    # 推論
    t0 = time.time()
    pred = model.predict(input_array)
    t1 = time.time()

    label = label_names[pred.argmax()]
    score = pred.max()

    # 表示
    print("elapsed_time: {:.3} sec".format(t1 - t0))
    print("scores: %s" % pred)
    print("result: label={}, score={:.3}".format(label, score))

    # 送信
    client.publish(
        topic='hello/world',
        payload="result: label={}, score={:.3}, elapsed_time: {:.3} sec".format(label, score, t1 - t0))

    # Asynchronously schedule this function to be run again in 5 seconds
    Timer(5, greengrass_hello_world_run).start()


# ラベル名
label_names = [
    "airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"
]

# モデルへの入力画像サイズ
input_image_shape = (32, 32, 3)

# Creating a greengrass core sdk client
client = greengrasssdk.client('iot-data')

# カメラ
capture = cv2.VideoCapture(2, cv2.CAP_V4L)

# モデルのロード
model = load_model("/saved_models/keras_cifar10_trained_model.h5", compile=False)
file_write("model loaded")

# Start executing the function above
file_write("started!")
greengrass_hello_world_run()


def lambda_handler(event, context):
    return


3. Greengrassコンソールでの設定

※greengrassコンソールのアップデートにより、2020/12/16時点のコンソール画面では従来からあるグループ/コア/デバイスという画面構成がClassic(v1)という括りで分割されています。本記事では、以前作成したものを再利用するため、Classic(v1)の機能を使用します。


3.1 デバイス/グループの作成

以前作成したデバイス/MyFirstGroupグループを使用するため、手順は省略します。(参考:作成手順は以前の記事の2.1)


3.2 Greengrass_HelloWorld2関数の割り当て

MyFirstGroupグループのLambda関数として、先ほど作成したGreengrass_HelloWorld2関数を参照するため、Greengrassコンソールのグループ > グループを選択 > Lambdaより、Lambdaの追加ボタンを押し、以下のように設定しました。

実行ユーザーはデフォルト、メモリは128MB、ライフサイクルは無制限としています。


3.3 モデルデータのアップロード

次に、学習済みモデルデータをGreengrassによりデバイスへデプロイするための設定を行います。


3.3.1 モデルデータのS3への配置

学習済みモデルデータをAWS上で保持するには、Amazon S3にアップロードするか、AWS SageMakerで学習したものを参照するという2通りがあります。今回はSageMakerを使用していないため、S3を利用することとします。

学習済みモデルデータは、以前の記事の1.3で出力されたkeras_cifar10_trained_model.h5を使用します。

アップロードについての注意点として、以下2つです。

  • Greengrassから参照可能なファイルはzipであるため、アップロードする前にzip圧縮しておく
  • 格納先バケットは以下の2つのいずれかを選択する(参考: https://docs.amazonaws.cn/en_us/greengrass/latest/developerguide/gg-dg.pdf)
    • "greengrass"が含まれるバケット
    • ピリオドが含まれないバケット名のバケット
      • この場合、Greengrassのサービスロールでそのバケットへのアクセス権限を与える必要がある

今回は、名前に"greengrass"が含まれるバケットを作成してzipファイルを配置しました。


3.3.2 機械学習リソースの設定

3.3.1で配置したモデルデータをLambdaから参照するため、Greengrassコンソールで機械学習リソースの作成を行います。

Greengrassコンソールのグループ > グループを選択 > リソース > Machine Learningより、機械学習リソースの追加ボタンを押し、以下のように設定しました。

モデルとして、3.3.1でアップロードしたzipファイルを選択します。ローカルパスは、先述の通り、Lambdaのソースコード上で参照されるパスと一致するようにします。アクセス権限は、モデルデータの編集は必要ないため、読み取り専用としました。


3.4 ローカルリソースの設定

Lambda関数から、CONEXIOBlackBearのUSB端子に接続したWebカメラを使用するには、Greengrassコンソールでローカルリソースを追加する必要があります。

Greengrassコンソールのグループ > グループを選択 > リソース > ローカルより、ローカルリソースの追加ボタンを押し、以下のように設定しました。

デバイスパスは、Webカメラが/dev/video2として認識されていたので、/dev/video2と入力します。Lambda関数に与えるアクセス権限は、読み取りと書き込みを設定する必要があります。


3.5 USBカメラへのアクセス許可設定

CONEXIOBlackBearにデプロイする前に、greengrass Coreソフトウェア上のLambda関数からWebカメラにアクセスできるように事前に設定が必要です。

まず、CONEXIOBlackBearのUSB端子の有効化。

echo 174 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio174/direction

Lambda関数はデフォルトでは、ggc_userユーザー/ggc_groupグループで実行されるため、/dev/video2にその他のユーザーの読み書きアクセス権限を与えます。

chmod 666 /dev/video2


3.6 デプロイ

CONEXIOBlackBearで、Greengrass Core ソフトウェアのデーモンを起動します。

/greengrass/ggc/core/greengrassd start

そして、Greengrassコンソールからデプロイします。デプロイが正常に完了したら成功です。


4. 動作確認

AWS IoTコンソールのテスト用デバイスゲートウェイ画面で、hello/worldトピックをサブスクライブすると、以下のようなメッセージを受信しました。CONEXIOBlackBearから推論した結果が届いています。無事、機械学習モデルで推論を行うプログラムをGreengrassでデプロイして動かすことができました。


まとめ

以上のように、機械学習モデルで推論を行うプログラムをGreengrassでデプロイして動かすことが出来ました。

今回は、PC上で学習を行った比較的時間の短い機械学習モデルを用いました。今後は、AWS  のSageMakerなどクラウド上のコンピューティングリソースを使って大量の学習が必要な高度なモデルを作成し、動かしたいと思います。


H

H

コネクシオ株式会社・IoT開発担当者