Detectron2 “快速开始” Detection Tutorial Colab Notebook 详细解读

Detectron2解读全部文章链接:

  1. Facebook计算机视觉开源框架Detectron2学习笔记 — 从demo到训练自己的模型

  2. Detectron2 “快速开始” Detection Tutorial Colab Notebook 详细解读

  3. Detectron2 官方文档详细解读 (上)

  4. Detectron2 官方文档详细解读(下)

  5. Detectron2 代码解读(1)如何构建模型

  6. Pytorch 基于 Detectron2 从零实现 Unet

Detectron新手教程

官方 Colab Notebook 上 Beginner Tutorial 部分阅读:

1. 使用预训练的Detectron2模型

下载一张图片,我们需要创建detectron2 config,随后根据config创建一个Default Predictor去进行单张图片推理。

cfg = get_cfg() # 获取 Default Config
# 根据 mask_rcnn_R_50_FPN_3x.yaml 的配置文件更新 config
cfg.merge_from_file(model_zoo.get_config_file("COCOInstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))
# 推理的显示阈值设置为 0.5
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5
# 根据配置文件选择对应的训练好的模型
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
# 创建 DefaultPredictor
predictor = DefaultPredictor(cfg)
# 推理
outputs = predictor(im)

获取网络输出结果:

print(outputs['instances'].pred_classes)
print(outputs['instances'].pred_boxes)

我们可以使用 Visualizer 类去可视化输出结果:

v = Visualizer(im[:,:,::-1], MetadataCatalog.get(cfg.DATASETS.TRAIN[0]), scale=1.2)
out = v.draw_instance_predictions(outputs['instances'].to('cpu'))
cv2_imshow(out.get_image()[:,:,::-1])

2. 在自定义数据集上训练

准备数据集

在这一部分,我们学习如何在自定义数据集上训练。我们以气球分割数据集为例,这个数据集只有一类:气球。我们使用在COCO数据集上预训练的模型。

准备好数据集后,我们尽量把数据集转换成COCO格式。对于COCO格式的数据集,我们可以直接用如下方法注册数据集:

from detectron2.data.datasets import register_coco_instances
register_coco_instances(
    "my_dataset_train",
    {},
    "json_annotation_train.json",
    "path/to/image/dir"
                       )
register_coco_instances(
	"my_dataset_val",
    {},
    "json_annotation_train.json",
    "path/to/image/dir"
)

如果我们的数据集是自己的格式,我们需要自定义一个函数来把自己格式的数据集输入detectron2。首先我们需要定义 get_balloon_dicts(img_dir) 方法来从数据集文件夹获取 dataset_dicts,之后通过DatasetCatalog.register方法把dataset_dicts注册到detectron2中。训练时使用 MetadataCatalog.get 来获取 Metadata。

from detectron2.structures import BoxMode

def get_balloon_dicts(img_dir):
    json_file = os.path.join(img_dir, "via_region_data.json")
    with open(json_file) as f:
        imgs_anns = json.load(f)
    
    dataset_dicts = []
    for idx, v in enumerate(imgs_anns.values()):
        record = {}
        
        filename = os.path.join(img_dir, v["filename"])
        height, width = cv2.imread(filename).shape[:2]
        
        """
        对于每张图片,我们需要记录: 
        1.图片的文件名,2.图片的编号,3.图片的高,4.图片的宽		
        """
        record["file_name"] = filename
        record["image_id"] = idx
        record["height"] = height
        record["width"] = width
        
        annos = v["regions"]
        objs = []
        
        # 对于单张图片的每个标注(annotation)
        for _, anno in annos.items():
            assert not anno["region_attributes"]
            anno = anno["shape_attributes"]
            px = anno["all_points_x"]
            py = anno["all_points_y"]
            poly = [(x+0.5, y+0.5) for x, y in zip(px, py)]
            poly = [p for x in poly for p in x]
            
            # 创建物体的字典
            obj = {
                "bbox":[np.min(px), np.min(py), np.max(px), np.max(py)], # 物体轮廓同时可以转换为一个框
                "bbox_mode": BoxMode.XYXY_ABS,
                "segmentation": [poly],
                "category_id": 0,
            }
            objs.append(obj)
        # 把转换完形式的字典放进 record 中
        record["annotations"] = objs
        # 把单张图片的信息加入 dataset_dict
        dataset_dicts.append(record)
    return dataset_dicts


for d in ["train", "val"]:
    DatasetCatalog.register("balloon_"+d, lambda d=d:get_ballon_dicts("balloon/"+d))
    MetadataCatalog.get("balloon_"+d).set(things_classes=["balloon"])

ballon_metadata = MetadataCatalog.get("balloon_train")

这些工作做完之后,我们可以测试数据集是否注册正确:

dataset_dicts = get_ballon_dicts("balloon/train")
for d in random.sample(dataset_dicts, 3):
    img = cv2.imread(d["filename"])
    visualizer = Visualizer(img[:,:,::-1], metadata=ballon_metadata, scale=0.5)
    out = visualizer.draw_dataset_dict(d)
    cv2_imshow(out.get_image()[:,:,::-1])
    #cv2_imshow方法不是opencv中的,可以使用cv2.imshow来显示图片。

训练

准备好数据集之后,我们即可开始训练,作为例子,我们使用在COCO数据集上与训练的 R50-FPN Mask R-CNN 模型。

from detectron2.engine import DefaultTrainer

cfg = get_cfg()
cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))
# "balloon_train"数据集已经被注册进去了,这里指定训练数据集
cfg.DATASETS.TRAIN = ("balloon_train",)
# 加载预训练模型
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
# 训练的一些基础参数
cfg.SOLVER.IMS_PER_BATCH = 2
cfg.SOLVER.BASE_LR = 0.00025
cfg.SOLVER.MAX_ITER = 300
cfg.SOLVER.STEPS = []
cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 128
cfg.MODEL.ROI_HEADS.NUM_CLASSES = 1

os.makedirs(cfg.OUTPUT_DIR, exist_ok=True)
trainer = DefaultTrainer(cfg) 
trainer.resume_or_load(resume=False)
#调用 trainer.train() 开始训练
trainer.train()

训练曲线可以在tensorboard上面可视化:

%load_ext tensorboard
%tensorboard --logdir output

推理和Evaluation

现在模型已经训练好,我们需要对没模型进行评测和单张图片推理,我们需要创建一个 predictor。推理时使用的config必须和训练时一致,我们只需要对config进行一些小改动:

cfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, "model_final.pth") # 加载训练好的模型
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.7 # 评分在0.7以上的框才可视化
predictor = DefaultPredictor(cfg)

之后我们随机从测试集选取几张图片:

from detectron2.utils.visualizer import ColorMode
dataset_dicts = get_balloon_dicts("balloon/val")
for d in random.sample(dataset_dicts, 3):    
    im = cv2.imread(d["file_name"])
    outputs = predictor(im)
    # 查看outputs的格式请浏览:https://detectron2.readthedocs.io/tutorials/models.html#model-output-format
    v = Visualizer(im[:, :, ::-1],
                   metadata=balloon_metadata, 
                   scale=0.5, 
                   instance_mode=ColorMode.IMAGE_BW
    )
    out = v.draw_instance_predictions(outputs["instances"].to("cpu"))
    cv2_imshow(out.get_image()[:, :, ::-1])

我们可以通过 COCOEvaluator 来评测数据集的 AP 等表现:

from detectron2.evaluation import COCOEvaluator, inference_on_dataset
from detectron2.data import build_detection_test_loader

evaluator = COCOEvaluator("balloon_val", ("bbox", "segm"), False, output_dir="./output/")
val_loader = build_detection_test_loader(cfg, "balloon_val")
print(inference_on_dataset(trainer.model, val_loader, evaluator))

其它模型的训练同理。

在视频上执行全景分割 (略)

你可能感兴趣的:(CV,计算机视觉,深度学习,pytorch,神经网络,计算机视觉,cv)