みらいテックラボ

音声・画像認識や機械学習など, 週末プログラマである管理人が興味のある技術の紹介や実際にトライしてみた様子などメモしていく.

Cloud AutoML Vision Object Detectionを試してみる

CODE for YAMATOKORIYAMAの取組みの一環として, 「Kingyo AI Navi」[1]なる金魚の種類識別を活用したアプリのプロト開発を行っている.
現在は, Cloud AutoML Visionを使って種類識別を行っているのだが, 水槽の中の泳いでいる金魚1匹に注目して, その1匹だけが写った写真を撮るのは結構難しい.
そこで, 今回複数の金魚が写った写真でもいけるようにするために, Cloud AutoML Vision Object Detectionを少し試してみることにした.


1. データ準備
お試しということで, 種類分類で使用している金魚画像約950枚をアノテーションして利用することにした.
アノテーションには, 今回もMS社のVoTT(Visual Object Tagging Tool)[2]を使用した.

f:id:moonlight-aska:20191006220626p:plain

VoTTでアノテーションした結果をVOC形式で出力し, その後AutoML VisionのTraining Data CSV形式に変換した.

[AutoML Visionのフォーマット]

[set], path, label, xmin, xmin, , , xmax, ymax, ,
注) 座標は, 画像のwidth, heightを1とした相対値.

f:id:moonlight-aska:20191006223900p:plain


2. モデル学習
"How-to Guides"[3]に手順が書かれているが, 以下に簡単に手順を書いておく.

2.1 プロジェクトの設定
”How-to Guides”の”Before you begin”に従って, プロジェクトの設定を行う.

2.2 データセットのアップロード
パケットを作成し, 画像データ及びcsvファイルをコピーする.

$ export PROJECT_ID='myproject-xxx'
$ export REGION_NAME='us-central1'
$ gsutil mb -p $PROJECT_ID -c regional -l $REGION_NAME gs://myproject-xxx-vcm/
Creating gs://myproject-xxx-vcm/...
$ gsutil -m cp -R labeled/img gs://myproject-xxx-vcm/
Copying file://labeled/img/GF17-00029.jpg [Content-Type=image/jpeg]...
Copying file://labeled/img/GF08-00023.jpg [Content-Type=image/jpeg]...
   :
Copying file://labeled/img/GF17-00043.jpg [Content-Type=image/jpeg]...
Copying file://labeled/img/GF05-00030.jpg [Content-Type=image/jpeg]...
| [952/952 files][  9.1 MiB/  9.1 MiB] 100% Done 234.1 KiB/s ETA 00:00:00       
Operation completed over 952 objects/9.1 MiB.
$ gsutil cp goldfish_detect.csv gs://myproject-xxx-vcm/csv/
Copying file://goldfish_detect.csv [Content-Type=text/csv]...
/ [1 files][126.4 KiB/126.4 KiB]                                                
Operation completed over 1 objects/126.4 KiB.

2.3 csvインポート
Cloud AutoML VisionのWeb UIで, "新しいデータセット"を選択し, csvインポートで金魚画像セットを読み込んでくる.

f:id:moonlight-aska:20191006230624p:plain

インポートする際に, ラベル情報などに不具合があると, エラーしたデータの詳細も示してくれる.
f:id:moonlight-aska:20191006232104p:plain:w500

2.4 学習
時間単位ごとに9ノード(ノード時間あたり $3.15)を並行して使用して学習を行うらしく, 1時間に$28.35かかるようだ.
今回は画像が1000サンプル未満だったのでとりあえず無料枠(40ノード時間)内の20ノード時間で学習を行ってみた.

f:id:moonlight-aska:20191006233222p:plain


3. 動作確認
pythonからObject Detection APIを呼び出して, 金魚の検出をやってみる.
以前のAutoML Visionをテストしたときのコードをベースに, 結果出力部分を変更した.

[コード]

import argparse
import cv2
import numpy as np
from google.cloud import automl_v1beta1 as automl

# AutoML情報
project_id = 'myproject-xxx'
compute_region = 'us-central1'
model_id = 'IOD91745XXXXXXX'

def main(args):
    # AutoMLセットアップ
    automl_client = automl.AutoMlClient()
    prediction_client = automl.PredictionServiceClient()
    model_full_id = automl_client.model_path(project_id,
                                             compute_region,
                                             model_id)
    params = {}
    if args.threshold:
        params = {"score_threshold" : args.threshold }

    with open(args.input, 'rb') as image_file:
        content = image_file.read()
    payload = {"image": {"image_bytes": content}}

    # 予測
    response = prediction_client.predict(model_full_id, payload, params)
    # print(response)
    if args.view:
        img = cv2.imread(args.input)
        height, width, channel = img.shape[:3]
        
    print('prediction results:')
    for result in  response.payload:
        print('Predicted name: {}'.format(result.display_name))
        print('Predicted object score: {}'.format(result.image_object_detection.score))
        pos = result.image_object_detection.bounding_box.normalized_vertices
        print('Predicted bounding box: {},{} - {}, {}'.format(pos[0].x, pos[0].y, pos[1].x, pos[1].y))
        # 結果表示
        if args.view and img is not None:
            x0 = int(pos[0].x * width)
            y0 = int(pos[0].y * height)
            x1 = int(pos[1].x * width)
            y1 = int(pos[1].y * height)
            res = '{} : {:.3f}'.format(result.display_name, result.image_object_detection.score)
            cv2.putText(img, res, (x0+20, y0+20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0))
            cv2.rectangle(img, (x0, y0), (x1, y1), (255, 0, 0), lineType=cv2.LINE_AA)
    cv2.imshow('Image', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    help_ = 'Input file'
    parser.add_argument('-i', '--input', help=help_)
    help_ = 'Score threshold (0.0 - 0.5)'
    parser.add_argument('-t', '--threshold', help=help_)
    help_ = 'View window'
    parser.add_argument('-v', '--view', help=help_, action='store_true')
    args = parser.parse_args()
    main(args)

[動作結果]
(1) ランチュウ琉金
中央のランチュウは検出できたが, 右上後ろの琉金は検出できず.

f:id:moonlight-aska:20191006233707p:plain

(2) 水泡眼と頂点眼
上の頂点眼は検出できたが, 中央の水泡眼は頂点眼と誤って検出した.

f:id:moonlight-aska:20191006233633p:plain

学習データが少ないので精度はまだまだであるが, 一応Cloud AutoML Vision Object Detectionの学習/予測を試してみることができた.

Cloud AutoML Vision Object Detectionで予測を行うにはモデルのデプロイが必要で, 今回は1ノード(ノード時間あたり $1.82)でデプロイした.
もし, 学習データを増やし検出精度が上がったとして, 「Kingyo AI Navi」で使用することを考えると,
 1.82 × 24 × 30 = 1,310.4
と, 約15万円/月の費用が発生する.

個人のお試しサービスでは, 高過ぎて使えないなー.

----
参照URL:
[1] 「Kingyo AI Navi」のアプリ化を考える (1)~(4)
[2] GitHub - microsoft/VoTT: Visual Object Tagging Tool: An electron app for building end to end Object Detection Models from Images and Videos.
[3] How-to Guides | Cloud AutoML Vision Object Detection | Google Cloud




GCPの教科書

GCPの教科書


Google Cloud Platformではじめる機械学習と深層学習

Google Cloud Platformではじめる機械学習と深層学習