Mask R-CNN训练自己的数据集

news2024/12/26 3:01:22

数据集制作

通常使用labelme来制作实例分割数据集,也有教程和代码来转换成COCO数据集。labelme项目地址为:https://github.com/wkentaro/labelme/tree/main

安装labelme

conda create --name=labelme python=3
conda activate labelme
pip install labelme

# or install standalone executable/app from:
# https://github.com/wkentaro/labelme/releases

标注分割区域

在labelme标注区域时,对于存在遮挡的物体,可以利用labelme标签里的group选项。如下图所示,elephant有两部分区域,group都设置为0.
image.png

转换为COCO数据集

在labelme项目下的examples/instance_segmentation文件夹中提供转VOC和COCO两种格式的数据和脚本。本文只对转COCO格式进行描述,文件结构如下所示。
image.png
图像和标签文件
数据集的类别
对于自定义数据集,按照以上的结果准备好图像数据和标签数据,即data_annotated文件夹中的内容。运行如下代码,转换为COCO格式的数据集。

python labelme2coco.py data_annotated/ coco --labels labels.txt

完成之后,会在输出文件夹下得到如下的内容。
转换后的COCO数据
一个小的点,在保存json文件时,可以将代码修改成如下,得到的json文件看起来比较美观,同时支持中文

with open(out_ann_file, "w") as f:
    json.dump(data, f, indent=2, ensure_ascii=False))
    #ensure_ascii=False可以消除json包含中文的乱码问题

Mask R-CNN训练

本文的环境配置如下:

  • pytorch==1.7.0
  • torchvision==0.8.0
  • mmcv-full==1.2.7
  • mmdet==2.8.0

config文件修改

model config

model的配置部分,唯一需要修改的是num_classes参数,根据数据集修改对应值。

# model settings

num_classes=1

model = dict(
    type='MaskRCNN',
    pretrained='torchvision://resnet50',
    backbone=dict(
        type='ResNet',
        depth=50,
        num_stages=4,
        out_indices=(0, 1, 2, 3),
        frozen_stages=1,
        norm_cfg=dict(type='BN', requires_grad=True),
        norm_eval=True,
        style='pytorch'),
    neck=dict(
        type='FPN',
        in_channels=[256, 512, 1024, 2048],
        out_channels=256,
        num_outs=5),
    rpn_head=dict(
        type='RPNHead',
        in_channels=256,
        feat_channels=256,
        anchor_generator=dict(
            type='AnchorGenerator',
            scales=[8],
            ratios=[0.5, 1.0, 2.0],
            strides=[4, 8, 16, 32, 64]),
        bbox_coder=dict(
            type='DeltaXYWHBBoxCoder',
            target_means=[.0, .0, .0, .0],
            target_stds=[1.0, 1.0, 1.0, 1.0]),
        loss_cls=dict(
            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),
        loss_bbox=dict(type='L1Loss', loss_weight=1.0)),
    roi_head=dict(
        type='StandardRoIHead',
        bbox_roi_extractor=dict(
            type='SingleRoIExtractor',
            roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),
            out_channels=256,
            featmap_strides=[4, 8, 16, 32]),
        bbox_head=dict(
            type='Shared2FCBBoxHead',
            in_channels=256,
            fc_out_channels=1024,
            roi_feat_size=7,
            num_classes=num_classes,
            bbox_coder=dict(
                type='DeltaXYWHBBoxCoder',
                target_means=[0., 0., 0., 0.],
                target_stds=[0.1, 0.1, 0.2, 0.2]),
            reg_class_agnostic=False,
            loss_cls=dict(
                type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0),
            loss_bbox=dict(type='L1Loss', loss_weight=1.0)),
        mask_roi_extractor=dict(
            type='SingleRoIExtractor',
            roi_layer=dict(type='RoIAlign', output_size=14, sampling_ratio=0),
            out_channels=256,
            featmap_strides=[4, 8, 16, 32]),
        mask_head=dict(
            type='FCNMaskHead',
            num_convs=4,
            in_channels=256,
            conv_out_channels=256,
            num_classes=num_classes,
            loss_mask=dict(
                type='CrossEntropyLoss', use_mask=True, loss_weight=1.0))))
# model training and testing settings
train_cfg = dict(
    rpn=dict(
        assigner=dict(
            type='MaxIoUAssigner',
            pos_iou_thr=0.7,
            neg_iou_thr=0.3,
            min_pos_iou=0.3,
            match_low_quality=True,
            ignore_iof_thr=-1),
        sampler=dict(
            type='RandomSampler',
            num=256,
            pos_fraction=0.5,
            neg_pos_ub=-1,
            add_gt_as_proposals=False),
        allowed_border=-1,
        pos_weight=-1,
        debug=False),
    rpn_proposal=dict(
        nms_across_levels=False,
        nms_pre=2000,
        nms_post=1000,
        max_num=1000,
        nms_thr=0.7,
        min_bbox_size=0),
    rcnn=dict(
        assigner=dict(
            type='MaxIoUAssigner',
            pos_iou_thr=0.5,
            neg_iou_thr=0.5,
            min_pos_iou=0.5,
            match_low_quality=True,
            ignore_iof_thr=-1),
        sampler=dict(
            type='RandomSampler',
            num=512,
            pos_fraction=0.25,
            neg_pos_ub=-1,
            add_gt_as_proposals=True),
        mask_size=28,
        pos_weight=-1,
        debug=False))
test_cfg = dict(
    rpn=dict(
        nms_across_levels=False,
        nms_pre=1000,
        nms_post=1000,
        max_num=1000,
        nms_thr=0.7,
        min_bbox_size=0),
    rcnn=dict(
        score_thr=0.05,
        nms=dict(type='nms', iou_threshold=0.5),
        max_per_img=100,
        mask_thr_binary=0.5))

data config

data的配置部分,需要修改data_rootclasses参数来指明数据集的路径,以及对应的类别名列表。对于训练集、验证集和测试集的ann_fileimg_prefix两个参数需要进行调整。

dataset_type = 'CocoDataset'

img_norm_cfg = dict(
    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)

train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='LoadAnnotations', with_bbox=True, with_mask=True),
    dict(type='Resize', img_scale=(416, 416), keep_ratio=True),
    dict(type='RandomFlip', flip_ratio=0.5),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='Pad', size_divisor=32),
    dict(type='DefaultFormatBundle'),
    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels', 'gt_masks']),
]
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(
        type='MultiScaleFlipAug',
        img_scale=(416, 416),
        flip=False,
        transforms=[
            dict(type='Resize', keep_ratio=True),
            dict(type='RandomFlip'),
            dict(type='Normalize', **img_norm_cfg),
            dict(type='Pad', size_divisor=32),
            dict(type='ImageToTensor', keys=['img']),
            dict(type='Collect', keys=['img']),
        ])
]

data_root = 'datasets/xuzhou2_single_jietou/'
classes=["jietou"]
data = dict(
    samples_per_gpu=32,
    workers_per_gpu=1,
    # dataset type
    train=dict(
        type=dataset_type,
        ann_file=data_root + 'annotations/instances_jietou_train20231016.json',
        img_prefix=data_root + 'train/',
        pipeline=train_pipeline,
        classes=classes
        ),
    val=dict(
        type=dataset_type,
        ann_file=data_root + 'annotations/instances_jietou_val20231016.json',
        img_prefix=data_root + 'val/',
        pipeline=test_pipeline,
        classes=classes
        ),
    test=dict(
        type=dataset_type,
        ann_file=data_root + 'annotations/instances_jietou_val20231016.json',
        img_prefix=data_root + 'val/',
        pipeline=test_pipeline,
        classes=classes
        ),
    )
evaluation = dict(
                    interval=10,   
                    metric=['bbox', 'segm']
                    )

优化器和学习率的配置

使用随机梯度下降法来更新参数,修改学习率的优化策略为warmup+余弦衰减策略。

# optimizer
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)

# Learning rate scheduler config used to register LrUpdater hook
lr_config = dict(
    policy='CosineAnnealing', 
    min_lr=0,
    warmup='linear',
    warmup_iters=25,
    warmup_ratio=0.001,
    warmup_by_epoch=True
)
total_epochs = 150

runtime配置

修改权重保存间隔为5个epoch保存一次。

checkpoint_config = dict(interval=5)
# yapf:disable
log_config = dict(
    interval=1,
    hooks=[
        dict(type='TextLoggerHook'),
        # dict(type='TensorboardLoggerHook')
    ])
# yapf:enable
dist_params = dict(backend='nccl')
log_level = 'INFO'
load_from = None
resume_from = None
workflow = [('train', 1)]

训练

通过运行如下命令,即可开启Mask R-CNN的训练。

CUDA_VISIBLE_DEVICES=4,5,6,7 \
bash tools/dist_train.sh configs/aaaa/mask_rcnn_r50_fpn_custom.py 4

测试

通过运行test.py文件,来开启单GPU的测试,命令如下。

python tools/test.py /path/to/config_file /path/to/checkpoint_file --eval bbox segm

常见问题

Q1:oserror: [errno 39] directory not empty "eval_hook"

通过注释mmdet/core/evaluation/eval_hooks.py文件中的tmpdir内容,具体操作是将multi_gpu_test函数中的tmpdir设置为None。

results = multi_gpu_test(
    runner.model,
    self.dataloader,
    # tmpdir=tmpdir,
    tmpdir=None,
    gpu_collect=self.gpu_collect)

参考链接

【实例分割(一)】Detectron2 数据集制作并注册数据集训练 - 古月居
【实例分割(二)】Mask2Former 数据集制作和训练 - 古月居
【深度学习】YOLOv5实例分割 数据集制作、模型训练以及TensorRT部署
利用labelme制作实例分割数据集_labelme实例分割_Jiazhou_garland的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1110517.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

纳米软件干货分享|芯片测试技术知识科普

芯片测试是确保芯片在各种条件下能够正常工作的关键环节。测试人员对芯片进行各种性能和可靠性的检测,以确保产品达到预期的性能指标和可靠性标准。 一、芯片测试的目的 芯片测试的主要目的是在投入应用之前发现和纠正芯片的潜在问题,防止不良品流入客…

c++_learning-对象模型探索

c对象模型探索 深入理解面向对象:c类对象模型:类中的成员:对象的内存大小:类对象内存的组成:不在对象内存中存放的成员: 类与类对象的内存分配:数据部分和代码部分:类对象占用的内存…

Verilog基础:避免混合使用阻塞和非阻塞赋值

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 “避免在一个always块中混杂阻塞赋值和非阻塞赋值”,这条原则是著名的Verilog专家Cliff Cummings在论文SUNG2000中提出的,这个观点在公众讨…

【AWS】亚马逊云的使用

现已推出预览版 — Amazon SageMaker Studio Lab,一项具有机器学习 (ML) 功能的免费学习和实验服务

公网使用PLSQL远程连接Oracle数据库【内网穿透】

🎬 鸽芷咕:个人主页 🔥 个人专栏:《速学数据结构》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址…

2.2.2 交换机间相同vlan的通信

实验2.2.2 交换机间相同vlan的通信 一、任务描述二、任务分析三、实验拓扑四、具体要求五、任务实施1.设置交换机的名称,创建VLAN,配置access并分配接口。对两台交换机进行相同的VLAN划分,下面是SWA配置过程,同理可实现SWB的配置。…

低代码源代码交付的平台有哪些?

一、前言 作为这两年IT界的风口,低代码在众人眼里已经不是什么陌生的概念。 对标于传统的纯代码开发,低代码是一种快速开发软件(应用程序)的方法,平台通过对大量功能与场景做提前封装,使得用户可以在可视化…

Flink学习笔记(三):Flink四种执行图

文章目录 1、Graph 的概念2、Graph 的演变过程2.1、StreamGraph (数据流图)2.2、JobGraph (作业图)2.3、ExecutionGraph (执行图)2.4、Physical Graph (物理图) 1、Graph 的概念 Flink 中的执行图可以分成四层:StreamGraph -> JobGraph -> ExecutionGraph -&g…

2023年下半年软考机考考试时间批次安排

中国计算机技术职业资格网发布了关于2023年下半年计算机技术与软件专业技术资格(水平)考试批次安排的通告,2023年下半年软考机考考试时间批次安排详见正文。 原文如下: 按照《2023年下半年计算机技术与软件专业技术资格&#xff…

2023年中国酒类新零售行业发展概况分析:线上线下渠道趋向深度融合[图]

近年来,我国新零售业态不断发展,线上便捷性和个性化推荐的优势逐步在放大,线下渠道智慧化水平持续提升,线上线下渠道趋向深度融合。2022年,我国酒类新零售市场规模约为1516亿元,预计2025年酒类新零售市场规…

STM32的hex文件格式的分析

前言 最近研究Bootloader,通过串口实现STM32程序的更新。需要学习了解STM32的Hex文件格式。在这进行一下总结。 HEX文件格式 我们通过文本形式打开hex文件,可以看到: 这一行就是一条指令数据,这里对数据帧格式进行说明&#xff…

c++_learning-模板与泛型编程

模板与泛型编程 模板概念、函数模板定义、调用:各种函数:替换失败不是一个错误SFINAE(substitution failure is not an error):由来:特性: *c11引入的类模板enable_if,体现了SFINAE的…

Hive安装配置 - 内嵌模式

文章目录 一、Hive运行模式二、安装配置内嵌模式Hive(一)下载hive安装包(二)上传hive安装包(三)解压缩hive安装包(四)配置hive环境变量(五)关联Hadoop&#x…

电容元件符号与工作原理:电子电路中的电荷储存利器 | 百能云芯

电容是电子电路中常见的元件之一,它具有储存电荷的能力。在电路图中,电容有一个特定的元件符号,用于表示其存在和连接方式。接下来,云芯带您深入了解电容的元件符号以及它的工作原理。 电容的元件符号通常由两个平行的线段组成&am…

基于CNN实现谣言检测 - python 深度学习 机器学习 计算机竞赛

文章目录 1 前言1.1 背景 2 数据集3 实现过程4 CNN网络实现5 模型训练部分6 模型评估7 预测结果8 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于CNN实现谣言检测 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐&am…

【第24例】华为 IPD 体系 | RMT 需求管理团队

目录 简介 内容 相关内容推荐(CSDN学院) 作者简介 简介 需求管理团队RMT是英文Requirement Management Team首字母的简称。 细分的话还包括: PL-RMT(产品线需求管理团队,Product Lin

使用Portainer图形化工具轻松管理远程Docker环境并实现远程访问

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 Portainer 是一个轻量级的容器管理工具,可以通过 Web 界面对 Docker 容器进行管理和监控。它提供了可…

【神印王座】伊莱克斯正式登场,皓晨通过永恒试炼,喜提两外挂,采儿丧失四感

Hello,小伙伴们,我是小郑继续为大家深度解析国漫资讯。 神印王座动画更新,龙皓晨在雅婷与皓月的帮助下,两次探索悲啸洞穴后成功闯入永恒之塔。在第78集预告中,伊莱克斯闪亮登场,皓晨通过永恒试炼成为新一代死灵圣法师&…

纯函数 和 函数柯里化 ( 函数式编程 )05

加油,今天周二啦!😍 文章目录 一、js 的纯函数二、JavaScript 柯里化三、柯里化作用四、将多个普通的函数,自动转成柯里化函数五、理解组合函数 一、js 的纯函数 函数式编程中有一个非常重要的概念叫纯函数,JavaScript…

C++设计模式_08_Factory Method工厂方法模式

文章目录 1. “对象创建模式”模式1.1 典型模式 2. 动机(Motivation)3. 代码演示Factory Method工厂方法模式3.1 常规方法3.2 面向接口的编程3.2.1 FileSplitter1.cpp3.2.2 MainForm1.cpp 3.3 Factory Method工厂方法3.3.1 ISplitterFactory.cpp3.3.2 Ma…