【GCP】AutoMLを使ってノーコード画像認識AIを作ろう！

今回は、先日行われた「Google I/O 2021」で発表されたVertex AIの**AutoML**を利用した自動識別AIを作っていきます。

注：今回の内容は、GCPの課金対象となります。金額に関しては、注意しながら作成してください。問題が発生してもこの記事の作者は、一切責任を取りません。AutoMLの金額に関しては、[こちら](https://cloud.google.com/vertex-ai/pricing)を確認してください。

## AutoML とは
AutoMLは、Google Cloud Platform内にあるVertex AIにおける一つです。
Vertex AIの紹介ページには、下記のように書かれています。

---
> Build with the groundbreaking ML tools that power Google, developed by Google Research

訳：Google Researchが開発したGoogleを支える画期的な機械学習ツールで構築
> Deploy more models, faster, with 80% fewer lines code required for custom modeling

訳：カスタムモデリングに必要なラインコードを**80%削減**し、より多くのモデルをより迅速に導入
> Use MLOps tools to easily manage your data and models with confidence and repeat at scale

訳：MLOpsツールを使用して、データとモデルを信頼性の高い方法で容易に管理し、大規模に繰り返すことができる

---
上記の中で一番特徴的なのは、コードを80%削減することができるという点です。誰でも、簡単にAIを使った識別をできるようになるのです！なぜ、Vertex AIがプログラム量が少なくても識別AIを作れるのかというのが公式サイトに書いてありました。

> ![bg_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/0c378bd9-6ed6-74af-e061-1600393624ae.png)
Vertex AI には、目的に合った結果を得るために使用できる、教師あり学習タスクが含まれています。アルゴリズムやトレーニング方法の詳細は、データ型とユースケースによって異なります。機械学習にはさまざまなサブカテゴリがあり、それらはすべて異なる問題を解決し、異なる制約の中で動作します。

便利な時代だなと思いました。
Vertex AIの詳細については、[このページ](https://cloud.google.com/vertex-ai/docs/start/introduction-unified-platform)を参照してください。
その中でも、AutoMLは、プログラムに詳しくない人が利用できます。AutoMLだけでなく、Vertex AIにはカスタムトレーニングというプログラムの技術やデータサイエンスの知識が必要となりますが、細かく設定のできるモードも存在します。（プログラムの量は通常より削減できます）
どちらにしようか悩んでいる方は、[このページ](https://cloud.google.com/vertex-ai/docs/start/training-methods)を参照してください。表になって細かく書いてあります。
今回は、AutoMLを利用します。
## 実際に行ってみる
それでは、行ってみましょう！
### 識別させたい画像を用意する
AIに学習させるためには、同じラベルの画像が通常は最低10枚以上必要になります。（今回の場合は、100枚以上の画像が一つのラベルに必要です）識別させたい画像を事前に用意しておいてください。どの画像を使おうか決まってないや、そんなのないという方は、ここからデータセットをダウンロードして利用することをおすすめします。今回、データセットを利用させてもらったサイトは、[こちら](https://www.kaggle.com/tongpython/cat-and-dog)です。kaggleは、AIのデータセットがたくさんあり有名です。（ダウンロードには、**会員登録が必要です**）今回は、犬と猫を見分けることを目標とします。（Zipでダウンロードされるので、解凍して利用します。解凍すると200MBぐらいになります。）
### データセットを作成する
Vertex AIは、ハンバーガーメニューのしたの方にあります。
![1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/4de1182f-7226-74ec-254e-736b0f429459.jpeg)
Vertex AIにアクセスすると**Enable Vertex AI API**と書いてあるのでそこをクリックして、ENABLEにします。
![2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/7fce98f5-b167-96a4-9b9b-4a6dc4be25ce.jpeg)
ENABLEにすると下の方にある**データセットを作成**が選択できるようになるのでそれをクリックします。
![3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/7502d292-b1bf-c82c-dcfc-403f33ed13a6.jpeg)
今回は、犬と猫を同時に読み込ませてもどちらが犬でどちらが猫かというのが表示されるようにします。なので、データタイプと目標の設定で**画像分類（マルチラベル）**を選択します。データセット名は、何でも大丈夫です。ここには、日本語の入力もできます。（初期のuntitled~~のままでも問題ありません）リージョンに関しては、どちらでもよいです。ですが、GCPは、基本的にusリージョンの方が安いのでusにしておくことをおすすめします。設定が完了したら作成をクリックします。
![4](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/18e515a5-1e10-135f-e5cf-903f24f64409.jpeg)
作成が完了すると画像をインポートする画面になります。
![5](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/4afd4890-607f-1fd7-6456-353d21147704.jpeg)
ここで先ほどダウンロード（事前に用意した画像）した画像をインポートします。インポートする際に、犬と猫を分けてアップロードすることをおすすめします。（ラベル付けが楽になります）今回は、最初にも書いたのですが10枚アップロードしたところ100枚ないと出来ないよ見たいな表示がでてくるので先ほどダウンロードした画像から犬と猫をそれぞれ100枚以上分けてインポートします。画像をインポートするとしたの方にストレージのパス（画像を保存するストレージ）の選択を求められます。使っていないストレージを利用してください。新規作成する場合、BROWSEから右上に追加マークがあるので新規作成できます。保存ストレージのパスを決めたら続行をクリックします。右下にアップロードステータスが表示されます。
![6](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/640120d5-19ba-f241-b644-17cef4078a88.jpeg)
アップロードが完了すると下記のような画像になります。このステップには、時間がかかります。完了するとメールが届くので完了まで待ちます。

| GCP | メール |
|:-:|:-:|
|![7](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/b6637abc-510c-2b24-b9f0-d46149999970.jpeg)|![8](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/7f59143c-05f7-91fa-cf43-a523bec85af5.jpeg)|

完了メールが来たら上の方にある**参照**に移動します。まずは、ラベルを作成します。今回は、犬と猫を見分けたいので**新規ラベルを追加**をクリックします。下記のように表示されるので**Dog**と入力します。次にもう一度新規ラベルを追加から**Cat**と入力して完了です。（ここでは、<font color="Red">英語のみ</font>入力できます）
![9](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/97b4e167-53d2-da6b-479e-2b13c72e7be0.jpeg)
### トレーニングの準備をする
**全て選択**→**ラベルの割り当て**を選択します。（この際に、下の方にあるページあたりのアイテム数を**100**にしてから全て選択にすると楽です）
![10](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/ef50dae0-e348-5fd1-8084-2bc1a6a66b5d.jpeg)
ラベルの割り当てを選択すると先ほど作成したラベルが表示されるのでインポートした画像のラベルを選択します。
![11](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/514b08c8-cba1-922c-b382-ed5262e98092.jpeg)
続いてもう一方の画像をインポートして先と同様にします。全てアップロードしてラベルを分別するとトレーニングを行えるようになり、画面の右上に**新しいモデルをトレーニング**を選択できるようになります。表示されていない場合は、分析タブにどうしたらよいか書いてあるので確認してみてください。
![12](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/eef8438e-478c-37b2-ab2d-48e755fe574a.jpeg)
新しいモデルをトレーニングをクリックすると下記のような画像の画面が表示されるので、**AutoML**が選択されていることを確認して特に変更せず次の画面に進みます。
![13](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/7de21b0c-e0b8-7fb5-8cf5-1fc3cf60931f.jpeg)
ここら辺は、自信にあった設定にしてください。（モデル名の変更は、自由ですが、他は特に変更する必要ありません）
![14](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/74c66589-217d-59de-37d9-b18e94c7736b.jpeg)
次に、時間の設定なのですが、最低でも8ノードにする必要があるので**8**と入力します。この際に、下にある**Enable early stopping**の設定にチェックをいれといてください。（標準でこの設定になっていると思いますが）200枚ぐらいの写真なら20分ぐらいでトレーニングが終わるので、8ノードの設定でトレーニングをすると料金が無駄に高くなります。注意してください。
![15](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/b4fc5ab6-2956-18d7-5ba7-aaddc3fd6783.jpeg)
全ての設定が完了したらトレーニング開始をクリックします。
### トレーニング結果を確認する
20分ぐらいでトレーニングは、終わります。（200枚程度なら）トレーニングが完了すると左側にある一覧の**モデル**という場所をクリックするとトレーニングが完了していることがわかります。また、先ほどの画面のままの方は、（一つ前のステップの最後の方の画面）このような表示がでているのでモデル名をクリックすることでとトレーニングの結果を確認できます。
![16](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/c11ce341-4782-0fc4-904e-bcff59384c4b.jpeg)
私の場合、下記がトレーニング結果になりました。（少し画像を増やしたりしているので枚数が先ほどまでと違います）
![17](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/ae539d1f-592e-39ea-32e8-be70685d92dc.jpeg)

| 再現率 | 信頼度のしきい値 |
|:-:|:-:|
| ![18](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/3fd071eb-f8a2-cefb-f4d3-8f6232e3151e.jpeg)|![19](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/481c67f6-5a45-6fb3-063b-a9a8ecc3f3b5.jpeg)|

上記のように詳細を確認できます。今回、私がインポートした画像の場合、AIがテストの際に誤って認識してしまったものがありました。左側にあるラベル横の数値が1となっていない場合は、何かしらの間違いをしてしまったということになります。詳細を確認するには、左側にあるラベルをクリックすると2枚目の写真のように確認できます。
![20](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/7643fae9-6f19-da7f-edab-0796e3f1161e.jpeg)
↓間違えてしまった画像
![21](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/140d4777-308f-29e8-2a46-5270c4dc4de8.jpeg)
### モデルを自動的に分類させてみる
ここまでで、AIは、犬と猫をだいたい見分けられるようになりました。最後に、本当に見分けられているのかを確認してみます。
![22](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/372029da-47cc-3e37-c5de-f97a9e26353c.jpeg)
**デプロイとテスト**→**エンドポイントへのデプロイ**をクリックします。エンドポイント名は、自由に入力します。コンピューティング ノード数を**1**と入力します。入力したら次のステップに進みます。
![23](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/447b5b4d-db6d-d828-163e-3b3cd9fa02dc.jpeg)
次のステップは、特に変更せずにそのままにします。そして、デプロイします。
![24](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/1b1f6144-e01e-27f5-2c29-2beac663d1c6.jpeg)
全て完了するとエンドポイントが作成されます。（20分ぐらいかかります）最後に、API経由でAIに、画像に写っている犬や猫を識別させていきます。

----

**作成した設定をもとに実行していきます。**

## 実行環境
- Debian10
- Google Cloud SDK v340.0.0

## Google Cloud SDKのインストール
私は、GCEを利用したため、既にGoogle Cloud SDKがインストール済みでした。なので、割愛させていもらいます。
何かしらを見たいというかたは、[GCPの公式ドキュメント](https://cloud.google.com/sdk/?hl=ja&_ga=2.163354684.-1418878339.1620039210)を参考にしてください。

## 実行環境を作る
ログインします。（ここら辺は、コマンド上の指示にしたがってください）

```
gcloud init
```

認証します。（ここもコマンド上の指示にしたがってください）

```
gcloud auth application-default login
```
ここまでで、たまにエラーとかでたりします。（自分もでました。）もし、解決できなさそうならコメント欄に書き込んでください。

実行するための画像ファイルを入れるjsonファイルを作成します。ファイル名は、何でもよいですがパスを後で通すので楽な名前にしておくことをおすすめします。

contentの中にbase64でエンコードした画像文字列が必要です。この際に、変換サイトなどで変換すると文字列の最初に**data:image/jpeg;base64,**とついている場合があるのですが、この部分は必要ないのでカットして張り付けてください。ちなみに、画像サイズがでかいと文字列の長さが大変なことになります。（解像度を下げたりするとよいです）

```json:set.json
{
  "instances": [{
    "content": "base64にエンコードした画像文字列"
  }],
  "parameters": {
    "confidenceThreshold": 0.5,
    "maxPredictions": 5
  }
}
```

次は、ProjectIDなどが必要です。確認するには、「Vertex AI」→「エンドポイント」→作成したエンドポイントをクリックします。右上に「リクエストの例」があるのでクリックします。4番目のステップに書いてあるのがendpoint_idとproject_idです。それをそのままコピーしてコマンドに張り付けて実行します。
![25](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/073fb723-0e47-1e24-4f7d-db9fdbb4bf1f.jpeg)
**INPUT_DATA_FILE**には、先ほど作成したjsonのパスを入力します。

```
ENDPOINT_ID="XXXXXXXXXXXXXXXX"
PROJECT_ID="XXXXXXXXXXXX"
INPUT_DATA_FILE="/vertex/set.json（例）"
```

パスを通したら下記のコマンドを実行します。

```
curl \
-X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://us-central1-aiplatform.googleapis.com/v1alpha1/projects/${PROJECT_ID}/locations/us-central1/endpoints/${ENDPOINT_ID}:predict \
-d "@${INPUT_DATA_FILE}"
```

実行すると下記のようにレスポンスされます、
![26](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527236/bd3a1c4e-6f53-e390-7167-aaa58fd87b62.jpeg)
この場合、0.999995708の割合で（1が上限）犬と見たようです。ちなみに、インプットした写真は、犬の写真だったので正解でした。

## 最後に
いかがだったでしょうか。このようにしてノーコードで簡単に犬と猫を見分けられるAIを作成しました。ラベルを増やせば、見分けられる種類を増やすことができます。