Amazon Lookout for Vision で画像の異常検出をやってみた

# はじめに

Amazon Lookout for Vision は、画像の異常を発見する機械学習 (ML) サービスで、製造業の企業が大規模に欠陥を検出することができます。最低限、正常な画像が 20 枚、異常な画像が 10 枚で使い始められます。画像のアップロードや、正常・異常のラベル付けなど、AWS の GUI から操作が出来るため、難しい機械学習の知識が不要で始められます。

Amazon Lookout for Vision を使って、正常・異常を推論する方法を紹介します。



# S3 Bucket の準備

適当に、Lookout for Vision 用のバケットを作成します。

- バージョニングを有効にする。
- S3バケットの下に、trainとtestのフォルダを作成します。
- trainフォルダの下に、「normal」と 「anomaly」の2つのフォルダを作成します。
- testフォルダの下に、「normal」と 「anomaly」という2つのフォルダを作成します。

![image-20230219161741751.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/8f7fbf9c-6af5-dce0-1e79-96cb908bac67.png)



AWS が公開しているサンプル画像を S3 にアップロードしていきます。まず、Git から Clone します。

```
git clone https://github.com/aws-samples/amazon-lookout-for-vision
```



ディレクトリを移動します。

```
cd amazon-lookout-for-vision
```



S3 Bucket にコピーします

```
aws s3 cp circuitboard/train s3://lookout-for-vision-sugi01/train --recursive
aws s3 cp circuitboard/test s3://lookout-for-vision-sugi01/test --recursive
```



# Lookout for Vision で Project 作成

Lookout for Vision の画面で、Get Started を押します。

![image-20230219163812304.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ca0517b5-7455-53da-084f-21fba15b2030.png)



Create S3 Bucket を押します。

![image-20230219163858365.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/64a1dc0f-a7ab-0d31-5623-0000856abfa8.png)



Create Project をおします。

![image-20230219163937455.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e01b1344-8cc2-23a8-4632-9b617440dea9.png)



名前を付けて、Create project を押します。

![image-20230219164006711.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/57a18074-926e-1660-6031-5cbd896cb9a4.png)



Project が出来上がったので、Create dataset を押します。

![image-20230219164053427.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/0e8d15e6-339b-5837-4383-9152126a8e3f.png)



Create a training dataset and a test dataset を押します。

![image-20230219164145103.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/5814af18-f017-c844-7662-db0c3e05148f.png)



アップロードした S3 バケットを選択します。また、トレーニングで利用するラベルの、オートラベリング機能を有効化します。オートラベリングでは、normalフォルダの画像には「normal」、anomalyフォルダの画像には「anomaly」というラベルが貼られます。 オートラベリング機能を使うと、これらの画像に手動でラベルを付ける手間が省けます。

![image-20230219164317528.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/f35c496d-41c3-a60a-b962-cdad18511eaa.png)



テストデータも同様に指定します。

![image-20230219164546472.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/f33742f5-b6da-f3ac-4c29-b01e7b642ab0.png)



Create dataset を押します。

![image-20230219164600873.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/8cf86157-8763-41b2-b54f-4ca9d37dcbc3.png)



Dataset が作成され、S3 に格納したディレクトリごとに、異常な画像と正常な画像が認識されました。

![image-20230219164831649.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/01215d05-7e57-b51d-38d2-1f6a5fc99317.png)



異常な画像を見てみると、はんだ付けが失敗している画像となっていることがわかります。

![image-20230219165007917.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/3abf278e-b076-895e-67d3-97b6e5ca9560.png)



Normal は綺麗な画像ですね。

![image-20230219165053376.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/f4b9882e-d734-c489-b0a7-d5d018ca1c7e.png)



# トレーニング実行

Train model を押します。

![image-20230219165152659.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/0ecdf09c-3f5e-6d3e-5b3d-dfeb1f696377.png)



Train model を押します。

![image-20230219165218722.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c0d0d31d-b7fe-4b5d-d16a-99418df3831d.png)



Train model を押します。

![image-20230219165231664.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/b07234d2-8683-933e-d968-5db05061412f.png)



Training が進んでいる様子がわかります。この記事の環境では、約 35 分ほどかかりました。

![image-20230219165300245.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/9d33a985-30fa-441f-e95a-1fd8d3313fcb.png)



Training が完了しました。

![image-20230219173217959.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/6b93d5fa-7a19-ebfa-84ce-4b29b588f7f8.png)



トレーニングしたモデルに対して、テスト用に準備した画像をつかった結果が表示されています。

- 偽陰性 (False Negative) : 2 件
- 偽陽性 (False Positive) : 1 件

![image-20230219173332121.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/66fd787c-ed6a-d21a-7fc7-d6b7fe381c05.png)



偽陽性や偽陰性と検出された画像にフィルターして、確認ができます。評価結果を見ながら、精度の改善が必要な場合には、さらなるトレーニング用の画像を調整していくことが考えられます。

![image-20230219173556940.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/2c614f1b-e495-1f50-5eb1-13bada60e6b8.png)



# 別の画像でトライアル推論してみる

出来上がったモデルに対して、手元にある画像を使った推論ができます。Run trial detection を押します。

![image-20230219173907507.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/2811db51-e26b-475c-7b73-7126a8f684ac.png)



ローカルからアップロードする方法を選択して、Detect anomalies を押します。

![image-20230219173954742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/16ceb12a-c224-140e-aaf0-c2877f8957b7.png)



Run trial detection を押します。

![image-20230219174100230.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e58d11fc-0405-aeba-0cb7-df3ad736caa3.png)



5 つのファイルを選択して、Upload image を押します。

![image-20230219174138446.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/b7c1e157-d3b7-0268-d40c-d49c191e534f.png)



推論処理をしてくれます。この記事の環境だと、8 分ほど掛かりました。

![image-20230219174251545.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/15f5d9c9-9373-9fd6-b93f-fc947f4d2c57.png)



全て Anomaly と評価されました。Verify machine predictions でフィードバックします。

![image-20230219175044883.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/fffcc8d5-dee8-89f7-4c2e-2a8d1c091a91.png)



正しい結果の場合には「Correct」を押して、間違っていた場合は「Incorrect」を押します。

![image-20230219175153132.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/184578af-6d1b-69bd-9595-05967108b081.png)



この結果を再度トレーニングデータに格納させることも出来ます。

![image-20230219175228579.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/6d8ceaa5-c47b-7a18-a196-31ef07f3510c.png)



# 本番用に Model をデプロイする

デプロイしたい Model を選択して、Integrate API to the Cloud を押します。

![image-20230219175951934.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/1ec69db6-cb75-b680-cd8d-dde18df92fa9.png)



AWS CLI のサンプルが表示されるのでメモっておきます

モデルの開始

```
aws lookoutvision start-model \
  --project-name lookoutforvision-demo \
  --model-version 1 \
  --min-inference-units 1
```



異常検出

```
aws lookoutvision detect-anomalies \
  --project-name lookoutforvision-demo \
  --model-version 1 \
  --content-type image/jpeg \
  --body /path/to/image.jpeg
```



モデルの停止

```
aws lookoutvision stop-model \
  --project-name lookoutforvision-demo \
  --model-version 1
```



start-model の実行例

```
> aws lookoutvision start-model \
        --project-name lookoutforvision-demo \
        --model-version 1 \
        --min-inference-units 1
{
    "Status": "STARTING_HOSTING"
}
```



Model が Starting Hosting のステータスに変わります。

![image-20230219180147015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/b73b881a-2bf6-4206-9ce3-039820d8b868.png)



約 3 分ほど待機すると、Hosted に変わりました。

![image-20230219180550187.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/48ee5cd4-7ef8-efa7-bc7d-fb3e44c50347.png)



AWS CLI から異常検出をしてみます。

```
aws lookoutvision detect-anomalies \
  --project-name lookoutforvision-demo \
  --model-version 1 \
  --content-type image/jpeg \
  --body extra_images-anomaly_9.jpg
```



実行結果 : IsAnomalous が true となっているので、異常となっていることがわかります。信頼度は 0.98.... となっています。

```
{
    "DetectAnomalyResult": {
        "Source": {
            "Type": "direct"
        },
        "IsAnomalous": true,
        "Confidence": 0.9898422360420227
    }
}
```



# Model を停止

Model を動かしていると料金が掛かるので、使わなければモデルを停止します。

```
aws lookoutvision stop-model \
  --project-name lookoutforvision-demo \
  --model-version 1
```





# 検証を通じてわかったこと

- S3 で正常な画像を格納する「anomaly」ディレクトリと、異常な画像を格納する「normal」のディレクトリを作成することで、自動的にラベリングしてくれる。
- Lookout for Vision の料金は、inference unit をどれくらい、何時間稼働させたかによって計算ができる。
  - start-model を実行することで推論が出来るようになり、stop-model を実行するまで、その時間分料金が発生する。表現を変えると、start-model をしている間は、推論をしなくても、料金は掛かり続ける考え方となる。
  - https://docs.aws.amazon.com/lookout-for-vision/latest/developer-guide/running-model.html
- inference unit を手動で増減させる場合は、一度 stop-model してから必要な数を指定して再起動させる。10-20 分のダウンタイムを許容できるときに、この方法を取りやすい。
  - https://docs.aws.amazon.com/lookout-for-vision/latest/developer-guide/running-model.html
- オートスケーリングをさせることも可能
  - https://docs.aws.amazon.com/lookout-for-vision/latest/developer-guide/running-model.html
- NVIDIA Jetson と AWS IoT Greengrass を使ってエッジ推論をさせることも可能
  - https://catalog.us-east-1.prod.workshops.aws/workshops/cbfb2625-416f-45e3-88b2-b68a1d25dab2/ja-JP/lab3
- サポートされる画像
  - JPEG および PNG
  - 最大 5 MB の画像ファイルサイズをサポート
* 精度を上げるための Tips
    * 学習時に与える画像の状況と、本番自に利用する画像の状況を同じにするのが良い。カメラの位置、光の具合、製品の角度、製品の大きさ、などなど
    * 画像の中には、対象の製品のみ中央に映すことで、精度の向上が期待できる。関係ないものは画像には入れない
    * 画像の寸法は、モデル学習時・本番利用時に同じものを利用する
    * https://docs.aws.amazon.com/ja_jp/lookout-for-vision/latest/developer-guide/model-create-dataset.html
* 画像の中で、どこが異常なのかを教えてくれる機能が追加された
    * https://dev.classmethod.jp/articles/lookout-vision-update-segmentation/




# 参考 URL

https://catalog.us-east-1.prod.workshops.aws/workshops/cbfb2625-416f-45e3-88b2-b68a1d25dab2/ja-JP