detectron2模型使用、讀寫、訓練及測試

1、使用模型

在detectron2模型(及其子模型)是由功能,如內置build_model,build_backbone,build_roi_heads:

from detectron2.modeling import build_model
model = build_model(cfg)  # returns a torch.nn.Module

build_model僅建立模型結構並用隨機參數填充它。有關如何將現有檢查點加載到模型以及如何使用model對象的信息,請參見下文。

1.1、加載/保存檢查點

from detectron2.checkpoint import DetectionCheckpointer
DetectionCheckpointer(model).load(file_path_or_url)  # load a file, usually from cfg.MODEL.WEIGHTS

checkpointer = DetectionCheckpointer(model, save_dir="output")
checkpointer.save("model_999")  # save to output/model_999.pth

Detectron2的檢查點可以識別pytorch .pth格式的模型以及.pkl我們模型動物園中的文件。 有關其用法的更多詳細信息,請參見API文檔

該模型文件可以使用任意操縱torch.{load,save}的.pth文件或 pickle.{dump,load}對.pkl文件。

1.2、使用模型

可以通過調用模型,其中是。每個字典對應一個圖像,所需的鍵取決於模型的類型以及模型是處於訓練還是評估模式。例如,爲了進行推斷,所有現有模型都希望使用“圖像”鍵,並且可以選擇使用“高度”和“寬度”。現有模型的輸入和輸出的詳細格式說明如下。

outputs = model(inputs) inputs list[dict]

在訓練模式下,所有模型都必須在下方使用EventStorage。培訓統計信息將被存儲:

from detectron2.utils.events import EventStorage
with EventStorage() as storage:
  losses = model(inputs)

如果只想使用現有模型進行簡單推斷,則 DefaultPredictor 是提供此類基本功能的模型包裝。它包括默認行爲,包括模型加載,預處理以及對單個圖像(而不是批量圖像)進行操作。有關用法,請參見其文檔。

模型也可以像這樣直接使用:

model.eval()
with torch.no_grad():
  outputs = model(inputs)

1.3、模型輸入格式

用戶可以實現支持任何任意輸入格式的自定義模型。在這裏,我們描述了detectron2中所 有內置模型都支持的標準輸入格式。它們都以a list[dict]作爲輸入。每個字典對應於有關一個圖像的信息。

該字典可能包含以下鍵:

  • “圖像”:Tensor(C,H,W)格式。通道的含義由定義cfg.INPUT.FORMAT。圖像歸一化(如果有)將使用在模型內部執行 cfg.MODEL.PIXEL_{MEAN,STD}。

  • “ height”,“ width”:所需的輸出高度和寬度,不一定與image字段的高度或寬度相同。例如,image如果將調整大小用作預處理步驟,則該字段包含調整大小的圖像。但是您可能希望輸出爲原始分辨率。

  • “實例”:一個 用於訓練的實例對象,具有以下字段:

    • “ gt_boxes”:一個Boxes對象,存儲N個盒子,每個實例一個。

    • “ gt_classes”:Tensor長類型,是N個標籤的向量,範圍[0,num_categories)。

    • “ gt_masks”:一個PolygonMasks 或BitMasks對象,存儲N個遮罩,每個實例一個。

    • “gt_keypoints”:一個關鍵點 對象存儲N個關鍵點集,每個實例。

  • “建議”: 僅在Fast R-CNN樣式模型中使用的Instances對象,具有以下字段:

    • “ proposal_boxes”:一個Boxes對象,存儲P個投標框。

    • “ objectness_logits”:TensorP分數的向量,每個提案一個。

如果提供,則模型將以該分辨率產生輸出,而不是以image模型的輸入分辨率產生輸出。這樣更有效,更準確。

  • “ sem_seg”:(Tensor[int]H,W)格式。語義分割是訓練的基礎。值代表從0開始的類別標籤。

它如何連接到數據加載器:

默認DatasetMapper的輸出是遵循上述格式的字典。數據加載器執行批處理後,list[dict]內置模型將支持它。

1.4、模型輸出格式

在訓練模式下,內置模型將輸出dict[str->ScalarTensor]所有損失。

在推理模式下,內置模型list[dict]爲每個圖像輸出一個dict。根據模型正在執行的任務,每個字典可能包含以下字段:

  • “實例”: 具有以下字段的實例對象:

    • “ pred_boxes”:Boxes對象,存儲N個盒子,每個檢測到的實例一個。

    • “分數”:TensorN個分數的向量。

    • “ pred_classes”:TensorN個標籤的向量,範圍爲[0,num_categories)。

    • “ pred_masks”:Tensor形狀(N,H,W)的a,每個檢測到的實例的掩碼。

    • “ pred_keypoints”:Tensor形狀爲a(N,num_keypoint,3)。最後一維中的每一行都是(x,y,score)。分數大於0。

  • “ sem_seg”:Tensorof(num_categories,H,W),語義分割預測。

  • “建議”: 具有以下字段的實例對象:

    • “ proposal_boxes”: 存儲N個盒子的Boxes對象。

    • “ objectness_logits”:N個得分的火炬矢量。

  • “ panoptic_seg”:的元組。張量具有(H,W)的形狀,其中每個元素代表像素的段ID。每個字典描述一個段ID,並具有以下字段:(Tensor, list[dict])

    • “ id”:細分ID

    • “事物”:細分是事物還是事物

    • “ category_id”:此細分的類別ID。它表示when isthing==True的事物類ID,否則代表stuff類ID。

1.5、部分執行模型

有時您可能想在模型內部獲得中間張量。由於通常有數百個中間張量,因此沒有提供所需中間結果的API。您有以下選擇:

  1. 編寫一個(子)模型。在學習完本教程之後,您可以重寫模型組件(例如,模型的頭部),使其與現有組件具有相同的功能,但是返回所需的輸出。

  2. 部分執行模型。您可以像往常一樣創建模型,但是可以使用自定義代碼而不是來執行模型forward()。例如,以下代碼在蒙版頭之前獲取蒙版特徵。

images = ImageList.from_tensors(...)  # preprocessed input tensor
model = build_model(cfg)
features = model.backbone(images.tensor)
proposals, _ = model.proposal_generator(images, features)
instances = model.roi_heads._forward_box(features, proposals)
mask_features = [features[f] for f in model.roi_heads.in_features]
mask_features = model.roi_heads.mask_pooler(mask_features, [x.pred_boxes for x in instances])

請注意,這兩個選項都要求您閱讀現有的前向代碼,以瞭解如何編寫代碼以獲得所需的輸出。

2、寫模型

如果您要嘗試全新的工作,則可能希望完全在detectron2中從頭開始實現模型。但是,在許多情況下,您可能會對修改或擴展現有模型的某些組件感興趣。因此,我們還提供了一種註冊機制,使您可以覆蓋標準模型的某些內部組件的行爲。

例如,要添加新的主幹,請將以下代碼導入您的代碼中:

from detectron2.modeling import BACKBONE_REGISTRY, Backbone, ShapeSpec

@BACKBONE_REGISTRY.register()
class ToyBackBone(Backbone):
  def __init__(self, cfg, input_shape):
    super().__init__()
    # create your own backbone
    self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=16, padding=3)

  def forward(self, image):
    return {"conv1": self.conv1(image)}

  def output_shape(self):
    return {"conv1": ShapeSpec(channels=64, stride=16)}

然後,您可以在配置對象中使用。 然後會致電給您。cfg.MODEL.BACKBONE.NAME = 'ToyBackBone'build_model(cfg)ToyBackBone

再舉一個例子,要向Generalized R-CNN元體系結構中的ROI頭添加新功能,可以實現一個新的 ROIHeads子類並將其放在中ROI_HEADS_REGISTRY。有關 實現新ROIHeads來執行新任務的示例,請參見detectron2 和meshrcnn中的密集姿勢。和項目/ 包含實現不同的架構更多的例子。

完整的註冊表列表可以在API文檔中找到。您可以在這些註冊表中註冊組件,以自定義模型的不同部分或整個模型。

3、訓練

從前面的教程中,您現在可能已經有了一個自定義模型和一個數據加載器。要進行培訓,用戶通常會偏好以下兩種樣式之一:

3.1、自定義訓練

準備好模型和數據加載器後,可以在PyTorch中找到編寫訓練循環所需的所有其他內容,您可以自己編寫訓練循環。這種風格使研究人員可以更清晰地管理整個培訓邏輯並擁有完全的控制權。tools / plain_train_net.py中提供了一個這樣的示例。

然後,用戶可以輕鬆地控制訓練邏輯上的任何定製。

3.2、訓練抽象

我們還提供帶有鉤子系統的標準化“培訓師”抽象,可幫助簡化標準培訓行爲。它包括以下兩個實例:

  • SimpleTrainer 爲單一成本的單一優化器單一數據源的培訓提供了一個最小的培訓循環,僅此而已。其他任務(檢查點,記錄等)可以使用掛鉤系統來實現 。

  • DefaultTrainer是SimpleTrainer從配置中初始化的,由 tools / train_net.py和許多腳本使用。它包括人們可能希望採用的更多標準默認行爲,包括優化程序的默認配置,學習率計劃,日誌記錄,評估,檢查點等。

要自定義DefaultTrainer:

  1. 對於簡單的自定義(例如,更改優化器,評估器,LR調度程序,數據加載器等),請在子類中覆蓋其方法,就像tools / train_net.py一樣

  2. 使用培訓師+掛鉤系統意味着總會有一些非標準行爲無法得到支持,尤其是在研究中。對於培訓期間的更復雜的任務,請查看 掛鉤系統是否可以支持它,或者從tools / plain_train_net.py開始手動實施培訓邏輯。

3.3、指標記錄

在訓練過程中,detectron2模型和訓練員將指標放入集中式EventStorage中。您可以使用以下代碼對其進行訪問併爲其記錄指標:

from detectron2.utils.events import get_event_storage

# inside the model:
if self.training:
  value = # compute the value from inputs
  storage = get_event_storage()
  storage.put_scalar("some_accuracy", value)

有關更多詳細信息,請參閱其文檔。

然後使用EventWriter將度量標準寫入不同的目標。DefaultTrainer啓用了一些EventWriter默認配置。有關如何自定義它們的信息,請參見上文。

4、評價

評估是一個過程,需要多個輸入/輸出對並進行彙總。您始終可以直接使用模型,而只是手動解析其輸入/輸出以執行評估。或者,可以使用DatasetEvaluator 接口在detectron2中實現評估。

Detectron2包括一些DatasetEvaluator使用標準數據集特定的API(例如COCO,LVIS)來計算指標的工具。您也可以DatasetEvaluator使用輸入/輸出對來實現自己的任務,以執行其他一些工作。例如,要計算在驗證集上檢測到多少個實例:

class Counter(DatasetEvaluator):
  def reset(self):
    self.count = 0
  def process(self, inputs, outputs):
    for output in outputs:
      self.count += len(output["instances"])
  def evaluate(self):
    # save self.count somewhere, or print it, or return it.
    return {"count": self.count}

4.1、使用評估器

要使用評估器的方法進行手動評估,請執行以下操作:

def get_all_inputs_outputs():
  for data in data_loader:
    yield data, model(data)

evaluator.reset()
for inputs, outputs in get_all_inputs_outputs():
  evaluator.process(inputs, outputs)
eval_results = evaluator.evaluate()

評估程序也可以與inference_on_dataset一起使用。例如,

eval_results = inference_on_dataset(
    model,
    data_loader,
    DatasetEvaluators([COCOEvaluator(...), Counter()]))

這將model在來自的所有輸入上執行data_loader,並調用evaluator進行處理。

與使用模型手動運行評估相比,此功能的優勢在於可以使用DatasetEvaluators將評估器合併在一起,並且所有評估都可以在數據集的一次向前傳遞中完成。此功能還爲給定的模型和數據集提供準確的速度基準。

4.2、自定義數據集的評估器

detectron2中的許多評估器都是針對特定數據集的,以便使用每個數據集的官方API獲得分數。除此之外,兩個評估器還能夠評估遵循detectron2的標準數據集格式的任何通用數據,因此它們可用於評估自定義數據集:

  • COCOEvaluator能夠評估AP(平均精度),以便在任何自定義數據集上進行框檢測,實例細分,關鍵點檢測。

  • SemSegEvaluator能夠評估任何自定義數據集上的語義細分指標。

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