ABEJA Platformで真贋判定するAIを作成

# はじめに
縁あって株式会社ABEJA様よりABEJA Platform評価用ライセンスを発行して頂き、ROLEXのDAYTONAの真贋判定を行うモデルを作成してみました。

真贋判定の対象をROLEXのDAYTONAに理由は、偽物のデータを集めやすそうだなと思ったからです。（そもそも偽物がある題材が他にパッと思いうかばかった）

本記事では、最初にモデル作成までの過程を記載して、最後にABEAJA PlatformとAI作成についての感想を記載したいと思います。
記事の中には、実際の操作の中で画面コピー撮り忘れていたものがある為、代わりの画像を用意して貼り付けたものがある事をご了承下さい。

あと、私自身はAI関係の第一線に身を置いているわけではなく、本格的なAIプロジェクトも未経験の独学中の人間です。
そういう立場からの記事であることをご了承下さい。

# データの収集
まずはDAYTONAの画像データの収集です。`icrawler`など画像収集に便利なライブラリがありますが、検索ワードだけで収集するのは難しいと判断して、正規取扱店と色々香ばしいWebサイトからコツコツ画像データをダウンロードしました。

余談ですが、`icawler`については[この記事](https://tech-blog.abeja.asia/entry/santa-recognition-from-scratch)が参考になりました。

# データの蓄積
収集したデータをABEJA Platformに蓄積します。
ABEJA Platformでは「チャンネル」というところに蓄積することになりますので、チャンネルを作成します。

画面左のメニューから「DataLake」-「Channel」をクリックし、画面右上の「Create Channel」ボタンをクリック。

![channel01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/5862f612-2dce-9fc1-2dba-9a6d26956f32.png)

下図画面が出現するので、それぞれの項目に値を入力して画面右下の「Create Channel」ボタンをクリック。

- Identifier: 任意のチャンネル名
- Description: チャンネルの説明

![channel02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/f206ff7e-d081-b362-014b-3de75897206f.png)

DataLake一覧画面に戻ると、先ほど作成したチャンネルが一覧に表示されています。
`Channel Name`がリンクになっているのでクリック。
![aaaaaaaaaaaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/dbe03203-47b3-534b-47ee-b94a6a7bb9a0.png)

右側にある「Upload」ボタンをクリック。
![channel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/d8cd79ca-4d61-665a-c3aa-760205a31c84.png)

アップロードしたいファイルを選択するには、画面中央のグレー領域にアップロードするファイルをDrag and Drop。
もしくは、画面中央のグレー領域の中央にある「select files」ボタンをクリックして、ダイアログ画面からアップロードするファイルを開く。
![channel05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/b9c9d057-7b2f-34b2-da1c-1e24887a7cb7.png)

アップロードするファイルが選択出来たら、画面下にある「Upload」ボタンをクリック。（下図では1つのファイルだけですが、実際は複数のファイルをアップロードしました。）
![channel06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/e335af2d-67fc-022f-e5e9-a41cea4559d3.png)

アップロードが終わったら画面右下の「Close」ボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/cd2fbf97-2556-7b4f-4208-517db39af94e.png)

# アノテーション
画像のアップロードが完了したら、アノテーションを実施します。

今回だと、アップロードした画像が本物なのか偽物なのかをラベリングします。そうすることで、この画像は本物、この画像は偽物、という教師データが作成されます。

機械学習は膨大な教師データからコンピュータが学習をする技術です。
今回の場合だと、コンピューターが教師データから本物に共通する特徴と偽物に共通する特徴を見出し、真贋判定をする能力を学習するといった感じでしょうか。

それでは、Annotation画面を起動します。
画面左のメニューから「Annotation」をクリック。
![annotation01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/9644e47b-5cec-7d4a-e3de-85e5fff8e7d1.png)

画面右上の「プロジェクト新規作成」ボタンをクリック。
![annotation02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/36e60050-5b1d-1880-36a7-18e97a4bc497.png)

「Image Classification」をクリックして、画面右下の「次へ」ボタンをクリック。
![Annotaiton01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/14672c43-1583-fa24-de24-1d10f16c6d9a.png)

「選択方式によるアノテーション」をクリック。
![Annotation04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/87e2aab3-9318-9b02-33cb-cb62c5c64749.png)

ラベリングする情報を作成します。
今回は本物と偽物のラベルデータがあればよいので、`Category2`を削除して、`Category1`を下図画面の通りに設定して、画面右下の「次へ」ボタンをクリック。
![authenticity.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/cd3141e9-8209-159b-1d77-f40af78150a2.png)


それぞれの項目に値を入力して、画面右下の「次へ」ボタンをクリック。

- プロジェクト名: 任意のプロジェクト名
- 目標データ数: 1人の担当者が何個のデータをアノテーションすればよいのかの目標
- 1データあたりのアノテーション数: 1データに対して何人以上のワーカー(アノテーション担当者)によるアノテーション作業が必要なのか(例えば`2`に設定すると、1つのデータに対して2人以上のアノテーションが必要)
- 入力データ用 Datalakeチャネル: アノテーションの対象となるデータが蓄積されたチャンネル
![Annotation06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/29380f85-9732-3fea-503a-4335d41929ec.png)

確認画面にて設定に間違いがないかをチェックして、問題が無ければ画面右下の「保存する」ボタンをクリック。
![authenticity01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/c8194c25-c11e-af5d-6af3-f24542732387.png)

元のサマリー画面に戻ったら、サマリー一覧の中に作成したプロジェクトが表示されているので、プロジェクトの右上にある「歯車アイコン」のボタンをクリックして、メニューの中の「作業画面へ」をクリック。
![03_作業画面へ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/109186e5-2b6e-f61d-9add-48b97eb1e592.png)

アノテーション作業画面になります。
表示されている画像に対して、画面右側に表示されているラベルをクリックして、画面下側の「送信」ボタンをクリックすることで、アノテーションされていきます。
ラベルが分からないものは、画面下側の「スキップ」ボタンをクリックすることで、スキップできます。
![05_アノテーション.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/bd3e2141-0f96-5e8f-0e80-23c929934465.png)

アノテーションが全て終わると、教師データをABEJA Platform上に蓄積します。
プロジェクトの右上にある「歯車アイコン」のボタンをクリックして、メニューの中の「データセット書き出し」をクリックする事で、ABEJA PlatformのDatasets上に蓄積されます。
（今回は私一人なので実施しませんでしたが、「レビュー画面へ」ボタンをクリックすると、ワーカーの作業をレビューする事も可能です）
![04_データセット書き出し.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/d9ae4390-64f2-e42b-1f63-9a34a955b5fa.png)

# 学習（モデルの作成）
データの準備が整ったので、学習を実施します。

まずは何の学習なのかを定義する「Training Job Definition」と、実際の学習を行う「Version」を作成します。
今回の場合だと、ROLEX DAYTONAの真贋判定である事を「Job Definition」で設定し、学習に使用する機械学習プログラムとデータセットを「Version」という形で管理する感じです。（学習処理は他の機能で実行）

## Training Job Definitionの作成
画面左のメニューから「Training」-「Job Definition」をクリックし、画面右上の「Create Training Job Definition」ボタンをクリック。
![000a_create-training-job-definition.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/dc039059-82c9-2f20-be70-19f3d395b4cd.png)

「Training Job Definition」に任意の値を入力。
今回は`Authentity_classification`。
![000b_create-training-job-definition.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/b2299617-db75-7dc3-08e0-e6201643cb19.png)


## バージョンの作成
Training Job Definitionの画面に戻り、作成したTraining Job Definitionが一覧に表示されているので、右下の「Create Version」ボタンをクリック。
![06a_バージョンの作成.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/60c2a7a5-d286-d57b-1f5f-792e9567eeb6.png)

それぞれの項目に値を入力して、画面右下の「Create Job definition version」ボタンをクリック。

- Runtime: 任意のRuntime
- Handler: [機械学習プログラムのファイル名]:[学習の関数名]
- Dataset: アノテーションのデータセット書き出しで作成されたDataset
- Dataset Alias: train
- SOURCE CODE: 機械学習プログラムをzipファイルに圧縮したもの

※学習用のコードは[ドキュメント](https://developers.abeja.io/getting-started-guide/training-model/training-and-model/#ディープラーニングの学習コードを確認する)の[サンプルコード](https://s3-us-west-2.amazonaws.com/abeja-platform-config-dev/datasets/archive.zip)に、一部手を加えたものを使用させていただきました。

![06c_バージョンの作成.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/116e575e-f645-a2e4-6505-864278f1b509.png)

## 学習ジョブの実行
Training Job Definitionの画面に戻り、作成したVersionが一覧に表示されているのが確認できます。

作成したVersionの学習を開始します。

Training Job Definition nameの右にある「Jobs」リンクをクリック。
![07a_学習ジョブの実行.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/4885b6d5-8607-c36b-c262-d41d4ffaa884.png)

画面右上の「Create Training Job」をクリック。
![ddddd.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/1914953e-62f2-ebfc-90f3-43a59a2f7f2a.png)


各項目を入力して、「Create Training Job」をクリック。

- Training Job Definition Version: 学習処理を実行するTraining Job DefinitionのVersion
- Instance type: 使用するインスタンスのタイプ

![07c_学習ジョブの実行.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/863beca4-ba7a-656d-b97d-d9985c8f75b4.png)

学習結果が表示されます。一番左に表示されるステータスが「SUCCESS」になったら成功です。
![bbb.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/00e2c087-c527-5a7f-aed6-b7af8e249ac2.png)

# Modelの作成・デプロイ
作成したモデルをABEJA Platform上で動くようにします。
※一般的に機械学習のモデルは機械学習で生成された数式のことを指しますが、ABEJA PlatformのModelは機械学習で生成された数式と推論プログラムを紐付けたものを指していると思われます。この辺少し言葉の迷路に陥りますね...

## Modelの作成（機械学習モデルと推論プログラムの紐付け）
画面左のメニューから「Model」-「Model」をクリックし、画面右上の「Create Model」ボタンをクリック。

![CreateModel00.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/e0580a86-8e7d-c74c-a1a3-06ab59fb0c4b.png)


各項目を入力して、「Create Training Job」をクリック。

- Name: 任意の名前
- Description: 任意の説明
- Version: 任意のバージョン
- Deployment after creating: チェック
- Deployment name: 任意のデプロイ名
- Runtime: 任意のランタイム
- Model Handler: [機械学習プログラムのファイル名]:[推論の関数名]
- Job Definition: 推論プログラム(本項目でいうModel Handler)と紐付けるTraining Job Definitionの名前
- Training Job: Training Job Definitionのバージョン
- Source Code: 機械学習プログラムをzipファイルに圧縮したもの

※推論用のコードは[ドキュメント](https://developers.abeja.io/getting-started-guide/training-model/training-and-model/#ディープラーニングの学習コードを確認する)の[サンプルコード](https://s3-us-west-2.amazonaws.com/abeja-platform-config-dev/datasets/archive.zip)に、一部手を加えたものを使用させていただきました。

![CreateModel.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/1b94f19d-24d5-c764-f338-aa66715b4a74.png)

## HTTP Serviceの作成・モデルの動作確認
Deploymentの画面からHTTP Service(インスタンス&エンドポイント)を作成して、モデルの動作確認を行います。

画面左のメニューから「Model」-「Deployment」をクリックすると、一覧の中に先ほど作成したDeploymentが存在しますので、Deployment nameのリンクをクリック。
※先ほどのCreate Training Jobの際にデプロイを同時にするようにしていなかった場合（Deployment after creating: チェック無し）は「Create Deployment」ボタンからDeploymentを作成する必要あり
![endpoint.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/7f98aa9a-57b3-5fcf-c4b3-10e46fa64e1b.png)

画面右上の「Create HTTP Service」をクリック。
![endpoint02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/cb59d1e7-1411-419e-65e5-d478f3abf3b0.png)

各項目を入力して、「Create HTTP Service」をクリック。

- Version: これから作成するエンドポイントと紐付けるModelのバージョン
- Instance type: 任意のインスタンスタイプ
- Instance numbers: 任意のインスタンス数(1 - 32)
![endpoint03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/925b509e-df68-91cd-7a6c-d606b3dab66d.png)

エンドポイントが作成されて一覧画面に表示されるので、「Status」が「Ready」になったら、「Check」ボタンをクリック。
![endpoint04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/100e0f3a-a47e-4efe-6958-8e35f259ca8c.png)


Test HTTP Service画面になったら、Upload Fileタブをクリックして、グレー領域にアップロードするファイルをDrag and Drop。
もしくは、画面中央のグレー領域の中央にある「select files」ボタンをクリックして、ダイアログ画面からアップロードするファイルを開く。
ファイルのアップロード後に「Send」ボタンをクリック。
![endpoint05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/b5ee5803-0dc7-4f8c-80f5-d1f62cebd33f.png)

Response項目に真贋判定の結果が返ってきました。完成です！
![endpoint06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/61b46ab1-54d3-ce37-a0d3-e97eba2de380.png)

### エンドポイントの追加（余談）
余談ですが、エンドポイントはHTTP Service作成時に付与されるものだけではないようです。

HTTP Serviceの画面にある「Add Endpoint」ボタンから、開発用やプロダクション用等のエンドポイントを別途作成し、自由にデプロイ済みのモデルに紐付けられるようです。

この機能を使うと、アプリ側のプログラムはそのままで、モデルのバージョンアップ等が出来そうですね。

![endpoint04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/100e0f3a-a47e-4efe-6958-8e35f259ca8c.png)

![endpoint07.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/5f4dc26d-0a3d-5c5f-a613-0be441d4bcd2.png)

![endpoint08.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/6645fb27-69aa-9826-5e72-000add0ac7b6.png)

# 最後に
## ABEJA Platformについて
ABEJA Platformを使ってみましたが、特にABEJA Platform Annotationが非常に良くできていると感じました。

アノテーション機能は勿論、レビューや管理や進捗など、実際のプロジェクトで必要となる機能が一通り揃っており、実際のプロジェクトで培われた感じが好印象です。

また、ABEJA Platform全体を通して見ても操作が簡単で、ドキュメントを読めばモデル作成まで簡単なところも良いと思いました。データやプログラム管理、エンドポイント等が1つのサービスとしてパッケージングされていると、使い始めるまでのハードルが低くて助かります。

しかし、良いところだけがあるわけではなく、少し気になることころもありました。
全体的に細かいところが詰められていない感じがしました。エラーメッセージやバリデーションチェック等ですね。
ドキュメントも少し弱い感じです。ドキュメントにない運用をやろうとすると結構悩みました。
ただ、この辺は指摘させて頂いたので、今後は良くなっていくかと思います。

あと細かいことを言うと、用語が直感的でなかったり、既存の用語と被っているものがあるので、最初は慣れが必要だと思いました。チャンネルやモデル等ですね。

今後については、[ABEJA Platform Accelerator](https://abejainc.com/ja/news/article/20190305-2429)のリリースに期待しています。リンク先の記事を見る感じでは仮説検証用みたいですが、ノンプログラミングで機械学習が出来るのは大きいと思います。これがリリースされれば、AI構築のハードルが大きく下がると思います。

## AI作成について
真贋判定ですが、実は偽物データについては「スーパーコピー」と呼ばれる**見た目が本物と殆ど一緒の精度の高い偽物画像データ**だけを用意したせいか、大した結果は得られませんでした。これは全てをAIで解決したいと思ってハードルが高いことをやらせようとした私のミスだと思います。

真贋判定のAIを作るのであれば、精度の低い偽物をAIが判定してふるいにかけ、残った精度が高い偽物を人間が判定するといった設計にするべきだったかもしれません。巷でよく聞く「AIだけで何もかも解決しようとするのではなく、人間との二人三脚も前提に考えるべき」というやつですね。
(正直、スーパーコピーの判定は最初から無理かもしれないとは思っていましたが、AIの力を試したい誘惑に負けました。その割にはデータ数も少なすぎなんですが...)

次回はもうちょっと上手くやりたいと思います。