在 PyTorch 中使用 Detectron2 进行对象检测的指南

源节点: 1062810

这篇文章是作为 数据科学博客马拉松

目标检测是深度学习的流行应用之一。 让我们从一个现实生活中的例子开始。 你们中的大多数人会在手机中使用谷歌照片,它会根据“事物”选项下的对象自动将照片分组。 我在下面附上一个片段。

照片

来源:我的谷歌照片截图

您可以观察到该应用程序能够从图片中识别对象并使用它们将它们分类为更广泛的类别。 这是一个涉及对象检测的示例。 在本文中,我将使用一个名为 Detectron2 的最新稳健模型来执行对象检测。 我将使用 PyTorch 编写代码。

介绍 Detectron2

Facebook AI Research (FAIR) 提出了这个高级库,它在对象检测和分割问题上给出了惊人的结果。 Detectron2 基于 maskrcnn 基准。 它的实现在 PyTorch 中。 由于涉及大量计算,它需要 CUDA。

它支持边界框检测、实例分割、关键点检测、densepose检测等多项任务。 它提供了预训练的模型,您可以轻松地在新图像上加载和使用它。 我将在下一节中介绍一个示例。

装置

第一步是安装detectron2库和所需的依赖项

导入 torch.__version__ 导入 torchvision #torchvision.__version__ !pip install detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu102/torch1.7/index.html

现在,您必须导入detectron2 及其模块。

从detectron2.utils.logger 导入detectron2 从detectron2.utils.logger 导入setup_logger setup_logger() %matplotlib inline 从detectron2.engine 导入model_zoo 从detectron2.config 导入DefaultPredictor 从detectron2.utils.visualizer 导入get_cfg 从detectron2.data 导入可视化工具 从detectron2 导入MetadataCatalog、DatasetCatalog .structures 导入 BoxMode

让我们也导入我们需要的公共库。

import numpy as np import os, json, cv2, random import matplotlib.pyplot as plt

使用预训练模型进行推理:代码

Detectron2 的许多预训练模型可以在以下位置访问 模型动物园. 这些模型已经在不同的数据集上进行了训练,可以随时使用。 

即使人们正在训练他们的自定义数据集,他们也会使用这些预训练的权重来初始化他们的模型。 事实证明,它可以减少训练时间并提高性能。 我们将使用的模型是在 COCO 数据集上预训练的。

首先,我们必须定义对象检测模型的完整配置。 我们从detectron2.config 模块中导入了“get_cfg”函数,我们现在将使用它。 我选择了 Coco Instance 分段配置(YAML 文件)。 还有其他可用的选项。 您还必须设置模型的阈值分数(通常设置在 0.4 到 0.6 之间)。 您可以从检查点加载配置的预训练权重

cfg = get_cfg() cfg.merge_from_file(model_zoo.get_config_file("COCOInstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")) cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCOInstanceSegmentation_R_50_FPN_3x.yaml")

完成配置部分后,我们使用配置初始化 DefaultPredictor。

预测器 = DefaultPredictor(cfg)

现在可以开始对图像进行预测了。

让我们在示例图像上使用它。 下面的代码使用 OpenCV 库加载和读取图像。

!wget http://images.cocodataset.org/val2017/000000439715.jpg -O input.jpg im = cv2.imread("./input.jpg") print(im.shape) plt.figure(figsize=(15,7.5 ,1)) plt.imshow(im[..., ::-XNUMX])

怎么做检测?

将输入图像传递给我们初始化的预测器

输出 = 预测器(im[..., ::-1])

这个输出是一个字典。 字典有实例(预测框)、分数、预测标签,我附上了代码片段的输出

输出字典

资料来源:在我的 Kaggle 笔记本中执行。

接下来,使用 Visualizer 类查看检测是如何执行的。 可视化类具有绘制实例预测的功能。

v = Visualizer(im[:, :, ::-1], MetadataCatalog.get(cfg.DATASETS.TRAIN[0]), scale=1.2) out = v.draw_instance_predictions(outputs["instances"].to(" cpu")) plt.figure(figsize=(20,10)) plt.imshow(out.get_image()[..., ::-1][..., ::-1])
示例图片 | 使用detectron2进行物体检测

你可以观察到模型检测到了所有的人和马。

我在照片上附加了另一个示例输出。

样本图片2 | 使用detectron2进行物体检测

背景中的汽车也以 97% 的准确率被检测到。

自定义数据集上的 Detectron2

到目前为止,我们只是使用预训练模型进行推理。 但在某些情况下,您可能必须单独检测特定对象,例如汽车、人。 您可能希望从头开始在数据集上训练模型。

Detectron2 也为此提供了一种简单的方法。 让我们看看如何。

准备数据集

我将使用气球数据集,目的是检测图像中的气球。 这是一个比较简单的例子。

!wget https://github.com/matterport/Mask_RCNN/releases/download/v2.1/balloon_dataset.zip !unzip balloon_dataset.zip > /dev/null

请注意,Detectron2 需要特定格式的数据。 要将我们的气球数据集转换为这种格式,让我们定义一些辅助函数。 我们的函数将输入图像目录/文件夹路径作为输入。 然后打开并加载 JSON 文件。 我们通过JSON文件的记录枚举,得到图片路径。 从路径中读取每个图像,并将其高度、重量、文件名和图像 ID 存储在字典“记录”中。接下来,我们读取注释,并将边界框详细信息存储在另一个字典“obj”中。 在每个循环结束时,记录被附加到一个名为“dataset_dicts”的列表中。 类似地,边界框字典也附加到列表“objs”中。 该列表将依次分配为记录字典中“注释”键的值。 然后将这些记录字典中的每一个附加到将返回的最终列表中。

from detectron2.structures import BoxMode def get_balloon_images(img_folder): json_file = os.path.join(img_folder, "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] 记录["file_name"] = 文件名记录["image_id"] = idx 记录["height"] = 高度记录["width"] = width annos = v["regions"] objs = [] 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["annotations"] = objs dataset_dicts.append (记录)返回 dataset_dicts

最后,这个辅助函数返回一个带有注释的字典列表。 下一步是注册这些训练和验证数据集。 要注册数据集,您必须使用 DatasetCatalog.register 和 MetadataCatalog 方法。

对于 ["train", "val"] 中的 d:DatasetCatalog.register("balloon_" + d, lambda d=d: get_balloon_images("balloon/" + d)) MetadataCatalog.get("balloon_" + d).set (thing_classes=["balloon"]) balloon_metadata = MetadataCatalog.get("balloon_train")

训练数据可视化

我们已经注册了数据集。 现在让我们看一下训练数据。 下面的代码从气球火车数据集中随机抽取一个样本。 为了绘制实例检测,我们再次使用可视化类

dataset_dicts = get_balloon_images("balloon/train") for d in random.sample(dataset_dicts, 3): img = cv2.imread(d["file_name"]) visualizer = Visualizer(img[:, :, ::-1] , 元数据=balloon_metadata, 比例=0.5) 输出 = 可视化器.draw_dataset_dict(d) plt.figure(figsize=(15,7)) plt.imshow(out.get_image()[:, :, ::-1][. .., ::-1])

火车数据 | 使用detectron2进行物体检测

来源:气球火车数据集的图像

自定义数据培训

让我们进入训练部分。 为此,首先从 Detectron 的引擎模块导入 DefaultTrainer。 定义数据集和其他参数,如工人数量、批量大小、类数量(在本例中为 1)。 我们用预先训练的权重初始化模型并进一步训练。 最大迭代参数将根据数据集的大小和任务的复杂性而有所不同。

从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")) cfg.DATASETS.TRAIN = ("balloon_train",) cfg.DATASETS.TEST = () cfg.DATALOADER.NUM_WORKERS = 6 # 让训练从模型动物园初始化 cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml") cfg.SOLVER.IMS_PER_BATCH = 8 cfg.SOLVER.BASE_LR = 0.001 cfg。 SOLVER.MAX_ITER = 500 cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 128 # 更快,足够这个数据集(默认值:512) cfg.MODEL.ROI_HEADS.NUM_CLASSES = 1 #只有一个类(气球) os.makedirs(cfg.OUTPUT_DIR, exists_ok=True) trainer = DefaultTrainer(cfg) trainer.resume_or_load(resume=False) trainer.train()

这可能需要一段时间来训练!

成果

请注意,每当您训练深度学习模型时,请保存其最终检查点。 您可以轻松加载它以执行预测并获得推论。

下面的代码片段加载模型并初始化预测器。 我们从验证数据集中抽取一些随机样本并将它们传递给预测器。

cfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, "model_final.pth") # 我们训练的模型的路径 cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 # 设置一个测试阈值 predictor = DefaultPredictor(cfg) from detectron2.utils.visualizer import ColorMode dataset_dicts = get_balloon_images("balloon/val") for d in random.sample(dataset_dicts, 2): im = cv2.imread(d["file_name"]) outputs = predictor(im) v = Visualizer(im[:, :, ::-1], metadata=balloon_metadata, scale=0.5, instance_mode=ColorMode.IMAGE_BW) out = v.draw_instance_predictions(outputs["instances"].to("cpu")) plt.图(figsize=(15,7)) plt.imshow(out.get_image()[:, :, ::-1][..., ::-1])

这是输出!

产量

输出 2 | 使用detectron2进行物体检测

希望你喜欢这篇文章! 您可以通过以下方式与我联系 [电子邮件保护]

谢谢

本文中显示的媒体不归 Analytics Vidhya 所有,由作者自行决定使用。

资料来源:https://www.analyticsvidhya.com/blog/2021/08/your-guide-to-object-detection-with-detectron2-in-pytorch/

时间戳记:

更多来自 分析维迪亚