【detectron2】注册、训练、推断自己的数据集

2023-10-27

一、注册自己的数据集

使用detectron2训练自己的数据集,第一步要注册自己的数据集。

  1. 首先保证自己的数据集标注是coco格式,就可以使用load_coco_json加载自己的数据集并转化为detectron2的专有数据格式。
  2. 使用DatasetCatalog.register注册训练集和测试集。
  3. 使用MetadataCatalog.get注册训练集和测试集的标注元数据

要纠结代码细节,具体注册数据集的逻辑思路参见下面几个函数,细节自己细品。

data/datasets/buildin.py/register_all_coco(root="datasets") 
data/datasets/buildin_meta.py/_get_builtin_metadata(dataset_name) 
data/datasets/buildin_meta.py/_get_coco_instances_meta() 
data/datasets/register_coco.py/register_coco_instances(name, metadata, json_file, image_root)
data/datasets/coco.py/load_coco_json(json_file, image_root, dataset_name=None, extra_annotation_keys=None)

直接上代码

from detectron2.data import DatasetCatalog, MetadataCatalog
from detectron2.data.datasets.coco import load_coco_json

DatasetCatalog.register("dataset_train", lambda: load_coco_json(TRAIN_JSON, TRAIN_PATH, "dataset_train"))
MetadataCatalog.get("dataset_train").set(thing_classes=["pos", "neg"],
                                                    json_file=TRAIN_JSON,
                                                    image_root=TRAIN_PATH)
DatasetCatalog.register("dataset_val", lambda: load_coco_json(VAL_JSON, VAL_PATH, "dataset_val"))
MetadataCatalog.get("dataset_val").set(thing_classes=["pos", "neg"],
                                                json_file=VAL_JSON,
                                                image_root=VAL_PATH)

二、训练自己的数据集

  1. 在官方的tools/train_net.py上加上注册数据集部分
  2. 继承DefaultTrainer父类,定义Trainer,重写build_evaluator类方法,使得Trainer具有评估功能。
class Trainer(DefaultTrainer):
    @classmethod
    def build_evaluator(cls, cfg, dataset_name, output_folder=None):
        if output_folder is None:
            output_folder = os.path.join(cfg.OUTPUT_DIR, "inference")
        return COCOEvaluator(dataset_name, cfg, distributed=False, output_dir=output_folder)

detectron2的训练器框架,具体细节可通过F12查看DefaultTrainer的父类SimpleTrainer的父类TrainerBase。是一个从抽像到具象的过程,通过重写父类方法累加功能。

我的训练脚本(包含注册数据集)

import os
import cv2
import logging
from collections import OrderedDict

import detectron2.utils.comm as comm
from detectron2.utils.visualizer import Visualizer
from detectron2.checkpoint import DetectionCheckpointer
from detectron2.config import get_cfg
from detectron2.data import DatasetCatalog, MetadataCatalog
from detectron2.data.datasets.coco import load_coco_json
from detectron2.engine import DefaultTrainer, default_argument_parser, default_setup, launch
from detectron2.evaluation import COCOEvaluator, verify_results
from detectron2.modeling import GeneralizedRCNNWithTTA


# 数据集路径
DATASET_ROOT = '/home/Documents/Datasets'
ANN_ROOT = os.path.join(DATASET_ROOT, 'annotations')
TRAIN_PATH = os.path.join(DATASET_ROOT, 'train')
VAL_PATH = os.path.join(DATASET_ROOT, 'val')
TRAIN_JSON = os.path.join(ANN_ROOT, 'train.json')
VAL_JSON = os.path.join(ANN_ROOT, 'val.json')


# 数据集类别元数据
DATASET_CATEGORIES = [
    {"name": "pos", "id": 1, "isthing": 1, "color": [220, 20, 60]},
    {"name": "neg", "id": 2, "isthing": 1, "color": [219, 142, 185]},
]


# 数据集的子集
PREDEFINED_SPLITS_DATASET = {
    "train_2019": (TRAIN_PATH, TRAIN_JSON),
    "val_2019": (VAL_PATH, VAL_JSON),
}


def register_dataset():
    """
    purpose: register all splits of dataset with PREDEFINED_SPLITS_DATASET
    """
    for key, (image_root, json_file) in PREDEFINED_SPLITS_DATASET.items():
        register_dataset_instances(name=key, 
                                   metadate=get_dataset_instances_meta(), 
                                   json_file=json_file, 
                                   image_root=image_root)


def get_dataset_instances_meta():
    """
    purpose: get metadata of dataset from DATASET_CATEGORIES
    return: dict[metadata]
    """
    thing_ids = [k["id"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    thing_colors = [k["color"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    # assert len(thing_ids) == 2, len(thing_ids)
    thing_dataset_id_to_contiguous_id = {k: i for i, k in enumerate(thing_ids)}
    thing_classes = [k["name"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    ret = {
        "thing_dataset_id_to_contiguous_id": thing_dataset_id_to_contiguous_id,
        "thing_classes": thing_classes,
        "thing_colors": thing_colors,
    }
    return ret


def register_dataset_instances(name, metadate, json_file, image_root):
    """
    purpose: register dataset to DatasetCatalog,
             register metadata to MetadataCatalog and set attribute
    """
    DatasetCatalog.register(name, lambda: load_coco_json(json_file, image_root, name))
    MetadataCatalog.get(name).set(json_file=json_file, 
                                  image_root=image_root, 
                                  evaluator_type="coco", 
                                  **metadate)


# 注册数据集和元数据
def plain_register_dataset():
    DatasetCatalog.register("train_2019", lambda: load_coco_json(TRAIN_JSON, TRAIN_PATH, "train_2019"))
    MetadataCatalog.get("train_2019").set(thing_classes=["pos", "neg"],
                                                    json_file=TRAIN_JSON,
                                                    image_root=TRAIN_PATH)
    DatasetCatalog.register("val_2019", lambda: load_coco_json(VAL_JSON, VAL_PATH, "val_2019"))
    MetadataCatalog.get("val_2019").set(thing_classes=["pos", "neg"],
                                                json_file=VAL_JSON,
                                                image_root=VAL_PATH)


# 查看数据集标注
def checkout_dataset_annotation(name="val_2019"):
    dataset_dicts = load_coco_json(TRAIN_JSON, TRAIN_PATH, name)
    for d in dataset_dicts:
        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.waitKey(0)


class Trainer(DefaultTrainer):
    @classmethod
    def build_evaluator(cls, cfg, dataset_name, output_folder=None):
        if output_folder is None:
            output_folder = os.path.join(cfg.OUTPUT_DIR, "inference")
        return COCOEvaluator(dataset_name, cfg, distributed=False, output_dir=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() # 拷贝default config副本
    args.config_file = "configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml"
    cfg.merge_from_file(args.config_file)   # 从config file 覆盖配置
    cfg.merge_from_list(args.opts)          # 从CLI参数 覆盖配置

    # 更改配置参数
    cfg.DATASETS.TRAIN = ("train_2019",)
    cfg.DATASETS.TEST = ("val_2019",)
    cfg.DATALOADER.NUM_WORKERS = 0  # 单线程
    cfg.INPUT.MAX_SIZE_TRAIN = 400
    cfg.INPUT.MAX_SIZE_TEST = 400
    cfg.INPUT.MIN_SIZE_TRAIN = (160,)
    cfg.INPUT.MIN_SIZE_TEST = 160
    cfg.MODEL.ROI_HEADS.NUM_CLASSES = 2 # 类别数
    cfg.MODEL.WEIGHTS = "/homeDocuments/pretrainedModel/Detectron2/R-50.pkl"    # 预训练模型权重
    cfg.SOLVER.IMS_PER_BATCH = 2  # batch_size=2; iters_in_one_epoch = dataset_imgs/batch_size  
    ITERS_IN_ONE_EPOCH = int(1434 / 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 = (30000,)
    cfg.SOLVER.WARMUP_FACTOR = 1.0 / 1000
    cfg.SOLVER.WARMUP_ITERS = 1000
    cfg.SOLVER.WARMUP_METHOD = "linear"
    cfg.SOLVER.CHECKPOINT_PERIOD = ITERS_IN_ONE_EPOCH - 1

    cfg.freeze()
    default_setup(cfg, args)
    return cfg


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

    # 注册数据集
    register_dataset()

    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 comm.is_main_process():
            verify_results(cfg, res)
        return res

    trainer = Trainer(cfg)
    trainer.resume_or_load(resume=args.resume)
    return trainer.train()


if __name__ == "__main__":
    args = default_argument_parser().parse_args()
    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,),
    )

三、推断数据

推断数据的脚本是根据官方的demo.py改的。
在推断之前,也是要注册自己的数据集。
我的推断脚本

import argparse
import glob
import multiprocessing as mp
import os
import time
import cv2
import tqdm

from detectron2.config import get_cfg
from detectron2.data import MetadataCatalog, DatasetCatalog
from detectron2.data.datasets import load_coco_json
from detectron2.data.detection_utils import read_image
from detectron2.utils.logger import setup_logger
from detectron2.utils.visualizer import ColorMode
from demo.predictor import VisualizationDemo

# constants
WINDOW_NAME = "detections"

# inference
INPUT_IMG_PATH = '/home/Documents/mask_THzDatasets/val'
OUTPUT_IMG_PATH = '/home/Documents/out'

# 数据集路径
DATASET_ROOT = '/home/Documents/Datasets'
ANN_ROOT = os.path.join(DATASET_ROOT, 'annotations')
TRAIN_PATH = os.path.join(DATASET_ROOT, 'train')
VAL_PATH = os.path.join(DATASET_ROOT, 'val')
TRAIN_JSON = os.path.join(ANN_ROOT, 'train.json')
VAL_JSON = os.path.join(ANN_ROOT, 'val.json')


# 数据集类别元数据
DATASET_CATEGORIES = [
    {"name": "pos", "id": 1, "isthing": 1, "color": [220, 20, 60]},
    {"name": "neg", "id": 2, "isthing": 1, "color": [219, 142, 185]},
]


# 数据集的子集
PREDEFINED_SPLITS_DATASET = {
    "train_2019": (TRAIN_PATH, TRAIN_JSON),
    "val_2019": (VAL_PATH, VAL_JSON),
}


def register_dataset():
    """
    purpose: register all splits of dataset with PREDEFINED_SPLITS_DATASET
    """
    for key, (image_root, json_file) in PREDEFINED_SPLITS_DATASET.items():
        register_dataset_instances(name=key, 
                                   metadate=get_dataset_instances_meta(), 
                                   json_file=json_file, 
                                   image_root=image_root)


def get_dataset_instances_meta():
    """
    purpose: get metadata of dataset from DATASET_CATEGORIES
    return: dict[metadata]
    """
    thing_ids = [k["id"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    thing_colors = [k["color"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    # assert len(thing_ids) == 2, len(thing_ids)
    thing_dataset_id_to_contiguous_id = {k: i for i, k in enumerate(thing_ids)}
    thing_classes = [k["name"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    ret = {
        "thing_dataset_id_to_contiguous_id": thing_dataset_id_to_contiguous_id,
        "thing_classes": thing_classes,
        "thing_colors": thing_colors,
    }
    return ret


def register_dataset_instances(name, metadate, json_file, image_root):
    """
    purpose: register dataset to DatasetCatalog,
             register metadata to MetadataCatalog and set attribute
    """
    DatasetCatalog.register(name, lambda: load_coco_json(json_file, image_root, name))
    MetadataCatalog.get(name).set(json_file=json_file, 
                                  image_root=image_root, 
                                  evaluator_type="coco", 
                                  **metadate)


# 注册数据集和元数据
def plain_register_dataset():
    DatasetCatalog.register("train_2019", lambda: load_coco_json(TRAIN_JSON, TRAIN_PATH, "train_2019"))
    MetadataCatalog.get("train_2019").set(thing_classes=["pos", "neg"],
                                                    json_file=TRAIN_JSON,
                                                    image_root=TRAIN_PATH)
    DatasetCatalog.register("val_2019", lambda: load_coco_json(VAL_JSON, VAL_PATH, "val_2019"))
    MetadataCatalog.get("val_2019").set(thing_classes=["pos", "neg"],
                                                json_file=VAL_JSON,
                                                image_root=VAL_PATH)


def setup_cfg(args):
    # load config from file and command-line arguments
    cfg = get_cfg()
    args.config_file = "configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml"
    cfg.merge_from_file(args.config_file)
    cfg.merge_from_list(args.opts)

    cfg.DATASETS.TRAIN = ("train_2019",)
    cfg.DATASETS.TEST = ("val_2019",)
    cfg.DATALOADER.NUM_WORKERS = 0  
    cfg.INPUT.MAX_SIZE_TRAIN = 400
    cfg.INPUT.MAX_SIZE_TEST = 400
    cfg.INPUT.MIN_SIZE_TRAIN = (160,)
    cfg.INPUT.MIN_SIZE_TEST = 160
    cfg.MODEL.ROI_HEADS.NUM_CLASSES = 2 # 类别数
    # cfg.MODEL.WEIGHTS = "/home/Documents/pretrainedModel/Detectron2/R-50.pkl"  # 预训练模型权重
    cfg.MODEL.WEIGHTS = '/home/anaconda3/envs/pytorch13/detectron2/output/model_final.pth'   # 最终权重
    cfg.SOLVER.IMS_PER_BATCH = 2  # batch_size=2; iteration = 1434/batch_size = 717 iters in one epoch
    ITERS_IN_ONE_EPOCH = int(1434 / 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 = (30000,)
    cfg.SOLVER.WARMUP_FACTOR = 1.0 / 1000
    cfg.SOLVER.WARMUP_ITERS = 1000
    cfg.SOLVER.WARMUP_METHOD = "linear"
    cfg.SOLVER.CHECKPOINT_PERIOD = ITERS_IN_ONE_EPOCH - 1

    cfg.freeze()
    return cfg


def get_parser():
    parser = argparse.ArgumentParser(description="Detectron2 Demo")
    parser.add_argument(
        "--config-file",
        default="configs/quick_schedules/e2e_mask_rcnn_R_50_FPN_inference_acc_test.yaml",
        metavar="FILE",
        help="path to config file",
    )
    parser.add_argument("--input", nargs="+", help="A list of space separated input images")
    parser.add_argument(
        "--output",
        help="A file or directory to save output visualizations. "
             "If not given, will show output in an OpenCV window.",
    )
    parser.add_argument(
        "--confidence-threshold",
        type=float,
        default=0.5,
        help="Minimum score for instance predictions to be shown",
    )
    parser.add_argument(
        "--opts",
        help="Modify config options using the command-line 'KEY VALUE' pairs",
        default=[],
        nargs=argparse.REMAINDER,
    )
    return parser


if __name__ == "__main__":
    mp.set_start_method("spawn", force=True)
    args = get_parser().parse_args()
    logger = setup_logger()
    logger.info("Arguments: " + str(args))

    cfg = setup_cfg(args)
    
    # 注册数据集
    register_dataset()
    
    demo = VisualizationDemo(cfg, instance_mode=ColorMode.SEGMENTATION)

    # for path in tqdm.tqdm(args.input, disable=not args.output):
    for imgfile in os.listdir(INPUT_IMG_PATH):

        # use PIL, to be consistent with evaluation
        img_fullName = os.path.join(INPUT_IMG_PATH, imgfile)
        img = read_image(img_fullName, format="BGR")
        start_time = time.time()
        predictions, visualized_output = demo.run_on_image(img)
        logger.info(
            "{}: detected {} instances in {:.2f}s".format(
                imgfile, len(predictions["instances"]), time.time() - start_time
            )
        )

        if args.output:
            if os.path.isdir(args.output):
                assert os.path.isdir(args.output), args.output
                out_filename = os.path.join(args.output, os.path.basename(imgfile))
            else:
                assert len(args.input) == 1, "Please specify a directory with args.output"
                out_filename = args.output
            visualized_output.save(out_filename)
        else:
            cv2.namedWindow(WINDOW_NAME, cv2.WINDOW_NORMAL)
            cv2.imshow(WINDOW_NAME, visualized_output.get_image()[:, :, ::-1])
            if cv2.waitKey(0) == 27:
                break  # esc to quit


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

【detectron2】注册、训练、推断自己的数据集 的相关文章

随机推荐

  • PI-撒币算法

    首先构造一个单位正方形和一个四分之一圆 然后假设你有一堆硬币 你开始随机对上述构造的正方形 撒币 当然这个硬币可能在圆里 也可能在圆外 只要你的硬币够多 那么你的硬币将构成1 4圆 通过计数其中落入内切圆的硬币的个数 有 如果一共投入a个硬
  • 【微信小程序】创建自定义组件

    文档地址 Component Object object 微信开放文档 视频地址 4 14 自定义组件Component的用法 哔哩哔哩 bilibili 基础 1 右键 gt 创建component文件夹 gt 创建component文件
  • conda虚拟环境安装pytorch+tensorboardX可视化工具

    安装要求 pytorch没有tensorflow那样具有tensorboard可视化工具 在pytorch中想要进行可视化可以调用tensorboardX 具体的调用与tensorboard类似 因此需要的安装包如下 1 pytorch 1
  • 蓝桥杯2022年第十三届JAVA B组省赛真题-最大子矩阵

    这题应该有更简单的方法做 本人太懒 直接暴力线段树 优先队列了 刚好卡时间过 include
  • DSP-滤波器稳定性与极点 &数字滤波器&TMS320C67XX dsp启动过程

    DSP技术 https www cnblogs com kanite category 1318278 html 滤波器稳定性与极点 在数字信号处理种 系统的稳定性是一个很重要的问题 比如说在滤波器的设计种 都要求系统必须稳定 否则是无法实
  • SparkCore

    第1章 RDD概述 1 1 什么是RDD RDD Resilient Distributed Dataset 叫做弹性分布式数据集 是Spark中最基本的数据抽象 代码中是一个抽象类 它代表一个弹性的 不可变 可分区 里面的元素可并行计算的
  • Linux环境开发工具(2)gdb调试工具+Makefile自动化构建工具

    Linux环境开发工具 2 gdb调试工具 Makefile自动化构建工具 Linux编译器 gcc g 使用 程序编译过程 重要概念 函数库 静态库与动态库 gcc选项 gdb使用 具体命令 Makefile 工具 使用过程 项目清理 关
  • 数字藏品是什么?

    有人说 任何东西都可以成为数字藏品 数字藏品是指通过区块链技术生成具有独特身份凭证的数字作品或艺术品 可以通过数字图片 音乐 视频 3D模型 电子门票 数字纪念品等形式进行展示 阿里巴巴 腾讯 京东 百度等互联网公司都推出了数字藏品平台或产
  • PMD使用与代码质量

    最近项目组要求使用PMD工具 通过自定义规则来检查代码 接录部分文档内容如下 PMD介绍 PMD是一种开源分析Java代码错误的工具 与其他分析工具不同的是 PMD通过静态分析获知代码错误 也就是说 在不运行Java程序的情况下报告错误 P
  • python100以内所有偶数-Python3基础 list 推导式 生成100以内的偶数列表

    Python 3 7 0 OS Ubuntu 18 04 1 LTS IDE PyCharm 2018 2 4 Conda 4 5 11 typesetting Markdown code coder Ubuntu source activ
  • Ubuntu系统预处理、编译、汇编、链接指令

    创建并编辑 c程序文件 gedit 1 c 以1 c为例 在编辑器中输入如下代码并保存 include
  • 基础学习5-centos7调整磁盘大小

    1 建立并查看物理磁盘 fdisk l dev sdb Disk dev sdb 10 7 GB 10737418240 bytes 20971520 sectors Units sectors of 1 512 512 bytes Sec
  • 静态Web服务器-命令行启动动态绑定端口号

    学习目标 能够写出获取终端命令行参数动态绑定端口号的web服务器程序 1 开发命令行启动动态绑定端口号的静态web服务器 实现步骤 获取执行python程序的终端命令行参数 判断参数的类型 设置端口号必须是整型 给Web服务器类的初始化方法
  • 2020-02-26

    请教大家一个AD的问题困扰多少的问题 AD10原理图复制一个器件 比如R1 正常复制粘贴还是R1 通过SHIFT拖动是R2 那如果我原理图中原本就有R2了 还是会有重复的现象 怎样复制粘贴会生成一个原理图中没有的位号呢
  • Splunk HEC 取发送数据 服务器的hostname

    1 背景 最近Client 发送数据到 Splunk HEC 发现对方hostname 没有取到 都是HEC 的VIP 地址 这个就不能发现是那个host 发过来的数据 下面查了下文档 发现Splunk 是可以跟踪发送数据的host 的 主
  • 【计算机网络】UDP协议

    目录 1 UDP协议头部格式 2 UDP协议的特点 2 1 无连接 2 2 不可靠 2 3 面向数据报 2 4 有接收缓冲区 没有发送缓冲区 2 5 大小受限 3 基于UDP的应用层协议 4 UDP协议与TCP协议对比 5 经典面试题 1
  • 基于.NET的企业级软件开发

    企业级开发最好基于一些成熟的框架 从而将主要精力集中到领域模型的设计上 1 UI与业务逻辑的隔离 在web领域可以采用ASP NET MVC框架 2 业务逻辑与DB的隔离 可以采用Entity Framework框架 3 业务逻辑中涉及工作
  • 毕业设计-基于机器视觉的水表读数智能识别系统-OpenCV

    目录 前言 课题背景和意义 实现技术思路 一 系统总体方案设计 二 图像预处理的研究与实现 三 识别区域定位及字符分割的研究与实现 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备
  • 分治算法(Java)

    想必大家通过算法的名字就已经明白了 这个算法的过程 一个是分 一个是治 那么我为什么要使用这种算法呢 因为当前的问题是我们使用现有的方法是解决不了的 所以我们需要将一个复杂的问题分成两个或者是更多个相同或相似的子问题 然后再一我们已有的方法
  • 【detectron2】注册、训练、推断自己的数据集

    一 注册自己的数据集 使用detectron2训练自己的数据集 第一步要注册自己的数据集 首先保证自己的数据集标注是coco格式 就可以使用load coco json加载自己的数据集并转化为detectron2的专有数据格式 使用Data