AWS でアクセサリー検査装置を作ってみよう

2022-08-02
日常で楽しむクラウドテクノロジー

Author : 渡邉 聡

こんにちは。ソリューションアーキテクトの渡邉です。最近のマイブームは電子工作で、先日妻が買った電子置き時計が壊れてしまって悲しんでいたので、 LED パネルに自作の制御基板をつなぎ、 3D プリンターで印刷した筐体で覆い、自作の LED 時計を作ってプレゼントしたところとても喜んでくれました。周りからの評判もよく、これは量産だ ! と意気込んでいるのですが、基板のハンダ付けで何度も間違えたりハンダ不良があったりと、色々苦労があったことを考えると量産がスムーズに行くとも思えません。

そこで、量産に備えて検査体制を確立するために、検査装置を作ってみようと思います。今回は我が家のネットワーク環境が途切れても検査し続け、大量の生産体制にも遅れなく検査できるようエッジでの検査体制確立が条件です。以前、こんなミニチュア工場のデモ も作っているのですが、このデモでは Amazon SageMaker を使って頑張って独自にモデルを構築しています。しかし AWS には、賢い AI サービスも揃っています。外観検査に特化したサービスである、Amazon Lookout for Vision (以降 L4V) が エッジでの推論に対応 したため、今回はこの L4V を用いて機械学習知識が浅い私でも賢い外観検査装置が作れるかチャレンジしてみようと思います。

とはいえ、学習用に基板を大量に準備するのはまだ難しいので、今回は娘の遊んでいたアイロンビーズを用いてアクセサリーの検査というシナリオで進めていこうと思います。

AWS ロゴをイメージしてアクセサリーを大量に作成しました。これをもとに L4V の学習を行い検査モデルを作っていこうと思います。アイロンビーズは普通に作っていてもミスが混入しますし、正しく作ったものもアイロンのかけ方、ビーズのブレによってある程度の違いが出るので良い題材ではないかと思いました。

最終的に出来上がった環境では、以下の動画のようにエッジでの推論、結果の確認、再学習が簡単にできるようになります。まずは完成動画を見てみてください。

実際お試しいただくために、今回作成したソースコードも下記に置いておきました。
※利用にあたっては免責事項についてもご一読ください。

サンプルコードのダウンロード »

ご注意

本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。

*ハンズオン記事およびソースコードにおける免責事項 »

このクラウドレシピ (ハンズオン記事) を無料でお試しいただけます »

毎月提供されるクラウドレシピのアップデート情報とともに、クレジットコードを受け取ることができます。 


1. アーキテクチャ

検査システムの全体アーキテクチャは下記のようにしました。おそらく最初に作ったモデルの精度はそんなに出ないだろうという想定から、検査に使った画像からそのまま再学習ができるようにしようと思います。また、検査結果や検査の信頼度など、エッジ検査の状況もリアルタイムに参照できるようにしました。


2. 利用するサービス


3. 利用するデバイス

L4Vで利用するエッジデバイスの動作要件は こちらの要件 に準拠します。

本記事では下記のデバイス、ソフトウェアで構成してきます。

エッジデバイス
  • Jetson AGX Xavier (※)
  • JetPack 4.5.1
  • Python 3.9.13
USB カメラ
  • Logicool C922 Pro HD
    • 上記 USB カメラの場合、今回作成したWeb インターフェースから フォーカスの設定等が可能です
    • ただし、一般的な USB カメラであれば動作可能だと思われます

※ L4V でサポートされているデバイスは現在のところ唯一 Jetson Xavier となっています。後述しますが、個人的には Jetson Nano で実行できたほうがお手軽と考えていたので Nano でも試しています。ただし Jetson Nano はメモリ容量が少ないため、作成されるモデルによっては確実な動作を保証できません。

※ Jetson デバイスが手元にない場合のために、EC2 での実行方法をプログラム中のREADME に記載していますので興味あれば参照してみてください。


4. クラウド環境の構築

今回、クラウド環境のセットアップには CDK を使用します。CDK を実行するためには AWS CLI がインストールされ、認証情報が設定されている必要があります。こちら を参考に設定してください。

cdk コマンドがインストールされていない場合、npm install -g aws-cdk で事前にインストールを行なってください。

4-1. 環境情報の設定

ダウンロードしたサンプルプログラムを解凍し、./cdk/cdk.json にセットアップする環境情報を設定します。cdk.jsonregion, projectName, siteName, bucketNamePrefix, ggArtifactBucketPrefix, thingName を下記を参考に変更します。

{
  "context": {
    "region": "ap-northeast-1",
    "projectName": "sample_project",
    "siteName": "my_site",
    "bucketNamePrefix": "l4v-edge-bucket",
    "ggArtifactBucketPrefix": "greengrass-private-component",
    "thingName": "MyL4VEdgeGreengrassCore",
  }
}
設定値 内容
region プロジェクトをデプロイするリージョン
projectName 任意のプロジェクト名 (検査対象がわかるような名前が良いかと思います)
siteName 任意の適用サイト名 (適用ライン名など)
bucketNamePrefix 推論画像がアップロードされるバケットの prefix
ggArtifactBucketPrefix Greengrass のコンポーネントをデプロイするバケット名の predfix
このあとデプロイする各コンポーネントの gdk-config.json の設定と合わせてください
thingName 作成する Greengrass デバイスにつける Thing 名

4-2. AWS CDK によるデプロイ実行

下記のコマンドを実行しクレデンシャル情報を設定します。リソース作成可能なユーザーの Access key ID, Secret Access Key で下記 XXXX の部分を書き換えコマンドを実行してください。

export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXX

cdk コマンドの初回利用時のみ、以下のコマンドを実行してください。対象のアカウント&リージョン内で、すでに実行済みであれば実行不必要です。

$ cdk bootstrap

このスタックで必要となるライブラリをインストールします。ダウンロードしたサンプルプログラムの cdk ディレクトリに移って作業します。

$ cd cdk
$ npm install

続いて、下記コマンドを実行することで、L4V のプロジェクト、Greengrass の関連リソース、S3 バケット、Lambda 関数、および SiteWise のモデル、アセット の各リソースが作成されます。

$ cdk deploy L4VEdgeStack

デプロイが完了すると、下記のような出力を得られます、GGv2 コンポーネントの設定で必要となりますので、メモしておいてください。(CloudFormation のコンソールの L4VEdgeStack からも確認できます)

 ✅  L4VEdgeStack
✨  Deployment time: 120.47s
Outputs:
L4VEdgeStack.IotGGInstallCommand0F84B18E = sudo -E java -Droot="/greengrass/v2" -Dlog.store=FILE  -jar ./GreengrassCore/lib/Greengrass.jar --aws-region ap-northeast-1  --thing-name MyL4VEdgeGreengrassCore --thing-policy-name sample_projectThingPolicy --tes-role-name  sample_projectTokenExchangeRole --tes-role-alias-name sample_projectTokenExchangeRoleAlias --component-default-user ggc_user:ggc_group --provision true --setup-system-service true --deploy-dev-tools true
L4VEdgeStack.IotGGTokenExchangeRole677C6116 = sample_projectTokenExchangeRole
L4VEdgeStack.IotRoleAliasFACE37BB = sample_projectTokenExchangeRoleAlias
L4VEdgeStack.IotThingPolicy1EA44720 = sample_projectThingPolicy
L4VEdgeStack.L4VProjectName = sample_project
L4VEdgeStack.LambdaFunctionName = l4v_sample_project_add_dataset
L4VEdgeStack.S3BucketName = l4v-edge-bucket-sample-project-ap-northeast-1-XXXXXXXXXXXXX
L4VEdgeStack.SiteName = my_site
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/L4VEdgeStack/6d944d00-fcf7-11ec-99bb-061b5853727d
✨  Total time: 134.22s

5. Jetsonのセットアップ

以降の作業は Jetson デバイスでの作業になります。

Jetson デバイスには JetPack 4.4, 4.5 または 4.5.1 がセットアップされている必要があります。今回は4.5.1をセットアップしました。

※ Jetson AGX Xavier に対しては最新の SDK Manager からだと該当するバージョンとしては 4.5.1 しか選択できない状況になっています。(2022/06 現在)

5-1. Python 3.9 のインストール

L4V の Edge エージェントの動作要件として Python3.8 もしくは 3.9 が必要です。JetPack4.5.1 にデフォルトでインストールされている Python は 3.6 となるため、新たに 3.9(もしくは 3.8)をインストールします。

本記事の動作確認は Python3.9 の環境で行なっていますので、Python3.9 環境のセットアップについて手順を記載します。

※ Python3.8 を使用する場合には、L4V のドキュメント に記載されている python3.8 のセットアップに加えて、本記事のプログラムのセットアップに pip が必要なため、pip のインストールも行なってください。

下記のコマンドを実行し Python3.9 のビルドとインストールを実行します。

$ sudo apt-get update
$ sudo apt install build-essential libbz2-dev libdb-dev libreadline-dev libffi-dev libgdbm-dev liblzma-dev libncursesw5-dev libsqlite3-dev libssl-dev zlib1g-dev uuid-dev tk-dev
$ wget https://www.python.org/fpt/python.3.9.13/Python-3.9.13.tgz
$ tar zxvf Python-3.9.13.tgz
$ cd Python-3.9.13
$ ./configure --enable-shared --enable-optimizations --with-ensurepip=yes
$ make -j $(nproc)
$ sudo -H make altinstall
$ sudo ldconfig -v

次に、Python3 コマンドの対象をインストールした Python3.9 に変更します。その前に、Python3 コマンドを 3.6 から 3.9 に変更すると Ubuntu の Terminal アプリケーションが起動できなくなるため、/usr/bin/gnome-terminal の先頭行の python3 の指定を python3.6 と変更し明示的に 3.6 を使用するようにします。(Terminal アプリケーションを使わない場合は作業不要です)

$ sudo vi /usr/bin/gnome-terminal

下記のコマンドで Python3 を更新します。

$ sudo update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.9 1
$ python3 --version
Python 3.9.13
$ python3 -m pip --version
pip 22.0.4 from /usr/local/lib/python3.9/site-packages/pip (python 3.9)

5-2. Greengrass v2 のセットアップ

こちら を参考に Greengrass v2 (以降 GGv2) をセットアップします。

CDK の出力を使用して自動プロビジョニングを行なっていく場合は以降の手順にしたがってインストールを実行していきます。

今回作成する GGv2 の Token Exchange Role には S3 への読み込み書き込み権限、SiteWise への書き込み権限(※) を付与する必要があります。CDK の出力結果を用いてインストールを行う場合には --tes-role-name コマンド引数で指定しているロールにこれら必要な権限が付与されています。

※ TokenExchangeRole 詳細
対象 S3 バケットに対して s3:GetObject , s3:PutObject , s3:AbortMultipartUpload , s3:ListMultipartUploadParts が必要となります。 また、SiteWise に対しては iotsitewise:BatchPutAssetPropertyValue が割り当てられている必要があります。

5-2-1. AWS 認証情報を Jetson に設定する

セットアップする Jetson デバイスで、AWS 認証情報を設定します。認証情報として設定する IAM ユーザには Greengrass インストーラーがリソースをプロビジョニングするための 最小限の IAM ポリシー が設定されている必要があります。IAM ユーザーを準備し、当該ユーザーの Access key ID, Secret Access Key で下記 XXXX の部分を書き換え、Jetson デバイスのコンソールで下記コマンドを実行します。

export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

5-2-2. 環境セットアップと GreengrassCore のダウンロード

下記コマンドで Java のインストールと、GreengrassCore のダウンロードと展開を行います。

$ sudo apt-get install default-jdk
$ sudo apt-get install curl
$ curl -s https://d2s8p88vqu9w66.cloudfront.net/releases/greengrass-nucleus-latest.zip > greengrass-nucleus-latest.zip && unzip greengrass-nucleus-latest.zip -d GreengrassCore

5-2-3. GreengrassCore のインストール

CDK 実行時に出力された L4VEdgeStack.IotGGInstallCommandXXXXXXXX のコマンドを実行します。

$ sudo -E java -Droot="/greengrass/v2" -Dlog.store=FILE  -jar ./GreengrassCore/lib/Greengrass.jar --aws-region ap-northeast-1  --thing-name MyL4VEdgeGreengrassCore --thing-policy-name sample_projectThingPolicy --tes-role-name  sample_projectTokenExchangeRole --tes-role-alias-name sample_projectTokenExchangeRoleAlias --component-default-user ggc_user:ggc_group --provision true --setup-system-service true --deploy-dev-tools true
Provisioning AWS IoT resources for the device with IoT Thing Name: [MyL4VEdgeGreengrassCore]...
Found IoT policy "sample_projectThingPolicy", reusing it
Creating keys and certificate...
Attaching policy to certificate...
Creating IoT Thing "MyL4VEdgeGreengrassCore"...
...
Creating group ggc_group
ggc_group created
Added ggc_user to ggc_group
Successfully set up Nucleus as a system service

ここまでで MyL4VEdgeGreengrassCore というデバイスが登録されているはずです。マネジメントコンソール から確認してください。

5-3. L4V Edge Agent 向け設定

GGv2 のコンポーネントが GPU およびUSBカメラ を利用できるようにするために下記コマンドで、ggc_uservideo グループに追加します。

$ sudo usermod -a -G video ggc_user

6. Greengrass コンポーネントのセットアップとデプロイの準備

以降はまたサンプルプログラムをダウンロードした開発環境に戻っての作業となります。

本記事の GGv2 コンポーネントは AWS IoT Greengrass Development Kit Command Line Interface (以降 GDK) を用いて作成しています。GDK を利用できるよう予めセットアップしてください。まだ GDK をセットアップしていない場合は、下記のコマンドを用いてセットアップできます。

$ python3 -m pip install git+https://github.com/aws-greengrass/aws-greengrass-gdk-cli.git

7. L4V エッジ用モデルパッケージの作成

L4V のモデル作成のための学習用画像を CDK で作成された S3 バケットに配置します。まだ画像が用意できていない場合、サンプルプログラム内に画像キャプチャ S3 アップロード用のコンポーネントを用意していますので、これを用いてエッジデバイスで画像を容易に撮影・収集できます。

7-1. キャプチャコンポーネントのデプロイと実行

7-1-1. キャプチャコンポーネントの登録

キャプチャコンポーネントは サンプルプログラムの ./component/capture/ にあります。コンポーネントの利用を開始するには、当該フォルダ内の gdk-config.json の内容確認と recipe.yaml の作成が必要です。下記の手順に従って各ファイルを ./component/capture/ 以下に作成してください。

  • gdk-config.json
    • ./component/capture/gdk-config.json の内容を確認します。
    • gdk-config.json の中の、bucket 項目を必要に応じて変更します。この名前はコンポーネントを配置するバケットの prefix となり、<bucket>-<region>-<account_id> というバケットが作成されます。CDK 実行時に cdk.json で指定した ggArtifactBucketPrefix と同じになるように指定してください。
    • また region の項目も cdk.json で指定した region と同じになるように指定してください。
  • recipe.yaml
    • ./component/capture/recipe.yaml.template の名前を recipe.yaml に修正して保存します。
    • YAMLファイル 中の <IMAGE_UPLOAD_BUCKET_NAME> を CDK 実行で出力された L4VEdgeStack.S3BucketName に変更します。
    • 他のパラメータも必要に応じて変更いただけます。各パラメータの内容は下記の通りです。
ComponentConfiguration
ImageUploadBucket 推論対象となった画像やカメラのキャプチャ画像がアップロードされるバケット
TargetVideoDevice 対象のカメラデバイス (例:/dev/video0 or filePath ※)
VideoSourceType ビデオデバイスのタイプ (live / file)
VideoWidth カメラ画角の幅
VideoHeight カメラ画角の高さ
WebServerPort カメラ画像の確認用 Web インターフェースのポート番号
LogLevel ログレベル (info / warn / error / debug )

※ デバイスにカメラを接続できない場合、USB カメラの代わりに動画ファイルをビデオソースとして使用できます。動画ファイルのパスを TargetVideoDevice に指定し VideoSourceTypefile とすることで、カメラが接続できないクラウド上のインスタンスでもお試しいただけるようにしています。(クラウド上のインスタンスで実行する方法についてはサンプルプログラム中の README ドキュメントを参照してください)

上記ファイルが準備できたら、下記のコマンドでキャプチャコンポーネントのディレクトリに移動してビルドを実行します。

$ cd component/capture/
$ gdk component build

ビルドが正常に完了したら下記のコマンドでコンポーネントを発行します。

$ gdk component publish

正常に発行されたら、GGv2 コンソールの マイコンポーネントcom.example.image-capture が登録されるのを確認できます。

7-1-2. キャプチャコンポーネントのデプロイ

CDK 出力の GGv2 インストールコマンドで GGv2 をセットアップしている場合、GGv2 の デプロイ に対象デバイス向けのデプロイが作成されています。

クリックすると拡大します

対象のデプロイを選択し、デプロイの変更を行なっていきます。

クリックすると拡大します

コンポーネントの選択画面で先ほど登録した com.example.image-capture を検索し選択します。

クリックすると拡大します

そのほかの項目はそのままデプロイを実行します。

デプロイのステータスが完了となって正常にデプロイされたことを確認します。

クリックすると拡大します

7-2. キャプチャコンポーネントの実行

コンポーネントがデプロイされたら GGv2 デバイスに直接ローカルネットワークで接続可能な PC から、下記 URL を参照します。

http://<デバイスのIP>:8080

※ポート番号は recipe.yamlWebServerPort 設定値に合わせて変更ください。

ブラウザにこちらのようなカメラ画像が表示されます。

画面右上の Focus Setting では、オートフォーカスに対応した USB カメラの場合、ここでフォーカスの調整が可能です。カメラ画像がはっきり映るように調整します。オートフォーカスに対応していない USB カメラの場合はこのメニューはグレーアウトして設定できません。その場合はカメラと対象物の距離を変えるなど、手動でフォーカスを調整します。

クリックすると拡大します

左上の Normal ボタンを押すと対象バケットに /normal/YYYYMMDDHHMMSS.jpg といったキーでファイルが保存されます。トレーニング用の画像と、テスト用の画像を分けておきたい場合は、 Key prefix (Option) にプレフィックスとなるキーを指定して更に画像を分けることができます。例えば、トレーニング用の画像の場合、Key prefix (Option)train と入力して Normal ボタンを押していきます。

クリックすると拡大します

上記の設定で、下記に画像が保存されていきます。

s3://<Bucket>/train/normal/YYYYMMDDHHMMSS.jpg

S3 に保存したログも画像上に表示されます。(この文字列は選択し DEL キーで削除できます)

同じ要領で、不良品をカメラ前に置いて「Anomaly」ボタンを押して撮影します。

クリックすると拡大します

同じ要領で、テスト用の画像も撮影します。テスト用の画像は test というプレフィックスとして保存することとする場合、Key prefix (Option) には、test として撮影していきます。

L4V でのモデル学習には、正常なオブジェクトの画像は少なくとも 20 枚、異常なオブジェクトの画像は少なくとも 10 枚必要です。もしくは、トレーニングデータセットとテストデータセットを別々に使用する場合、トレーニングデータセットには正常なオブジェクトの画像が最低 10 枚必要です。テストデータセットには、少なくとも 10 枚の正常なオブジェクトの画像と、少なくとも 10 枚の異常なオブジェクトの画像が必要です。より高品質なモデルを作成するには、最小画像数より多くの画像を使用してください。 詳しくは こちらの L4V のドキュメント を参照してください。

また、学習・推論に用いる画像の縦横サイズは全て等しい必要があります。今回は一つの Web カメラから画像を取得したので同じ画像サイズになっていますが、他のカメラからの画像と混ぜたりする場合は画像の前処理などですべての画像を同じサイズに揃える必要性があります。詳しくは  L4V のサービスクォータ をご覧ください。

対象の S3 バケットを参照してイメージが正しく保存されていることを確認します。

クリックすると拡大します

7-3. データセットの準備とモデルの作成

画像が準備できたら、CDK で作成された L4V のプロジェクトを開き、データセットを作成していきます。

クリックすると拡大します

クリックすると拡大します

上記までの手順で train と test でフォルダ分けして画像を撮影してきた場合は、データセットの作成で「トレーニングデータセットとテストデータセットを作成する」を選択し 「S3 バケットからイメージをインポートする」を選択し、S3 URI に S3://<BUCKET>/train/ (<BUCKET> は環境にあわせて書き換えてください)と入力し「自動ラベル付け」を選択します。

クリックすると拡大します

クリックすると拡大します

テストイメージに関しても同様の手順で設定し、S3 URI に S3://<BUCKET>/test/ を入力します。このようにすることで、ラベル付が自動で行われすぐにトレーニングを実行できるようになります。

クリックすると拡大します

トレーニングが完了したらテスト結果のスコアを確認します。


もし、期待したスコアが出ていない場合は、更に条件を変えながら撮影し画像を追加します。ただし、作成したデータセットに対して再度 S3 から画像を追加できないため、再度画像を S3 に追加してトレーニングを行う場合には、アクションメニューのイメージの追加で手動で画像を追加するか、データセット一度削除して再度データセットの作成から行ってください。

クリックすると拡大します

7-4. エッジモデルのパッケージ作成

作成したモデルからエッジモデルパッケージを作成します。L4V のメニューの「エッジモデルのパッケージ」から「モデルパッケージングジョブを作成」を選択し、モデルをパッケージ化します。

クリックすると拡大します

パラメータは下記の通り設定します。

  • モデルパッケージングジョブの設定
    • ジョブ名 : 任意のジョブ名
    • ジョブの説明 : 任意の説明
  • モデルの選択
    • 作成したモデルを選択
  • ターゲットハードウェア設定
    • ターゲットデバイス を選択
  • AWS IoT Greengrass のコンポーネントの設定
    • コンポーネント名 : プロジェクト名と同じ名前を入力 (※1)
    • コンポーネントの説明 : 任意の説明
    • コンポーネントバージョン : 任意のバージョン(例: 1.0.0)
    • コンポーネントの場所 : GG から参照可能な S3 バケットを指定 (※2)

※1 : コンポーネント名 は任意のモデル名を入力できますが、手順をわかりやすくするため、ここでは L4V に作られたプロジェクト名と同じ名前を入力してください。
※2 : キャプチャコンポーネント(com.example.image-capture)を GDK で発行する際に作成されたバケットを使用するのが良いでしょう。

クリックすると拡大します

上記の設定を行い モデルパッケージングジョブを作成 をクリックするとパッケージングが開始されます。パッケージングが完了すると、GGv2 の マイコンポーネント に上記で指定された L4V のプロジェクト名と同じ名前のコンポーネントが追加されます。


8. エッジ推論の実行

推論コンポーネントはサンプルプログラムを展開した ./component/predict/ にあります。プログラム構成としては下記の通りとなっています。

component/predict/
     ├─ src (プログラム本体)
     ├─ gdk-config.json (GDK設定)
     ├─ recipe.yaml.template (recipeテンプレート)
     └─ reqirements.txt (依存ライブラリ定義)

src 以下にはメインプログラムとなる visual_inspection.py、カメラからの映像を取り込む webcam.py、Webインターフェースを提供する webserver.py、Stream Manager を使ってそれぞれ S3 に送信する s3_stream.py、SiteWise に送信する sitewise_stream.py があります。

L4V の edge_agent 関連のソースコード (edge_agent_pb2.py, edge_agent_pb2_grpc.py) は こちら を参考に生成しています。また StreamManager 関連のソースコードは こちら から取得したものを含めています。

詳しいプログラムコードの解説はここではしませんが、興味ある方はプログラムコードを参照してみてください。

8-1. 推論コンポーネントのデプロイ

8-1-1. 推論コンポーネントの登録

コンポーネントの利用を開始するには、gdk-config.json の内容確認と recipe.yaml の作成が必要です。下記の手順に従って各ファイルを ./component/predict/ 以下に作成してください。

  • gdk-config.json : キャプチャコンポーネントと同様です。内容を確認して必要に応じて変更します。
  • recipe.yaml
    • ./component/predict/recipe.yaml.template の名前を recipe.yaml に修正して保存します。
    • YAML 中の <MODEL_COMPONENT_NAME> をエッジモデルパッケージでつけたコンポーネント名 (L4V のプロジェクト名) に書き換えます (2 箇所あります)。
    • YAML 中の <IMAGE_UPLOAD_BUCKET_NAME> を CDK 実行で出力された L4VEdgeStack.S3BucketName に変更します。
    • YAML 中の <SITE_NAME> を CDK 実行で出力された L4VEdgeStack.SiteName の値に置き換えます。
    • 他のパラメータも必要に応じて変更いただけます。各パラメータの設定値詳細は下記の通りです。
ComponentConfiguration
SiteName 任意の適用サイト名(送信先リソース Prefix として使用していますので必ず CDK 出力と合わせてください)
ModelComponentNames エッジモデルパッケージでつけたコンポーネント名(複数追加する場合はスペース区切りで記述 ※1)
ImageUploadBucket 推論対象となった画像やカメラのキャプチャ画像がアップロードされるバケット
UploadThreshold 画像アップロードの Confidence しきい値(0.0 - 1.0)。この設定値より下回った場合画像が S3 にアップロードされます。(異常時にはすべてアップロードされます)
TargetVideoDevice 対象のカメラデバイス(例:/dev/video0 or filePath ※2)
VideoSourceType ビデオデバイスのタイプ( live / file )
VideoWidth カメラ画角の幅
VideoHeight カメラ画角の高さ
TempDir 撮影したイメージを S3 送信前に一時的に保存する Temp ディレクトリ
WebServerPort カメラ画像の確認用 Web インターフェースのポート番号
LogLevel ログレベル(info / warn / error / debug )

※1 : 複数のモデルを同時に使用する場合は ModelComponentNames での設定に加えて ComponentDependencies セクションに依存コンポーネントとして列挙する必要があります。
※2 : キャプチャコンポーネントと同様に動画ファイルをビデオソースとして指定できます。設定方法についてはキャプチャコンポーネントの設定方法をご参照ください。

ファイルの作成が終わったら下記のコマンドでコンポーネントをビルドします。

$ cd component/predict/
$ gdk component build

ビルドが正常に完了したら、下記のコマンドでコンポーネントを登録します。

$ gdk component publish

8-1-2. 推論コンポーネントおよび L4V Agent のデプロイ

作成した com.example.l4v-ege-sample コンポーネント、L4V で作成したモデルコンポーネント、及びパブリックコンポーネントの aws.iot.lookoutvision.EdgeAgent を Greengrass にデプロイします。 また、キャプチャコンポーネントがデプロイされている場合は、このタイミングで削除してください。 具体的には、コンポーネントの選択で下記のように設定します。


そのほかの項目はそのままデプロイを実行し、デプロイのステータスが完了となって正常にデプロイされることを確認します。

クリックすると拡大します

8-2. 推論実行

下記の URL にアクセスすることで、カメラ映像を確認しながら推論実行が可能です。

http://<デバイスのIP>:8080

※ポート番号は recipe.yamlWebServerPort 設定値に合わせて変更ください。

ブラウザにこちらのようにカメラ画像が表示されます。フォーカス設定に関しては、キャプチャコンポーネントと同様に設定できます。

クリックすると拡大します

画面左上の Model メニューから適用するモデルを選択し Predict ボタンを押下します。
※ 複数モデルの使用については recipe.yaml の設定の項目を御覧ください。

推論結果に応じて画像周辺が

  • 緑 (良品と判断)
  • 赤 (不良品と判断)
  • 黄色 (良品と判断されたが、Confidence の閾値が設定値を下回っている) 

いずれかの色で枠が表示されます。また、推論結果の詳細も画面上に表示されていきます (選択の上削除も可能)。

こちらは正常と判断された際の表示です。

クリックすると拡大します

Confidence が閾値を下回るとこちらのように黄色枠で表示されます。

クリックすると拡大します

以下は、不良と判断された際の表示です。

閾値を下回る Confidence もしくは、不良 (isAnomaloustrue) となった場合、画像は S3 にアップロードされます。アップロード先は imageUri としてログに出力されます。

クリックすると拡大します


9. 推論結果データを再学習に備え学習データセットに加える

不良と判断された画像や低い Confidence 値となった画像は S3 にアップロードされ CDK によってデプロイされた Lambda 関数 によって自動で L4V のデータセットに追加されます。

L4Vのデータセットを見てみると、ラベル付けされていない画像が確認できると思います。「ラベルを追加」ボタンを押してこれら画像にラベル付けを行っていきます。

クリックすると拡大します

ラベルを追加」ボタンを押すと、それぞれの画像の下に「Normal」、「Anomaly」ボタンが出ますので、これらボタンを押して画像に対してラベル付けを行い、すべてのラベル付けが終わったら、「変更を保存」ボタンを押して変更を反映します。


新たにラベリングした結果からモデルの再学習が可能です。再学習したモデルを用いて再度モデルパッケージを作成し、新しくできたバージョンを Greengrass にデプロイします。

クリックすると拡大します


10. AWS IoT SiteWise による推論結果のモニタ

推論結果はすべて SiteWise に送られ、CDK で事前に作成された <SiteName> <ProjectName> アセットに入力されます。必要に応じて CDK で SiteWise 上に作成された L4V result model モデルに対して メトリクスの定義定義の変換 を追加することもできます。モニタリング用の下記のようなポータルを作成することで、推論結果をリアルタイムに確認することができるようになります。

こちらのようなモニタリング用のポータルを作成することで、推論結果をリアルタイムに確認することができるようになります。

クリックすると拡大します

SiteWise の使い方の詳細については AWS IoT SiteWise のユーザーガイド や ポータルの作成ガイドAWS IoT SiteWise Workshop をご参照ください。


11. デバイスについて

冒頭でも書いた通り L4V の対応デバイスは現在のところ唯一 Jetson Xavier となっています。この理由としてはコアデバイスに少なくとも 6GB のメモリを要求することに起因しているのが大きいようです。しかし、ちょっと試すには Xavier は高価ですし、もう少し入手性の高い Jetson Nano で試せたらと思っていました。

実際にモデルのコンパイラオプションを指定 ({"gpu-code": "sm_53", "trt-ver": "7.1.3", "cuda-ver": "10.2"}) することで Jetson Nano でも動作するモデルを作成することができますし、実際動作もしました。

しかし、メモリ搭載量が原因でモデルのロードが完了しないことがあります。コンパイルされたモデルサイズを見てみると、同じ対象物を学習していたとしても 40MB ほどのモデルであったり 350MB ほどのモデルであったりと内部的に選択されるアルゴリズムによって都度モデルサイズが変わってくるようでした。ですので、モデルを作成してみてから動かない ! となってしまう危険性があるため、実デバイスでの動作検証を行う場合はやはり Xavier を手元にご用意の上検証いただければと思います。

ちなみに、今回検証中に 40MB ほどとなったモデルが出来上がったので Xavier と Nano で推論スピードの検証をおこなってみたことろ Xavier で 0.15 秒ほどの推論スピードに対して Nano では 0.3 秒ほどの推論スピードとなりました。

簡単な動作検証であれば EC2 上に GPU インスタンス (東京リージョンですと現在のところ g4dn インスタンス) を使って試していただくことも可能です。EC2 上での検証方法については、サンプルプログラムに README を含めていますので、興味あれば合わせてご確認いただければと思います。


12. 利用料金について

L4V のエッジ推論の利用にあたりトレーニング料金に加えてエッジ推論ユニットの料金が発生します。この推論ユニットは 1 ユニットで 1 分間に最大 120 検査をサポートします。例えば、1 分間に 200 推論している場合は 2 ユニットとなります。このユニットは 1 日に数時間使おうが、24 時間使おうが特定の月の利用の最大推論数/分に応じて課金されることに注意してください。3 ヶ月の AWS 無料利用枠の設定もございます。詳しくは L4Vの料金ページ をご参照ください。

また、今回の構成では L4V の料金に加えて IoT Core, Greengrass, S3, Lambda, SiteWise の料金がかかります。それぞれの料金については各サービスの料金ページをご参照ください。


13. 環境の削除について

環境を削除する場合、スタックを削除する前に、L4V で作成したデータセットおよびモデルの削除、Greengrass デバイスの証明書に割り当てられたポリシーのデタッチ、TokenExchangeRole として作成されたロールからポリシーの削除を手動で行なってください。その上で、下記のコマンドを実行することで環境を削除できます。

$ cd ./cdk/
$ cdk destory L4VEdgeStack

また、Greengrass Core のアンインストール方法については 公式ドキュメント を参照ください。


14. まとめ

今回 L4V を使ってエッジでの検査装置を作ってみたところ、機械学習の知識が乏しい私でもエッジでの推論実行は勿論のこと、継続的に学習し推論精度を上げていく構成が L4V を使うと事で簡単に実現できました。とはいえ、私のアイロンビーズを作るスピードは早くても 10 分に一つというペースなので、これであればクラウド側で推論する仕組みの方が全体的に安く付きそうです (笑)

これで LED 時計の大量生産に際してまずは検査体制が確立できましたが、それ以外の資金面などの多くの障壁が乗り越えられず LED 時計大量生産の夢は夢として終わりそうです。

謝辞

今回エッジでの外観検査装置を作成するにあたり L4V ついては AI/ML Specialist SA の卜部さんに、CDK を使った環境構築では Prototyping Engineer の秋田さんに多大なご協力をいただきました。この場を借りてお礼申し上げます。


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます


筆者紹介

渡邉 聡
アマゾン ウェブ サービス ジャパン合同会社
デジタルトランスフォーメーション本部 プロトタイピングソリューションアーキテクト

趣味は DIY で棚や机の作成から、料理から手芸まで興味のあるものは何でも作ってみます。最近は電子工作と 3D プリンターによるものづくりにはまっています。

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する