detectron2训练自己的数据集和转coco格式

2023-05-16

参考

关于coco的格式
https://detectron2.readthedocs.io/en/latest/tutorials/datasets.html#register-a-dataset

注册并训练自己的数据集合https://blog.csdn.net/qq_29750461/article/details/106761382

https://cloud.tencent.com/developer/article/1960793
coco api https://blog.csdn.net/qq_41709370/article/details/108471072

注意这里如果出现说自己的数据没有注册的错误,需要在main里面加上函数plain_register_dataset()注册自己的数据集
在这里插入图片描述

数据转换成coco格式

一些坑:

  • bbox对于coco格式来说[x,y,width,height] x,y是左上角的坐标

  • file_name是图片的绝对路径 要写成xxx.jpg

  • 有些coco文件里说不是必须的字段但是如果没有会报keyerror
    anntations里比如area、iscrowd 可以设置默认值 area可以是bbox的w*h

  • 读取图片shape[0]是height shape[1]是witdh

height = img.shape[0]
width = img.shape[1]

注册数据集

#!/usr/bin/env python
# Copyright (c) Facebook, Inc. and its affiliates.
"""
A main training script.

This scripts reads a given config file and runs the training or evaluation.
It is an entry point that is made to train standard models in detectron2.

In order to let one script support training of many models,
this script contains logic that are specific to these built-in models and therefore
may not be suitable for your own project.
For example, your research project perhaps only needs a single "evaluator".

Therefore, we recommend you to use detectron2 as an library and take
this file as an example of how to use the library.
You may want to write your own script with your datasets and other customizations.
"""

import logging
import os
from collections import OrderedDict

import cv2
from detectron2.utils.visualizer import Visualizer

import detectron2.utils.comm as comm
from detectron2.checkpoint import DetectionCheckpointer
from detectron2.config import get_cfg
from detectron2.data import MetadataCatalog
from detectron2.engine import DefaultTrainer, default_argument_parser, default_setup, hooks, launch
from detectron2.evaluation import (
    CityscapesInstanceEvaluator,
    CityscapesSemSegEvaluator,
    COCOEvaluator,
    COCOPanopticEvaluator,
    DatasetEvaluators,
    LVISEvaluator,
    PascalVOCDetectionEvaluator,
    SemSegEvaluator,
    verify_results,
)
from detectron2.modeling import GeneralizedRCNNWithTTA

from detectron2.data import DatasetCatalog, MetadataCatalog
from detectron2.data.datasets.coco import load_coco_json
import pycocotools
#声明类别,尽量保持
CLASS_NAMES =["background", "military"]
# 数据集路径
DATASET_ROOT = '/home/szr/new_dete/detectron2/datasets'
ANN_ROOT = os.path.join(DATASET_ROOT, 'COCOformat')

TRAIN_PATH = os.path.join(DATASET_ROOT, 'JPEGImages')
VAL_PATH = os.path.join(DATASET_ROOT, 'JPEGImages')

TRAIN_JSON = os.path.join(ANN_ROOT, 'train.json')
VAL_JSON = os.path.join(ANN_ROOT, 'val.json')
# VAL_JSON = os.path.join(ANN_ROOT, 'test.json')

# 声明数据集的子集
PREDEFINED_SPLITS_DATASET = {
    "coco_my_train": (TRAIN_PATH, TRAIN_JSON),
    "coco_my_val": (VAL_PATH, VAL_JSON),
}
#===========以下有两种注册数据集的方法,本人直接用的第二个plain_register_dataset的方式 也可以用register_dataset的形式==================
#注册数据集(这一步就是将自定义数据集注册进Detectron2)

# 注册数据集和元数据
def plain_register_dataset():
    #训练集
    DatasetCatalog.register("coco_my_train", lambda: load_coco_json(TRAIN_JSON, TRAIN_PATH))
    MetadataCatalog.get("coco_my_train").set(thing_classes=CLASS_NAMES,  # 可以选择开启,但是不能显示中文,这里需要注意,中文的话最好关闭
                                                    evaluator_type='coco', # 指定评估方式
                                                    json_file=TRAIN_JSON,
                                                    image_root=TRAIN_PATH)

    #DatasetCatalog.register("coco_my_val", lambda: load_coco_json(VAL_JSON, VAL_PATH, "coco_2017_val"))
    #验证/测试集
    DatasetCatalog.register("coco_my_val", lambda: load_coco_json(VAL_JSON, VAL_PATH))
    MetadataCatalog.get("coco_my_val").set(thing_classes=CLASS_NAMES, # 可以选择开启,但是不能显示中文,这里需要注意,中文的话最好关闭
                                                evaluator_type='coco', # 指定评估方式
                                                json_file=VAL_JSON,
                                                image_root=VAL_PATH)


# 查看数据集标注,可视化检查数据集标注是否正确,
#这个也可以自己写脚本判断,其实就是判断标注框是否超越图像边界
#可选择使用此方法
def checkout_dataset_annotation(name="coco_my_val"):
    #dataset_dicts = load_coco_json(TRAIN_JSON, TRAIN_PATH, name)
    dataset_dicts = load_coco_json(TRAIN_JSON, TRAIN_PATH)
    print(len(dataset_dicts))
    for i, d in enumerate(dataset_dicts,0):
        #print(d)
        img = cv2.imread(d["file_name"])
        visualizer = Visualizer(img[:, :, ::-1], metadata=MetadataCatalog.get(name), scale=1.5)
        vis = visualizer.draw_dataset_dict(d)
        #cv2.imshow('show', vis.get_image()[:, :, ::-1])
        cv2.imwrite('out/'+str(i) + '.jpg',vis.get_image()[:, :, ::-1])
        #cv2.waitKey(0)
        if i == 200:
            break


def build_evaluator(cfg, dataset_name, output_folder=None):
    """
    Create evaluator(s) for a given dataset.
    This uses the special metadata "evaluator_type" associated with each builtin dataset.
    For your own dataset, you can simply create an evaluator manually in your
    script and do not have to worry about the hacky if-else logic here.
    """
    if output_folder is None:
        output_folder = os.path.join(cfg.OUTPUT_DIR, "inference")
    evaluator_list = []
    evaluator_type = MetadataCatalog.get(dataset_name).evaluator_type
    if evaluator_type in ["sem_seg", "coco_panoptic_seg"]:
        evaluator_list.append(
            SemSegEvaluator(
                dataset_name,
                distributed=True,
                output_dir=output_folder,
            )
        )
    if evaluator_type in ["coco", "coco_panoptic_seg"]:
        evaluator_list.append(COCOEvaluator(dataset_name, output_dir=output_folder))
    if evaluator_type == "coco_panoptic_seg":
        evaluator_list.append(COCOPanopticEvaluator(dataset_name, output_folder))
    if evaluator_type == "cityscapes_instance":
        return CityscapesInstanceEvaluator(dataset_name)
    if evaluator_type == "cityscapes_sem_seg":
        return CityscapesSemSegEvaluator(dataset_name)
    elif evaluator_type == "pascal_voc":
        return PascalVOCDetectionEvaluator(dataset_name)
    elif evaluator_type == "lvis":
        return LVISEvaluator(dataset_name, output_dir=output_folder)
    if len(evaluator_list) == 0:
        raise NotImplementedError(
            "no Evaluator for the dataset {} with the type {}".format(dataset_name, evaluator_type)
        )
    elif len(evaluator_list) == 1:
        return evaluator_list[0]
    return DatasetEvaluators(evaluator_list)


class Trainer(DefaultTrainer):
    """
    We use the "DefaultTrainer" which contains pre-defined default logic for
    standard training workflow. They may not work for you, especially if you
    are working on a new research project. In that case you can write your
    own training loop. You can use "tools/plain_train_net.py" as an example.
    """

    @classmethod
    def build_evaluator(cls, cfg, dataset_name, output_folder=None):
        return build_evaluator(cfg, dataset_name, output_folder)

    @classmethod
    def test_with_TTA(cls, cfg, model):
        logger = logging.getLogger("detectron2.trainer")
        # In the end of training, run an evaluation with TTA
        # Only support some R-CNN models.
        logger.info("Running inference with test-time augmentation ...")
        model = GeneralizedRCNNWithTTA(cfg, model)
        evaluators = [
            cls.build_evaluator(
                cfg, name, output_folder=os.path.join(cfg.OUTPUT_DIR, "inference_TTA")
            )
            for name in cfg.DATASETS.TEST
        ]
        res = cls.test(cfg, model, evaluators)
        res = OrderedDict({k + "_TTA": v for k, v in res.items()})
        return res


# def setup(args):
#     """
#     Create configs and perform basic setups.
#     """
#     # cfg = get_cfg()
#     # cfg.merge_from_file(args.config_file)
#     # cfg.merge_from_list(args.opts)
#     # cfg.freeze()
#     # default_setup(cfg, args)
#     # return cfg

def setup(args):
    """
    Create configs and perform basic setups.
    """
    cfg = get_cfg()
    args.config_file = "/home/szr/new_dete/detectron2/configs/COCO-Detection/retinanet_R_50_FPN_3x.yaml"
    cfg.merge_from_file(args.config_file)  # 从config file 覆盖配置
    cfg.merge_from_list(args.opts)  # 从CLI参数 覆盖配置

    # 更改配置参数
    cfg.DATASETS.TRAIN = ("coco_my_train",)  # 训练数据集名称
    cfg.DATASETS.TEST = ("coco_my_val",)
    cfg.DATALOADER.NUM_WORKERS = 4  # 单线程

    cfg.INPUT.CROP.ENABLED = True
    cfg.INPUT.MAX_SIZE_TRAIN = 640  # 训练图片输入的最大尺寸
    cfg.INPUT.MAX_SIZE_TEST = 640  # 测试数据输入的最大尺寸
    cfg.INPUT.MIN_SIZE_TRAIN = (512, 768)  # 训练图片输入的最小尺寸,可以设定为多尺度训练
    cfg.INPUT.MIN_SIZE_TEST = 640
    # cfg.INPUT.MIN_SIZE_TRAIN_SAMPLING,其存在两种配置,分别为 choice 与 range :
    # range 让图像的短边从 512-768随机选择
    # choice : 把输入图像转化为指定的,有限的几种图片大小进行训练,即短边只能为 512或者768
    cfg.INPUT.MIN_SIZE_TRAIN_SAMPLING = 'range'
    #  本句一定要看下注释!!!!!!!!
    cfg.MODEL.RETINANET.NUM_CLASSES = 2  # 类别数+1(因为有background,也就是你的 cate id 从 1 开始,如果您的数据集Json下标从 0 开始,这个改为您对应的类别就行,不用再加背景类!!!!!)
    # cfg.MODEL.WEIGHTS="/home/yourstorePath/.pth"
    #这个地址可以自己下载或者它会自己联网下载
    cfg.MODEL.WEIGHTS = "detectron2://COCO-Detection/retinanet_R_50_FPN_3x/190397829/model_final_5bd44e.pkl"  # 预训练模型权重
    cfg.SOLVER.IMS_PER_BATCH = 4  # batch_size=2; iters_in_one_epoch = dataset_imgs/batch_size

    # 根据训练数据总数目以及batch_size,计算出每个epoch需要的迭代次数
    # 9000为你的训练数据的总数目,可自定义
    ITERS_IN_ONE_EPOCH = int(1120 / cfg.SOLVER.IMS_PER_BATCH)

    # 指定最大迭代次数
    cfg.SOLVER.MAX_ITER = (ITERS_IN_ONE_EPOCH * 12) - 1  # 12 epochs,
    # 初始学习率
    cfg.SOLVER.BASE_LR = 0.002
    # 优化器动能
    cfg.SOLVER.MOMENTUM = 0.9
    # 权重衰减
    cfg.SOLVER.WEIGHT_DECAY = 0.0001
    cfg.SOLVER.WEIGHT_DECAY_NORM = 0.0
    # 学习率衰减倍数
    cfg.SOLVER.GAMMA = 0.1
    # 迭代到指定次数,学习率进行衰减
    cfg.SOLVER.STEPS = (7000,)
    # 在训练之前,会做一个热身运动,学习率慢慢增加初始学习率
    cfg.SOLVER.WARMUP_FACTOR = 1.0 / 1000
    # 热身迭代次数
    cfg.SOLVER.WARMUP_ITERS = 1000

    cfg.SOLVER.WARMUP_METHOD = "linear"
    # 保存模型文件的命名数据减1
    cfg.SOLVER.CHECKPOINT_PERIOD = ITERS_IN_ONE_EPOCH - 1

    # 迭代到指定次数,进行一次评估
    cfg.TEST.EVAL_PERIOD = ITERS_IN_ONE_EPOCH
    # cfg.TEST.EVAL_PERIOD = 100

    # cfg.merge_from_file(args.config_file)
    # cfg.merge_from_list(args.opts)
    cfg.freeze()
    default_setup(cfg, args)
    return cfg


def main(args):
    cfg = setup(args)

    if args.eval_only:
        model = Trainer.build_model(cfg)
        DetectionCheckpointer(model, save_dir=cfg.OUTPUT_DIR).resume_or_load(
            cfg.MODEL.WEIGHTS, resume=args.resume
        )
        res = Trainer.test(cfg, model)
        if cfg.TEST.AUG.ENABLED:
            res.update(Trainer.test_with_TTA(cfg, model))
        if comm.is_main_process():
            verify_results(cfg, res)
        return res

    """
    If you'd like to do anything fancier than the standard training logic,
    consider writing your own training loop (see plain_train_net.py) or
    subclassing the trainer.
    """
    trainer = Trainer(cfg)
    trainer.resume_or_load(resume=args.resume)
    if cfg.TEST.AUG.ENABLED:
        trainer.register_hooks(
            [hooks.EvalHook(0, lambda: trainer.test_with_TTA(cfg, trainer.model))]
        )
    return trainer.train()


if __name__ == "__main__":
    args = default_argument_parser().parse_args()
    plain_register_dataset()
    print("Command Line Args:", args)
    launch(
        main,
        args.num_gpus,
        num_machines=args.num_machines,
        machine_rank=args.machine_rank,
        dist_url=args.dist_url,
        args=(args,),
    )


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

detectron2训练自己的数据集和转coco格式 的相关文章

随机推荐

  • iOS开发常用加密

    Https加密流程详见博主Https加密流程第十条 其他常用加密方式 一 Base64 Base64加密原理 xff1a 1 原本数据一个字符为8bit xff0c 每3个字符为一组 xff0c 即 xff1a 3 8 2 编码过程中 xf
  • iOS开发细碎知识点总结二

    struct和class的区别 我们先了解栈和堆的区别 1 栈的特点 分配空间小 但是存在栈上的数据访问效率高 2 堆的特点 分配空间相对较大 但是数据访问相对于栈 效率底下 swift中struct与的class的区别 1 class是引
  • iOS开发之相册

    需求一 xff1a 简单的选择一张图片 在iOS开发中如果要调用相机拍取照片或者是直接获取相册中的照片 xff0c 那么调用UIImagePickerController是个不错的选择 UIImagePickerController继承于U
  • 一个小白对微信小程序的理解

    一 小程序开发框架组成介绍 首先介绍一个小程序宿主环境差异 xff0c 其中iOS是基于JavaScriptCore xff0c Android是基于X5内核 xff0c IDE是基于nwjs 1 WXML xff08 WeiXin Mar
  • 池塘里有4只鸭子,4只鸭子在同半圆中的概率(C语言版)

    将原来你是小幸运大佬的Python版代码改写为C语言版代码 xff0c 作为新手练习 原文链接如下 xff1a 4只鸭子在同一个圆圈内游泳 xff0c 问 xff1a 4只鸭子出现在同一个半圆内的概率是多少 xff1f Python解答 原
  • VirtualBox上安装ArchLinux步骤整理

    粗体 xff08 一 xff09 系统安装 从archlinux官网下载linux镜像 xff1a archlinux 2016 12 01 dual iso在virtualbox中加载镜像启动 xff0c 进入root cd dev 下
  • 数据结构设计题大题总结(非代码)

    文章目录 二叉树二叉树遍历孩子兄弟表示法平衡二叉树旋转过程哈夫曼树的构造森林 树与二叉树互转 图邻接矩阵 邻接表与图图的深度搜索与广度搜索Prim算法与Kruskal算法最短路径与AOE网 xff08 Activity on edge ne
  • 轻松通关Flink第24讲:Flink 消费 Kafka 数据业务开发

    在上一课时中我们提过在实时计算的场景下 xff0c 绝大多数的数据源都是消息系统 xff0c 而 Kafka 从众多的消息中间件中脱颖而出 xff0c 主要是因为高吞吐 低延迟的特点 xff1b 同时也讲了 Flink 作为生产者像 Kaf
  • 痛苦的ubuntu 18.043

    文章目录 添加驱动源使用TAB键查看能安装的驱动版本号 刚开始就进不去桌面 xff0c 然后看了教程得在在quite splash 加 nomodeset才能关闭显卡进入桌面 进了系统之后还是跟着https blog csdn net ne
  • Tbox(Can转Tcp),支持有线连接和4G无线连接两种方式

    本司Tbox有如下优点 xff1a 1 支持Can工作模式的远程配置包括波特率 帧类型 过滤ID设置 xff1b 2 tcp支持以太网和无线两种方式 xff0c 无线支持多种网络制式 xff1b 3 采用cotex A7内核处理器 xff0
  • SQL复习

    like 字符匹配 1 xff1a 匹配一个字符 例如 xff1a 查找姓张且名字为三个字的学生信息 select from student where name like 张 2 xff1a 匹配0个或多个字符串 例如 xff1a 查找姓
  • 回溯-切割问题:分割回文串/复原IP地址

    131分割回文串 在代码里什么是切割线呢 xff1f 递归参数需要传入startIndex xff0c 表示下一轮递归遍历的起始位置 xff0c 这个startIndex就是切割线 span class token keyword clas
  • 回溯-子集问题/子集I II/递增子序列

    78 子集 span class token keyword class span span class token class name Solution span span class token punctuation span sp
  • 回溯-排列问题/全排列I II

    46 全排列 这里和77 组合问题 opens new window 131 切割问题 opens new window 和78 子集问题 opens new window 最大的不同就是for循环里不用startIndex了 因为排列问题
  • 自然语言处理中的预训练模型-邱锡鹏老师

    自然语言处理中的预训练模型 视频地址 https www bilibili com video av883626347 参考https blog csdn net qq 37388085 article details 108463269
  • 二叉树-构建二叉树:中后序构建二叉树/前中序构建二叉树/最大二叉树/合并二叉树/二叉搜索树/最近公共祖先/

    前中 中后可以确定唯一二叉树 xff0c 前后不可以 因为没有中序遍历无法确定左右部分 xff0c 也就是无法分割 106 从中序与后序遍历序列构造二叉树 思路 xff1a 说到一层一层切割 xff0c 就应该想到了递归 来看一下一共分几步
  • 【zipfile】Python实现将文件打包为zip压缩包 & 解压

    用Python将文件进行压缩 xff0c 可以使用 zipfile库 xff0c 提供了非常丰富的API zipfile本身是上下文管理器 xff0c 可以使用with 以下为自己简单写的Demo 打包 span class token k
  • 动态规划:斐波那契数,爬楼梯,不同路径,整数拆分,不同二叉树

    基础 很多重叠子问题 xff0c 动态规划中每一个状态一定是由上一个状态推导出来的 xff0c 这一点就区分于贪心 xff0c 贪心没有状态推导 xff0c 而是从局部直接选最优的 1确定dp数组 xff08 dp table xff09
  • 负数+0+正数

    一堆负数 43 一堆0 43 一堆正数 找最后一个出现的负数和第一个出现的正数的下标 下标从1开始 果然没运行看不出哪里错了 555 span class token keyword def span span class token fu
  • detectron2训练自己的数据集和转coco格式

    参考 关于coco的格式 https detectron2 readthedocs io en latest tutorials datasets html register a dataset 注册并训练自己的数据集合https blog