Amazon Lookout for Visionで青森認証やってみた

不良品検出のAIサービス「[Amazon Lookout for Vision](https://aws.amazon.com/jp/lookout-for-vision/)」が先週25日(木)に[東京リージョンでの提供開始が発表](https://aws.amazon.com/jp/blogs/news/amazon-lookout-for-vision-tokyo-ga/)されましたが、27日(土)には早くも「AWSの基礎を学ぼう」コミュニティの[ハンズオンが開催](https://awsbasics.connpass.com/event/201477/)され、実際に体験してみることができました。

AI、機械学習系のハンズオンということで待ち時間なんかもあるわけですが、そこにソラコムの @ma2shita さんの「[Amazon Lookout for Vision 向いてるコト、使いどころと注意点](https://speakerdeck.com/soracom/what-amazon-lookout-for-vision-can-be-used-for-and-how-to-use-it)」とかJAWS-UG名古屋の [@nori2takanori](https://twitter.com/nori2takanori) さんの「[画像ベース異常検知Amazon Lookout for Visionを使ってみよう](https://www.slideshare.net/TakanoriTsutsui/20210227awsbasic)」とかLTが入って、退屈する暇のない2時間でした。その中で出てきたスライドの一枚がこちら。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/10cb2c37-73e5-75cc-db62-0fca244ed09a.png)

Lookout for Visionは不良品検知にしか使えないサービスじゃないぞ、と。アイデア次第だぞ、と。じゃあ安直ですが、あれやってみようと思いました。あれです、 **[青森認証](https://twitter.com/marugotoaomori/status/1364772606650572802)** です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/c725043a-809a-78dd-4353-dc99f94f20f0.png)

「青森版『私はロボットではありません』画像選択」とのことですが、「[“Apple”の認証画面](https://maidonanews.jp/article/14222420)」なる呼び名もあるようです。しかしここは独断により青森認証と呼ぶことにします。

# 千里の道もリンゴより

ハンズオンでは手順は決して複雑ではなかったけど、とにかく「正常な布地写真」と穴が開いてたり異物混入してたりする「異常な布地写真」を使ってたのが印象に残ってます。Lookout for Visionはこれらを学習して、「これ正常」「これ異常」と見分けられるようになってくれるサービスなのです。

ということはフジの画像とフジじゃないリンゴの画像を学習させて、「これ正常（フジ）」「これ異常（フジじゃない）」と見分けられるように教え込めばいいわけです。青森脳育成プロジェクトです。青森脳育成の第一歩は、リンゴ画像から、なのです。そういうわけで、フジとフジじゃないリンゴ画像をかき集めたのがこちら。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/007937fd-99e7-8e51-a1f7-cc467338288b.png)

……疲れました。しかしこれさえ済めば勝ったも同然です。

# 青森脳の誕生（Lookout for Visionのモデル作成まで）

AWSにサインインし、[Lookout for Visions](https://console.aws.amazon.com/lookoutvision/home)の「プロジェクト」を開きます。初回セットアップとしてS3バケットを作りたいと言われるので、許可します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/e17c6635-59be-e81a-252f-c2c1edf9a47b.png)

適当な名前でプロジェクトを作ります。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/9c06037b-f1c0-24ab-9db3-1beca5816a30.png)

ここで作成されるデータセットに「画像を追加」として、まずフジの画像をまとめてアップロードします。20枚集まってました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/cc0213e9-979b-ece5-6f41-db8a577fb542.png)

アップロードされた画像に「正常」「異常」のラベルを付けます。今回はフジの画像をアップロードしたので、すべて「正常」としたいです。「このページのすべてのイメージを選択」→「正常として分類」→次のページへ移動→「このページのすべてのイメージを選択」→…を繰り返して、すべてに「正常（Normal）」のマークを付けます。済んだら「変更（20）を保存」で保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/84a93b50-f28a-1c06-bd0a-0ab7d2f29eb4.png)

同様に、フジ以外のリンゴ画像もアップロードし、すべて「異常」として登録します。アップロード後、「フィルター」で「ラベルなし」を指定すると、あとからアップロードした画像だけが表示されるので、同じ手順で全部「異常（Anomaly）」ラベルを付けて保存します。

正常画像が20枚以上、異常画像が10枚以上になると、学習が可能になります。具体的には、「モデルをトレーニング」というボタンが押せるようになるので、やっちゃいます。モデルのトレーニングには30分ぐらいかかる（かかった）ので、しばらく待ちます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/1d8a63f6-9e70-1889-2059-6734dfe55edf.png)

一点、ポイントを。画像サイズがすべて同じじゃないと、以下のエラーメッセージで失敗します。学習開始直後すぐに出るようなので、少しの間見守っているといいかもしれません。

```
Images in the dataset must have the same dimensions.
```

モデルのステータスが「トレーニングが完了」になれば、準備完了です。言い換えれば、青森脳の誕生です。ここまでノーコード、ノーコマンド、ノーAI/ML知識で来れてしまいました。素晴らしいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/ef080acf-1604-f460-7574-c2d2840ab59a.png)

# 対決、青森認証 vs 青森脳（Lookout for Visionによる異常判別）

いよいよ青森脳を青森認証に挑ませます。そのためには、青森認証のリンゴ画像を一つ一つ、青森脳に見せてやれるようにします。そう、また個別ファイルを作成するわけです。こんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/cb6621a1-eb56-a380-8d9d-88e1cc5e148f.png)

これさえ済めば、勝ったも同然です。青森脳（Lookout for Visionで作成したモデル）による異常判別は、残念ながらAWS CLIを使った実行になりますが、コマンドはほぼコピペでOKです。モデルの画面で「モデルを使用」タブを開くと、必要なコマンドが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/cf606965-430f-a52a-9f97-e22d7d805b54.png)

一つ目のコマンドをそのまま実行すると、青森脳が起動されます。起動完了までに少し時間がかかり、それを待たずに二つ目の異常識別コマンドを実行しようとすると「状態がHOSTEDになるまで実行できないよ」的なエラーメッセージが返ってきます。起動状況はパフォーマンスメトリクスタブで確認できるので、完了を待ってください。

起動が完了したら、二つ目の異常識別コマンドを実行します。これもほぼこのまま実行すればいいのですが、最後の `/path/ti/image.jpg` 部分を識別したい画像ファイルのパスに変更します。相対パスでも、Windows環境ではパス区切り文字が `\` でも大丈夫でした。実行例はこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/d1f54ef0-7e9d-4abf-6bc1-c860af2865ff.png)

実行結果で先ず見るのは `IsNomalous` 。これが `true` のときは「異常発見」ということになります。今回の場合は `true`＝異常＝フジじゃない、ということです。この例ではフジの写真画像を指定して判別させていて、`false`つまり正常、フジだと判別されていますね。もう一つ見ておくのが `Confidence` 。これは判定結果の信頼度を表しています。56%ぐらい……自信なさげですね。大丈夫、合ってますよ。

ここでまた引っ掛かったところをいくつか。

* AWS CLIが古いと`aws lookoutvision`ができません。[Changelog](https://github.com/aws/aws-cli/blob/v2/CHANGELOG.rst)を見る限りそんなことはなさそうなのですが、私の環境は2.0.0版で実行できませんでした。最新MSIファイル (2.1.27版でした）に更新しました。
* 識別対象画像も学習用画像と同じサイズにしておくことが必要です。サイズが異なると`Image failed to pass validation.`というエラーになります。

こんなあたりに気を付けながら、9つのリンゴ画像を一つ一つ判別していけば、青森認証に回答できます……できるはずです……！あ、判別が終わったら三つ目のコマンドを実行して、青森脳を停止してやってください。青森脳（モデル）の稼働時間中は、利用料金が発生し続けます。本当に止めるのだけは忘れないでください。

# そしてこうなった

ということで、やってみた結果をまとめておきます。[正解も公開されている](https://twitter.com/marugotoaomori/status/1365134994511814658)ので、それも並べておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/1cd3ad78-9e55-17e3-3ed8-edadb482ca68.png)

残念ながら、あと一歩でした。上段中央のフジを「フジじゃない」と認識してしまいました。信頼度も（もっと低信頼度の異常判定もあるとはいえ）52%とそこそこ低めに出ています。本当にもうちょっとという感じで残念です。実用にする場合はここで、もう少しトレーニングを重ねていくことになりますが、今回はここまでです。

さいごに少し、ハンズオンおよびその間のLT2本で学んだことを思い出しながら、Lookout for Visionについて振り返ってみたいと思います。

* **[Lookout for Visionが得意なのは正常/異常の2値分類](https://speakerdeck.com/soracom/what-amazon-lookout-for-vision-can-be-used-for-and-how-to-use-it?slide=9)**。今回は「フジ＝正常」「フジじゃない＝異常」というキメをしたので、Lookout for Visionの対象にできました。これがフジと紅玉と北斗と…を区別する、といった3種類以上の分類になるときは、他サービスを使います。
* [**学習時と異常判別時の画像サイズ**](https://speakerdeck.com/soracom/what-amazon-lookout-for-vision-can-be-used-for-and-how-to-use-it?slide=10)は全部統一。しないとトレーニング実行時とか、異常判別時とかにエラーになる。
* **[画像ファイルの品質も併せておいた方がいい](https://speakerdeck.com/soracom/what-amazon-lookout-for-vision-can-be-used-for-and-how-to-use-it?slide=10)**。今回、枝についたまま緑の背景の画像がいくつも学習用画像に入ってました。青森認証での表示に合わせ、この背景をきれいに削除してやったら精度が上がったのではと思います。
* **学習用画像の収集が容易になる工夫をする**。[画像合成で作っちゃう](https://speakerdeck.com/soracom/what-amazon-lookout-for-vision-can-be-used-for-and-how-to-use-it?slide=17)とか、数を用意し異常バリエーションを作りやすい[お菓子を対象にやってみる](https://speakerdeck.com/soracom/what-amazon-lookout-for-vision-can-be-used-for-and-how-to-use-it?slide=17)とか。
* **[用途はアイデア次第](https://speakerdeck.com/soracom/what-amazon-lookout-for-vision-can-be-used-for-and-how-to-use-it?slide=12)**。正常/異常の二値分類しかできませんが、例えば「家電の運転ランプを撮影して正常（消灯）/異常（点灯）判別で切り忘れを調べる」とか「ドアのカギを撮影して正常（横になってる）/異常（縦になってる）判別で締め忘れを調べる」とか、不良品検出以外にもいろいろな使い道がありそうです。

以上、青森認証は青森脳で解けるのか、でした（違いました）。

# 参照

* [Amazon Lookout for Vision (コンピュータービジョンを使用して視覚表現の欠陥や異常を発見) | AWS](https://aws.amazon.com/jp/lookout-for-vision/)
* [Amazon Lookout for Vision 東京リージョンで一般提供開始のお知らせとオンデマンドウェビナーのご紹介 | Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/amazon-lookout-for-vision-tokyo-ga/)
* [AWSの基礎を学ぼう 特別編　最新サービスをみんなで触ってみる はじめての画像ベース異常検知 - connpass](https://awsbasics.connpass.com/event/201477/)
* [Amazon Lookout for Vision 向いてるコト、使いどころと注意点/what-amazon-lookout-for-vision-can-be-used-for-and-how-to-use-it - Speaker Deck](https://speakerdeck.com/soracom/what-amazon-lookout-for-vision-can-be-used-for-and-how-to-use-it)
* [画像ベース異常検知Amazon Lookout for Visionを使ってみよう](https://www.slideshare.net/TakanoriTsutsui/20210227awsbasic)

実施中はエラー解決に以下も参考にさせていただきました。

* [Amazon Lookout for Visionで行う「機械学習による欠陥品検出」、活用のTips - Qiita](https://qiita.com/ma2shita/items/fb61de364ab316ff47a4)