Detectron2 0.3 : Tutorials : カスタムデータセットの利用

Detectron2 0.3: Tutorials : カスタムデータセットの利用 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 03/04/2021 (0.3)

* 本ページは、Detectron2 ドキュメントの以下のページを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

無料セミナー実施中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
クラスキャットは人工知能・テレワークに関する各種サービスを提供しております :

人工知能研究開発支援 人工知能研修サービス テレワーク & オンライン授業を支援
PoC(概念実証)を失敗させないための支援 (本支援はセミナーに参加しアンケートに回答した方を対象としています。)

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

 

Detectron2 : Tutorials : カスタムデータセットの利用

このドキュメントはデータセット API (DatasetCatalog, MetadataCatalog) がどのように動作するか、そしてカスタムデータセットを追加するためにそれらをどのように利用するかを説明します。

detectron2 で組込みサポートを持つデータセットは 組込みデータセット でリストアップされています。

カスタムデータセットを detectron2 のデータローダも再利用しながら利用することを望む場合、以下を行なうことが必要です :

  1. データセットを登録する (i.e., データセットをどのように得るかを detectron2 に知らせます)。
  2. オプションで、データセットのためのメタデータを登録します。

次に、上の 2 つのコンセプトを詳細に説明します。

Colab チュートリアル はどのように登録してカスタム形式のデータセット上で訓練するかのライブサンプルを持ちます。

 

データセットを登録する

“my_dataset” という名前のデータセットをどのよう得るかを detectron2 に知らせるため、ユーザはデータセットの項目を返す関数を実装してからこの関数について detectron2 に知らせる必要があります :

def my_dataset_function():
  ...
  return list[dict] in the following format

from detectron2.data import DatasetCatalog
DatasetCatalog.register("my_dataset", my_dataset_function)
# later, to access the data:
data: List[Dict] = DatasetCatalog.get("my_dataset")

ここで、スニペットは “my_dataset” という名前のデータセットをデータを返す関数と関連付けています。関数は複数回呼び出された場合同じデータを返さなければなりません。登録はプロセスが抜けるまで有効であり続けます。

関数は任意のことができて以下の形式のいずれかでデータを返すべきです :

  1. 下で説明される、Detectron2 の標準データセット辞書。これは detectron2 の多くの他の組込み特徴とともにそれを動作させますので、それで十分な場合には利用することが推奨されます。
  2. 任意のカスタム形式。新しいタスクのために特別なキーを追加したような、貴方自身の形式で任意の辞書を返すこともできます。それからそれらをダウンストリームで正しく処理する必要もあるでしょう。より詳細については下を見てください。

 

標準データセット辞書

標準的なタスク (インスタンス検出、インスタンス/セマンティック/パノプティック (= panoptic) セグメンテーション、キーポイント検出) のためには、元のデータセットを COCO のアノテーションに類似した仕様を持つ list[dict] にロードします。これはデータセットのための標準的な表現です。

各辞書は一つの画像についての情報を含みます。辞書は以下のフィールドを持つかもしれません、そして必要なフィールドはデータローダやタスクが何を必要とするかに基づいて様々です (更に下を見てください)。

タスク フィールド
一般 file_name, height, width, image_id
インスタンス検出/セグメンテーション annotations
セマンティック・セグメンテーション sem_seg_file_name
パノプティック・セグメンテーション pan_seg_file_name, segments_info

  • file_name: 画像ファイルへのフルパス。

  • height, width: 整数。画像の shape。

  • image_id (str or int): この画像を識別するユニーク ID。画像を識別するために多くの evaluator (評価器) により必要とされますが、データセットは異なる目的のためにそれを利用するかもしれません。

  • annotations (list[dict]): インスタンス検出/セグメンテーション or キーポイント検出タスクにより必要とされます。各辞書はこの画像の一つのインスタンスのアノテーションに対応し、以下のキーを含むかもしれません :
    • bbox (list[float], 必須): インスタンスのバウンディング・ボックスを表す 4 つの数のリスト。
    • bbox_mode (int, 必須): bbox の形式。それは structures.BoxMode のメンバーでなければなりません。現在は以下をサポートしています : BoxMode.XYXY_ABS, BoxMode.XYWH_ABS.
    • category_id (int, 必須): カテゴリー・ラベルを表す範囲 [0, num_categories-1] の整数。値 num_categories は該当する場合、「背景」カテゴリーを表すために予約されています。
    • segmentation (list[list[float]] or dict): インスタンスのセグメンテーション・マスク。
      • list[list[float]] の場合、それはポリゴンのリストを表し、オブジェクトの関係のある各コンポーネントのために一つです。各 list[float] は [x1, y1, …, xn, yn] の形式にある一つの単純なポリゴンです。X と Y はピクセルのユニット内の絶対座標です。
      • 辞書の場合、それは COCO の圧縮 RLE 形式のピクセル毎セグメンテーション・マスクを表します。辞書はキー “size” と “counts” を持つべきです。pycocotools.mask.encode(np.asarray(mask, order=”F”)) により 0 と 1 の uint8 セグメンテーション・マスクをそのような辞書に変換できます。そのような形式を持つデフォルトのデータローダを使用する場合 cfg.INPUT.MASK_FORMAT が bitmask に設定されなければなりません。
    • keypoints (list[float]): [x1, y1, v1,…, xn, yn, vn] の形式にあります。 v[i] はこのキーポイントの visibility を意味します。n はキーポイント・カテゴリーの数に等しくなければなりません。X と Y は範囲 [0, W or H] の絶対実数値座標です。

      (COCO のキーポイント座標は範囲 [0, W-1 or H-1] の整数であることに注意してください、これは (私達の) 標準形式とは異なります。Detectron2 は COCO キーポイント座標を離散ピクセルインデックスから浮動小数点座標に変換するために 0.5 を加えます。)

    • iscrowd: 0 (デフォルト) or 1. このインスタンスが COCO の “crowd region” としてラベル付けされるか否か。それが何を意味するか知らない場合にはこのフィールドを含めないでください。

    annotations が空リストである場合、それは画像がオブジェクトを持たないとしてラベル付けされることを意味します。そのような画像はデフォルトでは訓練から除去されますが、DATALOADER.FILTER_EMPTY_ANNOTATIONS を使用して含めることができます。

  • sem_seg_file_name (str): セマンティック・セグメンテーション正解ファイルへのフルパス。それはピクセル値が整数ラベルであるグレイスケール画像であるべきです。

  • pan_seg_file_name (str): パノプティック・セグメンテーション正解ファイルへのフルパスです。それは RGB 画像であるべきです、そのピクセル値は panopticapi.utils.id2rgb 関数を使用してエンコードされる整数 id です。id は segments_info により定義されます。id が segments_info に現れない場合、ピクセルはラベル付けされていないと考えられて通常は訓練 & 評価で無視されます。

  • segments_info (list[dict]): パノプティック・セグメンテーション正解の各 id の意味を定義します。各辞書は以下のキーを持ちます :
    • id (int): 正解画像に現れる整数。
    • category_id (int): カテゴリーラベルを表す範囲 [0, num_categories-1] の整数。
    • iscrowd: 0 (default) or 1. このインスタンスが COCO の “crowd region” としてラベル付けされるか否か。

Note

PanopticFPN モデルはここで定義されたパノプティック・セグメンテーション形式ではなく、インスタンス・セグメンテーションとセマンティック・セグメンテーション・データ形式の両者の組合せを利用します。COCO の説明については Use Builtin Datasets を見てください。

Fast R-CNN (with pre-computed proposals) モデルは今日では滅多に利用されません。Fast R-CNN を訓練するには、以下の特別なキーが必要です :

  • proposal_boxes (array): この画像のための K precomputed proposal ボックスを表す shape (K, 4) を持つ 2D numpy 配列。
  • proposal_objectness_logits (array): shape (K, ) を持つ numpy 配列、これは ‘proposal_boxes’ の proposal の objectness ロジットに対応します。
  • proposal_bbox_mode (int): precomputed proposal bbox の形式。それは structures.BoxMode のメンバーでなければなりません。デフォルトは BoxMode.XYXY_ABS です。

 

新しいタスクのためのカスタムデータセット辞書

貴方のデータセット関数が返す list[dict] では、辞書は任意のカスタムデータを持つこともできます。これは標準的なデータセット辞書ではカバーされない特別な情報を必要とする新しいタスクのために有用です。この場合、ダウンストリーム・コードが貴方のデータを正しく処理できるかを確実にする必要があります。通常はこれはデータローダのための新しいマッパーを各必要があります (Use Custom Dataloaders 参照)。

カスタム形式を設計するとき、総ての辞書がメモリにストアされることに注意してください (時にシリアライズされて複数のコピーを伴います)。メモリを節約するため、各辞書はファイル名やアノテーションのような、各サンプルについて小さくても十分な情報を含むことを意図しています。full サンプルのロードは典型的にはデータローダで発生します。

データセット全体の中で共有される属性については、Metadata を使用します (下を見てください)。余計なメモリを回避するため、そのような情報を各サンプル内にセーブしないでください。

 

データセットのための “Metadata”

各データセットはあるメタデータと関連し、MetadataCatalog.get(dataset_name).some_metadata を通してアクセス可能です。メタデータはデータセット全体で共有される情報を含むキーバリュー・マッピングで、通常はデータセットにあるものを解釈するために使用されます、e.g., クラス名、クラスの色、ファイルのルート等です。この情報は増強、評価、可視化、ロギング等のために有用です。メタデータの構造は対応するダウンストリーム・コードから必要とされるものに依拠します。

DatasetCatalog.register を通して新しいデータセットを登録する場合、メタデータを必要とする任意の特徴を有効にするため、MetadataCatalog.get(dataset_name).some_key = some_value を通して対応するメタデータを追加することも望むかもしれません。それをこのように行なうことができます (サンプルとしてメタデータ・キー “thing_classes” を使用します) :

from detectron2.data import MetadataCatalog
MetadataCatalog.get("my_dataset").thing_classes = ["person", "dog"]

ここに detectron2 の組込み特徴により使用されるメタデータ・キーのリストがあります。これらのメタデータなしに貴方自身のデータセットを追加する場合、幾つかの特徴は利用可能ではないかもしれません :

  • thing_classes (list[str]): 総てのインスタンス検出/セグメンテーション・タスクにより使用されます。各インスタンス/thing カテゴリーのための名前のリストです。COCO 形式データセットをロードする場合、それは関数 load_coco_json により自動的に設定されます。
  • thing_colors (list[tuple(r, g, b)]): 各 thing カテゴリーのための事前定義された ([0, 255] 内の) 色。可視化のために使用されます。与えられない場合、ランダムカラーが使用されます。
  • stuff_classes (list[str]): セマンティックとパノプティック・セグメンテーション・タスクにより使用されます。各 stuff カテゴリーのための名前のリストです。
  • stuff_colors (list[tuple(r, g, b)]): 各 stuff カテゴリーのための事前定義された ([0, 255] 内の) 色。可視化のために使用されます。与えられない場合、ランダムカラーが使用されます。
  • ignore_label (int): セマンティックとパノプティック・セグメンテーション・タスクにより使用されます。このカテゴリーラベルを持つ正解アノテーションのピクセルは評価で無視されるべきです。典型的にはこれらは「ラベル付けされていない」ピクセルです。
  • keypoint_names (list[str]): キーポイント検出により使用されます。各キーポイントのための名前のリストです。
  • keypoint_flip_map (list[tuple[str]]): キーポイント検出により使用されます。名前のペアのリストで、そこでは各ペアは増強の間に画像が水平に反転された場合反転されるべき 2 つのキーポイントです。
  • keypoint_connection_rules: list[tuple(str, str, (r, g, b))]. 各タプルは接続されたキーポイントのペアと可視化されるときそれらの間のラインのために使用される色を指定します。

幾つかの追加のメタデータ、これらは特定のデータセット (e.g. COCO) の評価に固有です :

  • thing_dataset_id_to_contiguous_id (dict[int->int]): COCO 形式の総てのインスタンス検出/セグメンテーション・タスクにより使用されます。データセットのインスタンス・クラス id から範囲 [0, #class) の連続 id へのマッピング。関数 load_coco_json により自動的に設定されます。
  • stuff_dataset_id_to_contiguous_id (dict[int->int]): セマンティック/パノプティック・セグメンテーションのための予測 json ファイルを生成するときに使用されます。データセットのセマンティック・クラス id から [0, num_categories) の連続 id へのマッピング。評価のためだけに有用です。
  • json_file: COCO アノテーション json ファイル。COCO-形式データセットのための COCO 評価により使用されます。
  • panoptic_root, panoptic_json: COCO-形式パノプティック評価により使用されます。
  • evaluator_type: evaluator (評価器) を選択するために組込み main 訓練スクリプトにより使用されます。新しい訓練スクリプトでそれを使用しないでください。貴方の main スクリプトで直接データセットのために DatasetEvaluator を単に提供することができます。

Note

見て分かるように (= in recognition)、時にインスタンス-level タスクのために用語 “thing” をセマンティック・セグメンテーション・タスクのために “stuff” を使用します。両者はパノプティック・セグメンテーション・タスクで使用されます。”thing” と “stuff” のコンセプトの背景については、On Seeing Stuff: The Perception of Materials by Humans and Machines を見てください。

 

COCO 形式データセットを登録する

貴方のインスタンス-level (検出、セグメンテーション、キーポイント) データセットが既に COCO 形式の json ファイルであれば、データセットとその関連するメタデータは次で容易に登録できます :

from detectron2.data.datasets import register_coco_instances
register_coco_instances("my_dataset", {}, "json_annotation.json", "path/to/image/dir")

データセットが COCO 形式にあるものの更なる処理が必要とされたり、特別なインスタンス毎カスタム・アノテーションを持つ場合、load_coco_json 関数が有用であるかもしれません。

 

新しいデータセットのために Config を更新する

ひとたびデータセットを登録したならば、cfg.DATASETS.{TRAIN,TEST} でデータセットの名前 (e.g., 上のサンプルの “my_dataset”) を利用できます。

新しいデータセット上で訓練または評価するために変更することを望むかもしれない他の config があります :

  • MODEL.ROI_HEADS.NUM_CLASSES と MODEL.RETINANET.NUM_CLASSES はそれぞれ R-CNN と RetinaNet モデルのための thing クラスの数です。

  • MODEL.ROI_KEYPOINT_HEAD.NUM_KEYPOINTS は Keypoint R-CNN のためのキーポイントの数を設定します。評価のために TEST.KEYPOINT_OKS_SIGMAS で Keypoint OKS を設定する必要もあります。
  • MODEL.SEM_SEG_HEAD.NUM_CLASSES は Semantic FPN & Panoptic FPN のための stuff クラスの数を設定します。
  • TEST.DETECTIONS_PER_IMAGE は検出されるオブジェクトの最大数を制御します。テスト画像が >100 オブジェクトを含むかもしれない場合にはそれをより大きな数に設定します。
  • Fast R-CNN (with precomputed proposals) を訓練している場合、DATASETS.PROPOSAL_FILES_{TRAIN,TEST} はデータセットに一致する必要があります。proposal ファイルの形式は ここで 文書化されています。

新しいモデル (e.g. TensorMask, PointRend) はしばしばそれら自身の類似の config を持ちます、それらもまた変更される必要があります。

Tip

クラス数を変更した後、事前訓練されたモデルのある層は非互換になりますので新しいモデルにロードできません。これは想定され、そのような事前訓練モデルのロードはそのような層についての警告を生成します。

 

以上