detectron2 学习笔记
目录
- 一、安装
- 二、项目详细介绍
- 训练
- 三、tools文件夹
- 四、换自己的数据集
- 制作数据集
- 换数据集
- 标准数据集字典
- Metadata
- Dataloader
- 数据增强Data Augmentation [原文](https://blog.csdn.net/weixin_42174674/article/details/116307377)
- Use Model
- 注册自己的model
- 训练
- 评估
- 遇到的问题
- 代码解读 实际操作
一、安装
- 安装pytorch和对应CUDA
- 安装detectron2
git clone https://github.com/facebookresearch/detectron2.git
python -m pip install -e detectron2
如果更换pytorch版本,需要删除`rm -rf build/ **/*.so`再重新构建
具体安装相关问题点击这里
二、项目详细介绍
链接
API文档
- 模型搭建
主要入口:detectron2/detectron2/modeling/meta_arch/build.py 中的 def build_model(cfg) 方法。
相关代码:detectron2/detectron2/modeling 目录下。
相关配置:detectron2/config/defaults.py中_C.MODEL 开头的配置。
主要包括了:TrainerBase, SimpleTrainer, DefaultTrainer 三个类。
训练
- 1
TrainerBase:
定义在 detectron2/detectron2/engine/train_loop.py 中。- 主要功能:
- 提供了 hooks 机制,可以通过导入 HookBase 对象,在训练过程的各个时间点进行自定义处理。
- 定义了训练函数为 train(self, start_iter: int, max_iter: int),且维训练提供了一个 EventStorage 对象。
- 这个与TF中的SessionRunHook类似,只不过TF已经实现在源码里,而Detectron2中是自己实现的。
- 主要功能:
- 2
SimpleTrainer:
定义在 detectron2/detectron2/engine/train_loop.py 中。- 主要功能:在 TrainerBase 的基础上添加了训练所需的基本参数以及最基本的训练过程代码。
基本训练参数指的是 model/data_loader/optimizer
基本训练过程包括位于 run_step 函数中,主要包括的功能是:
导入数据。- 计算损失函数(并确保损失函数是有效的)。
- 记录一些性能指标(包括损失函数、时间点),保存到 EventStorage 对象中。
- 进行梯度下降操作。
- 主要功能:在 TrainerBase 的基础上添加了训练所需的基本参数以及最基本的训练过程代码。
- 2
DefaultTrainer
定义在 detectron2/detectron2/engine/defaults.py 中。- 主要功能:
- 在 SimpleTrainer 的基础上,提供了通过配置文件创建模型、数据集、优化器、学习率等一系列操作。
- 提供了 checkpoint 功能。
- 使用了一系列常见的 hooks。
- hooks的定义都在 detectron2/detectron2/engine/hooks.py 中。
- 主要功能:
三、tools文件夹
train_net.py
训练脚本
benchmark.py
标记给定配置的训练速度、推理速度或数据加载速度。
analyze_model.py
分析FLOPs,参数,detectron2模型的激活。
visualize_json_results.py
可视化json实例检测/分割结果转储“cocoevaluator”或“LVISEvaluator”。如果不使用内置数据集,则需要自己的脚本或修改脚本。
visualize_data.py
可视化ground truth或训练数据(after preprocessing/augmentations).
四、换自己的数据集
制作数据集
要转化成coco格式的数据集
换数据集
train.py
该文件里面包含了Trainer这个类,继承了DefaultTrainer,这里重写了build_evaluator 和 test_with_TTA这两个方法。
根据英文注释,可以明显看出这两个方法,一个是创建对应数据集的评价器,一个是对应于RCNN系列的评价。
如果您想在使用自定义数据集的同时重用检测器 2 的数据加载器,您将需要:
注册您的数据集(即,告诉detectron2 如何获取您的数据集)。
(可选)为您的数据集注册元数据。
官方:
def my_dataset_function():...return list[dict] in the following formatfrom detectron2.data import DatasetCatalog
DatasetCatalog.register("my_dataset", my_dataset_function)
# later, to access the data:
data: List[Dict] = DatasetCatalog.get("my_dataset")
my_dataset_function() 函数返回了你的数据集(比如叫my_dataset)中的数据。这个函数无论被调用多少次,必须返回同一批数据。这个注册在进程结束之前一直有效。
这个函数在经过任意处理后必须以 list[dict] 格式返回数据,每个 dict 必须具有如下格式:
Detectron2 的标准数据字典(下面会介绍)。使用这种格式的话,你的数据集将会支持很多 Detectron2 内置的操作,如果没有其他需求推荐使用这种格式。
任何自定义的格式,比如对于新的任务,你要求数据具有额外的信息。但是在随后的运行中你需要逐一处理可能出现的问题。
原文链接:https://blog.csdn.net/weixin_42174674/article/details/116290093
后来发现,在built.py中注册自己的数据集:
以coco格式为例
# 先声明自己的数据集,模仿下面的格式,先是图片路径,再是annotation
mydataset={"coco_2017_train": ("coco/train2017", "coco/annotations/instances_train2017.json"),"coco_2017_val": ("coco/val2017", "coco/annotations/instances_val2017.json"),"coco_2017_test": ("coco/test2017", "coco/annotations/image_info_test2017.json")}
# 再声明数据集中的类别
metadata_mydata = {"thing_classes": ["cat,dog"]
}
# 然后在这个函数中加入循环
def register_all_coco(root):for key, (image_root, json_file) in mydataset.items():# Assume pre-defined datasets live in `./datasets`.register_coco_instances(key,metadata_mydata,os.path.join(root, json_file) if "://" not in json_file else json_file,os.path.join(root, image_root),)
标准数据集字典
目标检测/实例分割
annotations (list[dict]): 在目标检测/分割/或者关键点检测任务中需要。每个字典对应了图片中的一个物体,这个子字典需要有这些内容:
- bbox (list[float], 必须):一个有4个浮点数的list
- bbox_mode (int, 必须):整数,代表了每个bounding box的数据存储模式(xyxy 或者 xywh),它必须是 structure.BoxMode 中的成员,现在支持 BoxMode. XYXY_ABS, BoxMode. XYWH_ABS
- category_id (int, 必须):整数,这个 int 在 [0,类别数 - 1] 的范围内,代表了物体属于哪类。
- segmentation (list[list[float]] or dict):存储了分割需要的mask
- 如果是 list[list[float]],那么它存储了一个多边形的 list,每个代表物体的一个联通区域,每个多边形的格式是 [x1, y1, …, xn, yn] (n >= 3). 这里 x 和 y 是像素的绝对坐标。
- 如果是 dict,那么它对应了逐像素分割的类型,格式为 COCO 的 压缩RLE格式。这个字典需要有 “size” 和 “counts”。
- keypoints:(list[float]),格式是 [x1, y1, v1, …, xn, yn, vn]. v[i] 是这个关键点的 visibility,n 等于关键点的类别数量。x 和 y 是绝对坐标。
iscrowd (0 (default) or 1):这个物体是不是 “Crowd region”,参见 COCO,如果你不知道这个是什么,不要加入这个。
原文链接:https://blog.csdn.net/weixin_42174674/article/details/116290093
如果您的实例级(检测、分割、关键点)数据集已经是 COCO 格式的 json 文件,则数据集及其关联的元数据可以通过以下方式轻松注册:
from detectron2.data.datasets import register_coco_instances
register_coco_instances("my_dataset", {}, "json_annotation.json", "path/to/image/dir")
一旦您注册了数据集,您就可以在cfg.DATASETS.{TRAIN,TEST}中使用数据集的名称。
如果您的数据集是 COCO 格式但需要进一步处理,或者具有额外的自定义每个实例注释,则load_coco_json 函数可能很有用。
Metadata
https://blog.csdn.net/weixin_42174674/article/details/116290093#t11
Dataloader
Detectron2 提供了两个函数 build_detection_{train,test}_loader 从给定的config创建一个默认的dataloader。
- 它采用注册数据集的名称(例如,“coco_2017_train”)并list[dict]以轻量级格式加载表示数据集项的 。
- 每一个 list[dict] 中的字典会被一个 mapper 映射到模型可接受的格式。
使用不同的“映射器”build_detection_{train,test}_loader(mapper=)适用于大多数自定义数据加载用例。例如,如果要将所有图像调整为固定大小以进行训练,请使用:
import detectron2.data.transforms as T
from detectron2.data import DatasetMapper # the default mapper
dataloader = build_detection_train_loader(cfg,mapper=DatasetMapper(cfg, is_train=True, augmentations=[T.Resize((800, 800))]))
如果默认DatasetMapper的参数 没有提供您需要的参数,您可以编写自定义映射器函数并使用它
数据增强Data Augmentation 原文
from detectron2.data import transforms as T
# 定义一堆数据增强:
augs = T.AugmentationList([T.RandomBrightness(0.9, 1.1),T.RandomFlip(prob=0.5),T.RandomCrop("absolute", (640, 640))
])
# 定义数据增强的输入(必须输入图片,其它输入可选)。=
input = T.AugInput(image, boxes=boxes, sem_seg=sem_seg)
# 实施数据增强
transform = augs(input) # 类型:T.Transform
image_transformed = input.image # 新的图像
sem_seg_transformed = input.sem_Seg # 新的语义分割# 除了input这些图片之外,如果你想进行额外的操作:
image2_transformed = transform.apply_image(image2)
polygons_transformed = transform.apply_polygons(polygons)
T.Augmentation 定义了如何去改变输入数据
T.Transform 对数据应用具体操作
T.AugInput 存储了 T.Augmentation 需要的输入数据和它们需要怎样被转换。
Use Model
通过config配置模型,通过build_model, build_backbone, build_roi_heads等函数构建模型
from detectron2.modeling import build_model
model = build_model(cfg) # 返回一个 torch.nn.Module
Load/Save a Checkpoint
from detectron2.checkpoint import DetectionCheckpointer
DetectionCheckpointer(model).load(file_path_or_url) # load a file, usually from cfg.MODEL.WEIGHTScheckpointer = DetectionCheckpointer(model, save_dir="output")
checkpointer.save("model_999") # save to output/model_999.pth
保存的文件
torch.{load,save} for .pth files
pickle.{dump,load} for .pkl files.
输入必须是list[dist],outputs = model(inputs) inputs list[dict]
每个字典对应一个图像的信息,dist中可能包含这些键:
“image” (Tensor): 是 (C,H,W) 格式
“height”, “width”:我们希望的输出的高和宽
“instances”:训练中需要用到的物体标注
“sem_seg”: Tensor[int], (H,W) 格式,语义分割中的 gt,单通道图,值对应类别。
输出
training 时输出dict[str->ScalarTensor]
包含所有loss。
预测时,输出list[dict]
每一个 dict 对应一张图,可能会包含如下内容:前面输入中的instances、sem_seg,或者panoptic_seg
注册自己的model
如果编写自己的backbone,使用以下代码注册到框架
from detectron2.modeling import BACKBONE_REGISTRY, Backbone, ShapeSpec@BACKBONE_REGISTRY.register()
class ToyBackbone(Backbone):def __init__(self, cfg, input_shape):super().__init__()# create your own backboneself.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=16, padding=3)def forward(self, image):return {"conv1": self.conv1(image)}def output_shape(self):return {"conv1": ShapeSpec(channels=64, stride=16)}
之后便可以在config调用:
cfg = ... # 读取 config
cfg.MODEL.BACKBONE.NAME = 'ToyBackbone' # 或者你可以在 config file 中更改
model = build_model(cfg)
训练
SimpleTrainer 提供了最简单的 单损失,单优化器,单数据集的 训练循环,没有其它的任何功能(包括保存,记录等),这些功能可以通过 hook 来实现。
DefaultTrainer 继承自 SimpleTrainer, 在 tools/train_net.py 和很多脚本中被使用。DefaultTrainer 从 config 初始化,包含了一些允许用户自定义的更加标准化的操作,比如优化器的选择、学习率的规划、记录日志、保存模型、评测模型等。
自定义一个DefaultTrainer
对于简单的自定义(例如更改优化器、评估器、LR 调度器、数据加载器等),在子类中覆盖其方法,就像tools/train_net.py。
训练过程中,Detectron2 会把日志记录到 EventStorage 中
在train_net.py中自定义训练参数
https://blog.csdn.net/qq_29750461/article/details/106761382
def setup(args):"""Create configs and perform basic setups."""cfg = get_cfg()args.config_file = "../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 = Truecfg.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或者768cfg.INPUT.MIN_SIZE_TRAIN_SAMPLING = 'range'
# 本句一定要看下注释!!!!!!!!cfg.MODEL.RETINANET.NUM_CLASSES = 81 # 类别数+1(因为有background,也就是你的 cate id 从 1 开始,如果您的数据集Json下标从 0 开始,这个改为您对应的类别就行,不用再加背景类!!!!!)#cfg.MODEL.WEIGHTS="/home/yourstorePath/.pth"cfg.MODEL.WEIGHTS = "/home/yourstorePath/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(9000 / 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.0001cfg.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 = 1000cfg.SOLVER.WARMUP_METHOD = "linear"# 保存模型文件的命名数据减1cfg.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
评估
Detectron2 包含了一些 DatasetEvaluator 来计算模型在常用数据集上的表现 (COCO, LVIS等)。
遇到的问题
运行demo
TypeError: forward() takes 2 positional arguments but 4 were given
- 已解决:还是环境有问题,重新安装1.7+0.8+cuda9.2,使用官方源,耐心等待
代码解读 实际操作
- tools/train_net.py
首先调用了一个 cfg = setup(args),之后创建了一个 Trainer 对象,然后执行了 trainer.train() - DefaultTrainer 类,在 detectron2/engine/defaults.py,里面有
model = self.build_model(cfg)
, - 被定义在
detectron2/modeling /meta_arch/build.py
中
def build_model(cfg):"""Build the whole model architecture, defined by ``cfg.MODEL.META_ARCHITECTURE``.Note that it does not load any weights from ``cfg``."""meta_arch = cfg.MODEL.META_ARCHITECTUREmodel = META_ARCH_REGISTRY.get(meta_arch)(cfg)model.to(torch.device(cfg.MODEL.DEVICE))_log_api_usage("modeling.meta_arch." + meta_arch)return model
meta_arch文件夹下放入模型代码,用@META_ARCH_REGISTRY.register()
注册,通过build_model调用,例如rcnn中。
init()中有 self.backbone = build_backbone(cfg)
,在detectron2/modeling/backbone/build.py中,通过传来的cfg找到已注册的backbone
def build_backbone(cfg, input_shape=None):backbone_name = cfg.MODEL.BACKBONE.NAMEbackbone = BACKBONE_REGISTRY.get(backbone_name)(cfg, input_shape)assert isinstance(backbone, Backbone)return backbone
在detectron2/modeling/backbone/backbone.py
中,这个类中init和forward需要自己重写,在detectron2/modeling/backbone
文件夹下,需要自己重写backbone,构造函数需要使用@BACKBONE_REGISTRY.register()
注册,才能被build_backbone(cfg)
找到。
build_proposal_generator
detectron2/utils/visualizer.py
是制作mask、box的代码
detectron2 学习笔记相关推荐
- 从源代码开始 Detectron2学习笔记
`从零开始 Detectron2学习笔记(一) 框架简介 1.Detection2的安装 2. 用预训练模型进行检测 2.1官方demo示例 2. 2源代码解读 2.2.1 模型的配置和构建 2.2. ...
- Detectron2学习笔记
文章目录 一.Detectron2 操作介绍 1.1 训练 1.2 测试 1.3 数据及格式要求 1.4 Load/Save model 1.5 模型输入形式 1.6 模型输出 1.7 config ...
- Faster R-CNN——学习笔记~
1 致谢 感谢网友theoqian的帮助,原文链接如下: https://www.jianshu.com/p/cbfaa305b887 关于RPN的过程解释的十分通俗易懂! 2 Faster R-CN ...
- PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call
您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...
- 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程
暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...
- 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移
暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...
- 2020年Yann Lecun深度学习笔记(下)
2020年Yann Lecun深度学习笔记(下)
- 2020年Yann Lecun深度学习笔记(上)
2020年Yann Lecun深度学习笔记(上)
- 知识图谱学习笔记(1)
知识图谱学习笔记第一部分,包含RDF介绍,以及Jena RDF API使用 知识图谱的基石:RDF RDF(Resource Description Framework),即资源描述框架,其本质是一个 ...
最新文章
- Golang向Templates 插入对象的值
- 设计模式学习(十六) 模板方法模式
- Jarvis OJ web(一)
- Mysql Insert Or Update语法实例
- Memcached 与 PHP 结合使用
- Java模块化方法–模块,模块,模块
- php 可选表格,PHP_表格标记, 
■ 表格标记
TABLE - phpStudy
- erlang的timer定时器浅析
- Network Delay Time
- POST 请求的三种常见数据提交格式
- 最全面的 Spring 学习笔记
- Arduino mixly 点灯科技(blinker) 在线电压监测(带电压高低提醒)
- Greenplum集群扩容总结
- CSS度量单位rem、em、vw、vh详解
- 计算机健康小知识,电脑一族护肤保健小常识
- 游戏策划笔记:交互分析
- 木瓜从林。。。。。。。。。。。。。。。。。
- 基于ArcGIS Pro 的AI地图配色工具
- Android调试系列之开发者选项常用功能
- Windows命令行查看文件的MD5 和win10下获取md5-sha1
热门文章
- photoshop油画滤镜使用和案例教程
- 前端网络基础-传输层UDP协议
- 微信小程序导购开发跳转到京东拼多多苏宁唯品会等小程序
- indesign选中不了图片删除_word图文设计:如何用图片水印功能制作日历画册
- 微信支付报错提示“商户号该产品权限未开通,请前往商户平台产品中心检查后重试...
- 53 pandas 时间序列-时区处理(tz_localize本地化tz_conver转换)(tcy)
- Windows8.1安装tools提示:安装程序无法验证是否已安装所需的Microsoft更新KB2919355的问题详解
- 【R言R语】算法工程师入职一年半的总结与感悟
- 京东AI:戴口罩人脸识别pytorch开源库
- 1032:大象喝水 题解 信息学奥赛 NOIP