LoginSignup
1
0

More than 1 year has passed since last update.

Azure Custom VisionでトレーニングしたモデルをAPIで使いたい

Posted at

やりたいこと

Azureでトレーニングしたモデルを手元のPC上で扱いたい。

実行コード

!pip install azure-cognitiveservices-vision-customvision
import glob
from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient
from azure.cognitiveservices.vision.customvision.training.models import ImageFileCreateBatch, ImageFileCreateEntry, Region
from msrest.authentication import ApiKeyCredentials
import os, time, uuid

ENDPOINT = "https://****************.cognitiveservices.azure.com/"
prediction_key = '***************************'
prediction_resource_id = "/subscriptions/*****************************************/resourceGroups/Fish/providers/Microsoft.CognitiveServices/accounts/****************"
projectID = '*******************************'
publish_iteration_name = 'Iteration1'

def testModel(testfiles, fishname):
    data_count = len(testfiles)
    true_count = 0

    # 予測用インスタンスの作成 …①
    prediction_credentials = ApiKeyCredentials(in_headers={"Prediction-key": prediction_key})
    predictor = CustomVisionPredictionClient(ENDPOINT, prediction_credentials)
    for testfile in testfiles:
        predicts = {}
        with open(testfile, mode='rb') as f:
            # 予測実行 …②
            results = predictor.classify_image(projectID, publish_iteration_name, f.read())

        # 予測結果のタグの数だけループ …③
        for prediction in results.predictions:
            # 予測した魚とその確率を紐づけて格納 …④
            predicts[prediction.tag_name] = prediction.probability

        # 一番確率の高い魚を予測結果として選択 …⑤
        prediction_result = max(predicts, key=predicts.get)

        # 予測結果が合っていれば正解数を増やす
        if fishname == prediction_result:
            true_count += 1

    # 正解率の算出
    accuracy = (true_count / data_count) * 100
    print('正解率:' + str(accuracy) + '%')

#検証用画像を保存したルートディレクトリパス
root_dir = 'fish_images/'
#検証対象の魚一覧
fishnames = ['アイゴ', 'オニカサゴ']

for fishname in fishnames:
    print('*****' + fishname + '*****')
    #testデータのリストを取得
    testfiles = glob.glob(root_dir + fishname + '/test/*')
    testModel(testfiles, fishname)
エラーメッセージ
CustomVisionErrorException: Operation returned an invalid status code 'Unauthorized'

エラーメッセージの内容は'CustomVisionErrorException:操作が無効なステータスコード「Unauthorized」を返しました'となっている。該当コードをみてみると

該当コード
---------------------------------------------------------------------------
CustomVisionErrorException                Traceback (most recent call last)
<ipython-input-8-4906765a0299> in <module>
      8     #testデータのリストを取得
      9     testfiles = glob.glob(root_dir + fishname + '/test/*')
---> 10     testModel(testfiles, fishname)

<ipython-input-7-145134263771> in testModel(testfiles, fishname)
     10         with open(testfile, mode='rb') as f:
     11             # 予測実行 …②
---> 12             results = predictor.classify_image(projectID, publish_iteration_name, f.read())

12行目のprojectID, publish_iteration_nameに問題があると考えられる。このエラーメッセージを検索してみると、こちらの記事がヒットした。

API typeでALL Cognitive Servicesとすると良いとのこと。私はCustom Vision Trainingとしているためこうなっているのではとのこと。

Screen Shot 2021-10-30 at 13.00.15.png

対処

ただ、API typeを変える以外に方法はあるはずなので確認してみるとこちらに参考になるページがあった。サイトのとおりに一度やってみる。以下のようなコードに変更した。

import requests
import json

url = 'https://*********************.cognitiveservices.azure.com/customvision/v3.0/Prediction/********************************/classify/iterations/Iteration1/image'
headers={'content-type':'application/octet-stream','Prediction-Key':'**********************'}

def testModel(testfiles, fishname):
    data_count = len(testfiles)
    true_count = 0

    for testfile in testfiles:
        predicts = {}
        #予測実行
        response =requests.post(url,data=open(testfile,"rb"), headers=headers)
        response.raise_for_status()
        analysis = response.json()

        # 予測結果のタグの数だけループ …③
        for prediction in range(len(analysis["predictions"])):
            # 予測した魚とその確率を紐づけて格納 …④
            predicts[analysis["predictions"][prediction]["tagName"]] = analysis["predictions"][prediction]["probability"]

        # 一番確率の高い魚を予測結果として選択 …⑤
        prediction_result = max(predicts, key=predicts.get)

        # 予測結果が合っていれば正解数を増やす
        if fishname == prediction_result:
            true_count += 1

    # 正解率の算出
    accuracy = (true_count / data_count) * 100
    print('正解率:' + str(accuracy) + '%')

#検証用画像を保存したルートディレクトリパス
root_dir = 'fish_images/'
#検証対象の魚一覧
fishnames = ['アイゴ', 'オニカサゴ']

for fishname in fishnames:
    print('*****' + fishname + '*****')
    #testデータのリストを取得
    testfiles = glob.glob(root_dir + fishname + '/test/*')
    testModel(testfiles, fishname)

すると以下のように結果がエラー無く返ってきたため成功したことがわかる。

result
*****アイゴ*****
正解率:81.25%
*****オニカサゴ*****
正解率:92.85714285714286%

課題

実行することはできてひとまず良かったが、大きく2つ課題が生じた。

  • 動かなかったコードについて原因がわかっていない。Unautherized
  • 毎回WebAPIを叩いているため予測をするのに時間がかかること
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0