detectron2使用自定義數據集及數據加載

1、使用自定義數據集

數據集中列出了detectron2中內置支持的數據集。如果要使用自定義數據集,同時還重複使用detectron2的數據加載器,則需要:

1)註冊您的數據集(即,告訴detectron2如何獲取您的數據集)。

2)(可選)爲您的數據集註冊元數據。

接下來,我們詳細解釋以上兩個概念。該Colab教程 對如何對自定義格式的數據集註冊和訓練標準數據集。

1.1、註冊數據集

爲了讓detectron2知道如何獲取名爲“ my_dataset”的數據集,您將實現一個函數,該函數返回數據集中的項目,然後將此函數告知detectron2:

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

from detectron2.data import DatasetCatalog
DatasetCatalog.register("my_dataset", my_dataset_function)

在此,代碼段將數據集“ my_dataset”與返回數據的函數相關聯。如果多次調用,該函數必須返回相同的數據。註冊將一直有效直到該過程退出。

該函數可以將數據從其原始格式處理爲以下任意一種:

1、Detectron2的標準數據集字典,如下所述。它可以與detectron2中的許多其他內置功能一起使用,因此建議在足以完成任務時使用它。

2、您的自定義數據集字典。您還可以以自己的格式返回任意字典,例如爲新任務添加額外的鍵。然後,您還需要在下游正確處理它們。請參閱下面的更多細節。

1.2、標準數據集字典

對於標準任務(實例檢測,實例/語義/全景分割,關鍵點檢測),我們將原始數據集加載到list[dict]具有類似於COCO json註釋的規範中。這是我們對數據集的標準表示。

每個字典包含有關一個圖像的信息。dict可能具有以下字段,並且必填字段根據數據加載器或任務的需要而有所不同(請參閱下文)。

  • file_name:圖像文件的完整路徑。如果圖像具有此類exif信息,則將應用旋轉和翻轉。

  • height,width:整數。圖像的形狀。

  • image_id(str或int):標識此圖像的唯一ID。在評估期間用於識別圖像,但數據集可將其用於不同目的。

  • annotations(list [dict]):每個字典對應此圖片中一個實例的註釋。實例檢測/細分或關鍵點檢測任務需要。

annotations默認情況下,具有空圖像的圖像將從訓練中刪除,但可以使用添加DATALOADER.FILTER_EMPTY_ANNOTATIONS。

每個dict包含以下鍵bbox,bbox_mode並且category_id是必需的:

  • bbox (list [float]):4個數字的列表,代表實例的邊界框。

  • bbox_mode(int):bbox的格式。它必須是structure.BoxMode的成員 。目前支持:BoxMode.XYXY_ABS,BoxMode.XYWH_ABS。

  • category_id(int):表示類別標籤的[0,num_categories-1]範圍內的整數。保留值num_categories表示“背景”類別(如果適用)。

  • segmentation (list [list [float]]或dict):實例的分段掩碼。

    • 如果爲list[list[float]],則表示一個多邊形列表,該對象的每個連接組件一個。每個list[float]都是一個簡單的多邊形,格式爲。Xs和Ys是以像素爲單位的絕對座標。[x1,y1,...,xn,yn]
    • 如果爲dict,則表示COCO的RLE格式的按像素分割蒙版。字典應具有鍵“大小”和“計數”。您可以通過將uint8的0和1分割掩碼轉換爲dict 。如果使用具有這種格式的默認數據加載器,則必須設置爲。pycocotools.mask.encode(np.asarray(mask,order="F"))cfg.INPUT.MASK_FORMATbitmask
  • keypoints(list [float]):格式爲[x1,y1,v1,…,xn,yn,vn]。v [i]表示此關鍵點的可見性。n必須等於關鍵點類別的數量。Xs和Ys是[0,1]中的相對座標,還是絕對座標,取決於“ bbox_mode”是否是相對的。

請注意,COCO格式的座標註釋是[0,H-1或W-1]範圍內的整數。默認情況下,detectron2向絕對關鍵點座標添加0.5,以將其從離散像素索引轉換爲浮點座標。

  • iscrowd:0(默認)或1。是否將此實例標記爲COCO的“人羣區域”。如果您不知道這是什麼意思,請不要包括此字段。

  • sem_seg_file_name:基本事實語義分段文件的完整路徑。語義分割任務需要。它應該是像素值爲整數標籤的圖像。

如今,很少使用快速R-CNN(帶有預先計算的建議)。要訓​​練快速R-CNN,需要以下額外的鍵:

  • proposal_boxes (數組):形狀爲(K,4)的2D numpy數組,表示該圖像的K個預先計算的投標框。

  • proposal_objectness_logits (數組):形狀爲(K,)的numpy數組,對應於“ proposal_boxes”中提案的客觀記錄。

  • proposal_bbox_mode(int):預先計算的投標bbox的格式。它必須是structure.BoxMode的成員 。默認值爲BoxMode.XYXY_ABS。

1.3、新任務的自定義數據集字典

在list[dict]數據集函數返回的中,字典也可以具有任意的自定義數據。這對於需要標準數據集字典不支持的額外信息的新任務很有用。在這種情況下,您需要確保下游代碼可以正確處理您的數據。通常,這需要mapper爲數據加載器編寫新文件(請參閱使用自定義數據加載器)。

在設計自定義格式時,請注意,所有字典都存儲在內存中(有時會序列化並帶有多個副本)。爲了節省內存,每個字典旨在包含有關每個樣本的少量但足夠的信息,例如文件名和註釋。加載完整樣本通常在數據加載器中進行。

對於在整個數據集中共享的屬性,請使用Metadata(請參閱下文)。爲避免額外的內存,請勿爲每個樣本重複保存此類信息。

1.4、數據集的“元數據”

每個數據集都與一些元數據相關聯,可通過訪問這些元數據 MetadataCatalog.get(dataset_name).some_metadata。元數據是一個鍵值映射,其中包含在整個數據集中共享的信息,通常用於解釋數據集中的內容,例如,類的名稱,類的顏色,文件的根目錄等。此信息對於元數據的結構取決於相應下游代碼的需求。

如果您通過來註冊新的數據集DatasetCatalog.register,則可能還需要通過來添加其相應的元數據 ,以啓用需要該元數據的所有功能。您可以這樣操作(以元數據鍵“ thing_classes”爲例):MetadataCatalog.get(dataset_name).some_key=some_value

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

這是detectron2的內置功能所使用的元數據密鑰的列表。如果添加自己的數據集而沒有這些元數據,則某些功能可能對您不可用:

  • thing_classes(list [str]):由所有實例檢測/分段任務使用。每個實例/事物類別的名稱列表。如果加載COCO格式的數據集,它將由函數自動設置load_coco_json。

  • thing_colors(list [tuple(r,g,b)]):每個事物類別的預定義顏色(在[0,255]中)。用於可視化。如果未給出,則使用隨機顏色。

  • stuff_classes(list [str]):用於語義和全景分割任務。每個物料類別的名稱列表。

  • stuff_colors(list [tuple(r,g,b)]):每個填充類別的預定義顏色(在[0,255]中)。用於可視化。如果未給出,則使用隨機顏色。

  • keypoint_names(list [str]):由關鍵點本地化使用。每個關鍵點的名稱列表。

  • keypoint_flip_map(list [tuple [str]]):由關鍵點本地化任務使用。名稱對列表,其中每對都是在增強過程中圖像水平翻轉時應該翻轉的兩個關鍵點。

  • keypoint_connection_rules:列表[tuple(str,str,(r,g,b))]。每個元組指定一對連接的關鍵點,以及在可視化時用於它們之間的線的顏色。

一些特定於某些數據集評估的其他元數據(例如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:由全景評估中使用。

  • evaluator_type:由內置的主要培訓腳本用來選擇評估者。不要在新的培訓腳本中使用它。您可以直接在主腳本中爲數據集提供DatasetEvaluator

注意:有關“事物”和“材料”概念的背景知識,請參見 “看到材料:人與機器對材料的感知”。在detectron2中,術語“事物”用於實例級任務,而“東西”用於語義分割任務。兩者都用於全景分割。

1.5、註冊COCO格式數據集

如果您的數據集已經是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 函數可能會很有用。

1.6、更新新數據集的配置

註冊數據集後,您可以在中使用數據集的名稱(例如,上例中的“ my_dataset”)cfg.DATASETS.{TRAIN,TEST}。您可能還需要更改其他配置以對新數據集進行訓練或評估:

  • MODEL.ROI_HEADS.NUM_CLASSES和MODEL.RETINANET.NUM_CLASSES分別是R-CNN和RetinaNet模型的事物類別的數量。

  • MODEL.ROI_KEYPOINT_HEAD.NUM_KEYPOINTS設置關鍵點R-CNN的關鍵點數。您還需要設置關鍵點OKS 與TEST.KEYPOINT_OKS_SIGMAS評估。

  • MODEL.SEM_SEG_HEAD.NUM_CLASSES 設置語義FPN和Panoptic FPN的東西類的數量。

  • 如果您正在訓練Fast R-CNN(帶有預先計算的建議),則DATASETS.PROPOSAL_FILES_{TRAIN,TEST}需要匹配數據集。建議文件的格式在 此處記錄

新模型(例如TensorMaskPointRend)通常具有自己的相似配置,也需要更改。

2、使用自定義數據加載器

2.1、現有數據加載器的工作方式

Detectron2包含一個內置的數據加載管道。如果您需要編寫自定義代碼,最好了解它的工作原理。

Detectron2提供了兩個函數build_detection_ {train,test} _loader ,它們從給定的配置創建默認的數據加載器。下面是如何build_detection_{train,test}_loader工作:

  1. 它採用已註冊數據集的名稱(例如“ coco_2017_train”),並list[dict]以輕量級規範格式加載表示數據集項的。這些數據集項尚未準備好由模型使用(例如,圖像未加載到內存中,尚未應用隨機擴充等)。有關數據集格式和數據集註冊的詳細信息可以在數據集中找到 。

  2. 此列表中的每個字典都由一個函數(“映射器”)映射:

  • 用戶可以通過在中指定“ mapper”參數來自定義此映射功能 build_detection_{train,test}_loader。默認的映射器是DatasetMapper
    • 該函數的輸出格式可以是任意的,只要該數據加載器的使用者(通常是模型)可以接受即可。批處理後,默認映射器的輸出遵循Use Models中記錄的默認模型輸入格式 。

    • 映射器的作用是將數據集項目的輕量級規範表示形式轉換爲可供模型使用的格式(包括例如讀取圖像,執行隨機數據增強並轉換爲割炬張量)。如果要對數據執行自定義轉換,則通常需要自定義映射器。

  1. 映射器的輸出被批處理(簡單地成一個列表)。

  2. 批處理的數據是數據加載器的輸出。通常,它也是的輸入 model.forward()。

2.2、編寫自定義數據加載器

build_detection_{train,test}_loader(mapper=)在大多數自定義數據加載的用例中,使用不同的“映射器”即可。例如,如果您想將所有圖像調整爲固定大小以進行Mask R-CNN訓練,請編寫以下代碼:

from detectron2.data import build_detection_train_loader
from detectron2.data import transforms as T
from detectron2.data import detection_utils as utils

def mapper(dataset_dict):
	# Implement a mapper, similar to the default DatasetMapper, but with your own customizations
	dataset_dict = copy.deepcopy(dataset_dict)  # it will be modified by code below
	image = utils.read_image(dataset_dict["file_name"], format="BGR")
	image, transforms = T.apply_transform_gens([T.Resize((800, 800))], image)
	dataset_dict["image"] = torch.as_tensor(image.transpose(2, 0, 1).astype("float32"))

	annos = [
		utils.transform_instance_annotations(obj, transforms, image.shape[:2])
		for obj in dataset_dict.pop("annotations")
		if obj.get("iscrowd", 0) == 0
	]
	instances = utils.annotations_to_instances(annos, image.shape[:2])
	dataset_dict["instances"] = utils.filter_empty_instances(instances)
	return dataset_dict

data_loader = build_detection_train_loader(cfg, mapper=mapper)
# use this dataloader instead of the default

有關詳細信息,請參考detectron2.data的API文檔

如果您不僅要更改映射器(例如,編寫不同的採樣或批處理邏輯),還可以編寫自己的數據加載器。數據加載器只是一個python迭代器,它產生模型接受的格式。您可以使用任何喜歡的工具來實現它。

2.3、使用自定義數據加載器

如果使用DefaultTrainer,則可以覆蓋其build_{train,test}_loader方法以使用自己的數據加載器。有關 示例,請參見densitypose數據加載器。

如果您編寫自己的訓練循環,則可以輕鬆插入數據加載器。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章