概要
車両、ナンバープレートの物体検出の検証を行うため、学習用のデータセットを取得しImage Analysis 4.0に読み込ませモデル学習を行いました
前提条件
以下のリソースが作成済みであることとします
-
Cognitive services マルチサービス アカウント
Japan {East, West}等カスタムモデルの学習が出来ないリージョンがあるので注意してください
ここではUs Eastを使用しました -
ストレージ アカウント
上記Cognitive servicesからのREAD権限を付与してください(SAS, Managed Id, パブリックアクセス)
ここではパブリックアクセスを使用しました
学習モデルを取得する
学習用のデータセットを自前で一から作成するのは大変なので、無料で公開されているデータセットを使用します
-
COCO - Common Objects in Context (https://cocodataset.org/)
学習用の画像、アノテーションの数共に膨大(18Gb)で今回の検証には大きすぎるため見送りました -
roboflow (https://universe.roboflow.com/)
検索画面で「car plate」等のキーワードで検索すると手頃(11Mb程度)なデータセットがあったのでこれを使用します
License Plates Dataset (https://public.roboflow.com/object-detection/license-plates-us-eu)
各データセットには異なるラインセンスが採用されていますので使用する際には注意してください
学習モデルの構成
ダウンロードしたファイルを展開すると以下のような構成になっています
$ mkdir dataset
$ (mkdir dataset && cd dataset && unzip ../License\ Plates.v3-original-license-plates.coco.zip)
$ tree dataset
dataset
├── README.dataset.txt
├── README.roboflow.txt
├── test
│ ├── _annotations.coco.json # テスト用のデータセットのCOCOファイル
│ └── <テスト用の画像データが沢山>
├── train
│ ├── _annotations.coco.json # 学習用のデータセットのCOCOファイル
│ └── <学習用の画像データが沢山>
└── valid
├── _annotations.coco.json # 検証用のデータセットのCOCOファイル
└── <検証用の画像データが沢山>
3 directories, 356 files
$
COCOファイルの修正
ダウンロードしたCOCOファイルをそのまま使用すると学習の際に異常終了してしまうので修正を行います
問題点は3つ
- カテゴリーIDが0始まりである(1始まりでないとエラー)
- supercategoryは不要
- imagesにcoco_url(absolute_url)要素がない
手作業で修正するのは大変なので簡単な変換スクリプトを作成します
import json, sys
with open(sys.argv[1]) as fp:
root = json.load(fp)
del root["categories"][0]
for category in root["categories"]:
del category["supercategory"]
for image in root["images"]:
file_name = image["file_name"]
image["id"] += 1
image["absolute_url"] = f"https://<ストレージアカウント名>.blob.core.windows.net/<コンテナ名>/custom-model/dataset/train/{file_name}"
for annotation in root["annotations"]:
annotation["id"] += 1
annotation["image_id"] += 1
print(json.dumps(dict(root), indent=4))
作成したプログラムで修正を行います
$ py fix.py dataset/train/_annotations.coco.json > dataset/custom.coco.json
$
COCOファイルのBlob Storageへのアップロード
ストレージ上にコンテナを作成し学習モデルをアップロードします
$ az storage container create \ # Containerの作成
-n <コンテナ名> \
--public-access blob \ # パブリックアクセスをBlobに設定
--account-name <ストレージアカウント名>
$ az storage blob directory upload \ # 学習モデルのアップロード
-c <コンテナ名> \
--account-name <ストレージアカウント名> \
-s dataset \
-d custom-model \
--recursive
$
Computer Visionにトレーニングセットを作成する
ここからソースコードを取得して実行します
# Resource and key
import logging
logging.getLogger().setLevel(logging.INFO)
from cognitive_service_vision_model_customization_python_samples import ResourceType
resource_type = ResourceType.MULTI_SERVICE_RESOURCE
resource_name = None
multi_service_endpoint = None
if resource_type == ResourceType.SINGLE_SERVICE_RESOURCE:
resource_name = '{specify_your_resource_name}'
assert resource_name
else:
multi_service_endpoint = 'https://<コグニティブサービス名>.cognitiveservices.azure.com/'
assert multi_service_endpoint
resource_key = '<コグニティブサービスのキー>'
from cognitive_service_vision_model_customization_python_samples import DatasetClient, Dataset, AnnotationKind, AuthenticationKind, Authentication
dataset_name = '<作成するデータセット名>'
auth_kind = AuthenticationKind.MI
dataset_client = DatasetClient(resource_type, resource_name, multi_service_endpoint, resource_key)
annotation_file_uris = ['https://<ストレージアカウント名>.blob.core.windows.net/<コンテナ名>/custom-model/dataset/custom.coco.json']
# register dataset
if auth_kind == AuthenticationKind.SAS:
# option 1: sas
sas_auth = Authentication(AuthenticationKind.SAS, '{your_sas_token}') # note the token/query string is needed, not the full url
dataset = Dataset(name=dataset_name,
annotation_kind=AnnotationKind.MULTICLASS_CLASSIFICATION, # checkout AnnotationKind for all annotation kinds
annotation_file_uris=annotation_file_uris,
authentication=sas_auth)
else:
# option 2: managed identity or public accessible. make sure your storage is accessible via the managed identiy, if it is not public accessible
dataset = Dataset(name=dataset_name,
annotation_kind=AnnotationKind.OBJECT_DETECTION, # checkout AnnotationKind for all annotation kinds
annotation_file_uris=annotation_file_uris)
reg_dataset = dataset_client.register_dataset(dataset)
logging.info(f'Register dataset: {reg_dataset.__dict__}')
# specify your evaluation dataset here, you can follow the same registeration process as the training dataset
eval_dataset = None
if eval_dataset:
reg_eval_dataset = dataset_client.register_dataset(eval_dataset)
logging.info(f'Register eval dataset: {reg_eval_dataset.__dict__}')
$ py -m venv venv
$ source venv/Scripts/activate
(venv)
$ pip install cognitive-service-vision-model-customization-python-samples
(venv)
$ py regist.py
(venv)
$
実際に学習を行う
ここからソースコードを取得し実行します
import logging
logging.getLogger().setLevel(logging.INFO)
from cognitive_service_vision_model_customization_python_samples import ResourceType
resource_type = ResourceType.SINGLE_SERVICE_RESOURCE # or ResourceType.MULTI_SERVICE_RESOURCE
resource_type = ResourceType.MULTI_SERVICE_RESOURCE
resource_name = None
multi_service_endpoint = None
if resource_type == ResourceType.SINGLE_SERVICE_RESOURCE:
resource_name = '{specify_your_resource_name}'
assert resource_name
else:
multi_service_endpoint = 'https://<コグニティブサービス名>.cognitiveservices.azure.com/'
assert multi_service_endpoint
resource_key = '<コグニティブサービスのキー>'
from cognitive_service_vision_model_customization_python_samples import TrainingClient, Model, ModelKind, TrainingParameters, EvaluationParameters
model_name = '<作成するモデル名>'
dataset_name = '<作成したデータセット名>'
eval_dataset = None
training_client = TrainingClient(resource_type, resource_name, multi_service_endpoint, resource_key)
train_params = TrainingParameters(training_dataset_name=dataset_name, time_budget_in_hours=1, model_kind=ModelKind.GENERIC_OD) # checkout ModelKind for all valid model kinds
eval_params = EvaluationParameters(test_dataset_name=eval_dataset.name) if eval_dataset else None
model = Model(model_name, train_params, eval_params)
model = training_client.train_model(model)
logging.info(f'Start training: {model.__dict__}')
training_client = TrainingClient(resource_type, resource_name, multi_service_endpoint, resource_key)
model = training_client.wait_for_training_completion(model_name, 30)
学習プログラムを実行します
このプログラムは学習が終了するまで30秒に一度進捗ステータスを確認しています
学習時間(time_budget_in_hours)にもよりますがかなり時間がかかります
$ py train.py
$
エラーが出力しなければ学習が終了です(∩´∀`)∩
モデルの学習が「Failed (NotEnoughBudget)」で終了した場合
トレーニングが失敗する理由とは?また、何を行う必要がありますか?
https://learn.microsoft.com/ja-jp/azure/cognitive-services/computer-vision/concept-model-customization#why-does-my-training-fail-and-what-i-should-do
notEnoughBudget: 指定した予算は、トレーニングしているデータセットとモデルの種類のサイズには不十分です。 より大きな予算を指定します。
とあるのですがここで言う予算はお金では無く時間なので、「time_budget_in_hours」に大きな値を指定してください