Azure Custom Vision Serviceで「きのこの山」と「たけのこの里」を判別させてみた

このエントリは [Cogbot！ – Cognitive Services, Bot Framework, Azure ML, Cognitive Toolkit(CNTK) Advent Calendar 2017](https://qiita.com/advent-calendar/2017/cogbot) の２日目です。

ナレッジコミュニケーションの大柳です。

今回はMicrosoft Azureの画像認識サービスCustom Vision Serviceを使った画像判定のデモをやってみます。「きのこの山」と「たけのこの里」が判別できるか、試してみます。

# Custom Vision Serviceとは

Microsoft Azureで提供される画像認識サービスです。自分の持っている画像を学習させることで、その画像が何かを当てるための仕組み、いわゆる機械学習モデルを作ることができます。
https://azure.microsoft.com/ja-jp/services/cognitive-services/custom-vision-service/

例えば、Microsoftの公式ブログではヒアリかどうかを見分ける機械学習モデルを作った検証例が公開されています。
https://blogs.technet.microsoft.com/jpai/2017/09/14/protection-from-fire-ant-using-ai/
![1202CV_01.jpg](https://qiita-image-store.s3.amazonaws.com/0/69163/b5d9e98a-b38e-c7fc-c6d6-dc2141a41c02.jpeg)

Azureの画像認識系のサービスには他にも、Computer Vision APIやFace APIもありますが、Microsoftが構築した機械学習モデルを使う形になります。一方、Custom Vision Serviceでは、Azureの力を借りてカスタマイズした学習モデルを作ることができます。
なお、2017年12月時点ではPreviewになっています。

# 今回やること
Custom Visionで画像認識させる題材を何にするか考えていたところ、コンビニで目に留まった「きのこの山」と「たけのこの里」を見分けられるのではないかとひらめいたので、検証してみます。

「きのこの山」と「たけのこの里」の画像を学習させて、見分けられるようになるでしょうか。
データの準備から、学習モデル作成、予測、APIの利用まで説明していきます。

# データの準備
機械学習モデルを作成するには、学習するための元データが必要です。機械学習界隈では訓練データ(training data)と呼ばれるものです。
今回の場合は、「きのこの山」と「たけのこの里」の画像が必要です。ネットの画像検索から集めてくるやり方もありますが、今回は自前で準備します。

コンビニで「きのこの山」と「たけのこの里」を買ってきました。
# ![1202CV_02.jpg](https://qiita-image-store.s3.amazonaws.com/0/69163/af552d9f-26df-3470-c416-a4d0e8e5cf8e.jpeg)

パッケージを開けて、きのことたけのこを並べていきます。きのこの山、たけのこの里とも１箱にはちょうど３０個入ってました。偶然なのかきっちり３０個入ってるのかは別途検証したいです。
ちなみに「きのこの山」は残念ながら１本は折れていたため、今回検証用に使ったのは２９本になります。

きのこの山
![1202CV_03.jpg](https://qiita-image-store.s3.amazonaws.com/0/69163/716d7bae-8a51-b577-0d9c-d8e6b40410e4.jpeg)

たけのこの里
![1202CV_04.jpg](https://qiita-image-store.s3.amazonaws.com/0/69163/bfdf4e44-8a8c-4afd-3579-71d9c2eacf81.jpeg)

写真を撮ったらＰＣ上で、「きのこの山」と「たけのこの里」を１個１個切り出して保存していきます。
機械学習のためのデータ準備はこんな感じで地味な反復作業が多いです。OpenCVあたりを使えば自動切り出しもできるかもしれませんが、今回は数も多くないので手作業で地道にやっていきます。

![1202CV_05.jpg](https://qiita-image-store.s3.amazonaws.com/0/69163/2d397818-9762-5cae-7811-804fbb75df84.jpeg)

画像のサイズや認識対象の位置は、きっとCustom Visionさんがよしなにやってくれると思うので、特にこだわらず調整はせず切り出していきます。

こんな感じで２９個のきのこ、３０個のたけのこの画像を切り出しました。

![1202CV_06.jpg](https://qiita-image-store.s3.amazonaws.com/0/69163/7ff0ea32-bf92-9235-4827-c7ca96102f62.jpeg)

# 学習モデルの作成

学習データが準備できたのでCustom Visionで学習モデルを作っていきます。

前提としてAzureのライセンスが必要です。持ってない方は作りましょう。クレジットカードの登録が必要ですが、初回登録時は30日間、20,500円の無料枠がついています。(2017年12月時点)

まず、Custom Visionのポータルにアクセスします。
https://customvision.ai/

サインインして、新しいプロジェクトを作成します。

![1202CV_07.png](https://qiita-image-store.s3.amazonaws.com/0/69163/cf7bb8a5-034c-71cb-629d-561a3a9cf451.png)

プロジェクト名を付けます。
![1202CV_08.png](https://qiita-image-store.s3.amazonaws.com/0/69163/9ea6dc05-8ad3-09da-644f-fa02797801ce.png)

「Domains」の選択肢にはfood、landmark、retailなどがあります。これらを選ぶと、モノの種類に応じた最適なモデルを作ってくれるようです。今回はどれにあてはまるか分からないのでgeneral(一般)を選びました。

できたプロジェクトを開くと、画像がアップロードできます。
![1202CV_09.png](https://qiita-image-store.s3.amazonaws.com/0/69163/20710eda-d091-270d-ad95-e28a8905eab4.png)


訓練データのアップロードは複数ファイルをまとめてアップロードも可能です。今回はそれぞれ１０枚ずつアップします。アップした画像にはタグをつけます。それぞれkinoko、takenokoというタグをつけます。
![1202CV_10.png](https://qiita-image-store.s3.amazonaws.com/0/69163/5f902322-5229-9d10-3624-a0be049712c1.png)

画像のアップロードとタグ付けが終わったので、いよいよ学習させます。[Train]ボタンを選択すると、１０秒くらいで処理は終わりました。速いです。今回は画像サイズも小さく、画像数も各々１０枚と少なかったためかと思いますが、それでもかなり速いです。
学習が終わると、モデルの作成結果が表示されます。
![1202CV_11.png](https://qiita-image-store.s3.amazonaws.com/0/69163/c2941099-48a8-27b3-92c7-45521de98d15.png)

Precisionは96％、Recallは100％とかなりよい精度が出ています。

このPrecision、Recallはそれぞれ適合率、再現率という機械学習モデルの成績を表す指標です。
適合率(Precision)は、例えば、「きのこ」と判断したもので、実際「きのこ」だったものの割合です。
再現率(Recall)は、実際に「きのこ」のもののうち、正しく「きのこ」と判断されたものの割合です。
分かりにくいですが、図にすると以下のようなイメージです。
![1202CV_12.png](https://qiita-image-store.s3.amazonaws.com/0/69163/56e7e460-6d04-ddb0-6e34-3179ddb98979.png)

さらに詳しく知りたいという方は、以下のサイトに詳しく解説されています。
[そろそろ本気で機械学習の評価方法について学習するよ – Web就活日記](http://yut.hatenablog.com/entry/20120910/1347233734)


# 予測
学習モデルが作れたので、予測、つまり「きのこ」か「たけのこ」か当ててみます。

右上にある[QuickTest]をクリックします。

![1202CV_13.png](https://qiita-image-store.s3.amazonaws.com/0/69163/df302171-9593-231c-0d58-84358d8e1dc1.png)

ますは「きのこの山」画像を選んでアップロードします。
結果は100%の確率でkinoko、「きのこの山」と出ており正解です。

![1202CV_14.png](https://qiita-image-store.s3.amazonaws.com/0/69163/d42b80a0-8820-9205-b108-de46453d856b.png)

次に「たけのこの里」画像も試してみましたが、正解しています。

![1202CV_15.png](https://qiita-image-store.s3.amazonaws.com/0/69163/26a554f4-c38a-da69-4d33-fe6db3144763.png)

他のお菓子も試してみました。
![1202CV_16.png](https://qiita-image-store.s3.amazonaws.com/0/69163/f75429d8-6230-8bf9-b338-e844b3c75fbc.png)

アルフォートとコアラのマーチは、「きのこ」でも「たけのこ」でもないと正しく判断しています。
一方、コロンは「たけのこ」と判定されました。形や色が似ているため、間違ったんだと思いますが、そういうことを除けば正しく判定できてます。すごーい！

ここまでコマンド操作なし、Webブラウザだけで、１時間もかからず精度の高い「きのこの山」「たけのこの里」判定モデルを作成できました。Custom Vision、とても手軽です。

# APIによる予測

Custom VisonではAPIも標準で提供されます。APIを使った予測もやってみます。
APIに画像を渡すには、インターネット上のURLを指定する方法とPOSTでデータとして渡す２通りの方法があります。

APIのURLは[PERORMANCE]タブ→[Prediction URL]から確認できます。
![1202CV_17.png](https://qiita-image-store.s3.amazonaws.com/0/69163/bf13e1ea-43dd-9058-3671-42372e2ef54f.png)

今回はインターネット上のURLを指定して画像を渡します。curlで以下のURLにPOSTします。

```shell
curl -sX POST "https://southcentralus.api.cognitive.microsoft.com/customvision/v1.0/{PrijectID}/url?iterationId={IterationID}" \
-H "Content-Type: application/json" \
-H "Prediction-key: {Prediction-key}" \
-d '{"Url": "画像のURL"}'
```

結果はJSONで返ってきます。

```json
{
    "Created": "2017-11-30T07:22:29.2698916Z",
    "Id": "88951980-eb5f-4519-a45e-ca371c5d105a",
    "Iteration": "962f6ef2-b049-437d-b39e-6c115d918b30",
    "Predictions": [
        {
            "Probability": 0.9999999,
            "Tag": "kinoko",
            "TagId": "28bdc70f-26f2-47cf-91a1-730905b3366a"
        },
        {
            "Probability": 1.73013581e-09,
            "Tag": "takenoko",
            "TagId": "a662bff1-06f8-4ac5-be49-22861237e8cc"
        }
    ],
    "Project": "250d2d53-2d1a-4ca5-9b35-95c215206e84"
}
```

今回は「きのこ」の画像を投げました。kinokoである確率が99.9％と正しく予測できています。

APIの詳しい仕様やプログラミング言語ごとのサンプルコードは以下にあります。
[Custom Vision Prediction PredictImageUrl](https://southcentralus.dev.cognitive.microsoft.com/docs/services/eb68250e4e954d9bae0c2650db79c653/operations/58acd3c1ef062f0344a42813)
[Custom Vision Prediction PredictImage](https://southcentralus.dev.cognitive.microsoft.com/docs/services/eb68250e4e954d9bae0c2650db79c653/operations/58acd3c1ef062f0344a42814)

# まとめ

従来は機械学習を使った画像判定モデルを作る場合は、学習データの収集、画像の調整(サイズ合わせ、トリミング、二値化など）、学習ネットワークの構築、データ学習、パラメータの調整、再評価・・・、と手数も時間もかかりました。しかしCustom Visionの登場により、画像さえあれば、誰でも、すぐに機械学習モデルを作って、活用することができます。API連携してアプリケーションと組み合わせることもすぐにできます。

今回は、それぞれ１０枚という少ない画像から精度の高いモデルが作れたように見えます。しかし、実運用で使うにあたっては、画像の明るさ、見る向きなどにより期待した精度が出ない可能性もあり、訓練データを増やしたり、予測した場合の正解率を評価して、チューニングが必要かもしれません。

今回、使用した訓練データは以下のURLからダウンロードできるようにしています。この画像をもとに、Azureアカウントさえあれば、簡単に、すぐにCustom Vision Serviceを試すことができますので、ぜひともチャレンジしてみてください。

きのこ・たけのこ画像データ
http://doc.kc-cloud.jp/kinoko_takenoko.zip

※この記事はナレッジコミュニケーションの技術ブログナレコムAzureレシピでもご紹介しています。
https://azure-recipe.kc-cloud.jp/2017/12/custom_vision_2017adcal/