Detectron2学习笔记
转载:https://www.cxybb.com/article/jiaoyangwm/114845483 建议前往,这里仅当学习
文章目录
-
- 一、Detectron2 操作介绍
-
- 1.1 训练
- 1.2 测试
- 1.3 数据及格式要求
- 1.4 Load/Save model
- 1.5 模型输入形式
- 1.6 模型输出
- 1.7 config usage
- 二、Detectron2 代码结构介绍
-
- 2.1 数据
- 2.2 模型
- 2.3 训练类的实现
- 2.4 训练
- 2.5 推理
- 2.6 模型的加载和保存
- 2.7 性能评估
- 2.8 日志存储
一、Detectron2 操作介绍
Detectron2代码链接:https://github.com/facebookresearch/detectron2
Detectron2说明文档:https://detectron2.readthedocs.io/index.html
安装之后要编译:
# 编译
python setup.py build develop
https://github.com/facebookresearch/detectron2/blob/master/datasets/README.md
3、训练
# 单GPU
cd toos/
./train_net.py \
--config-file ../configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml \
--num-gpus 1 SOLVER.IMS_PER_BATCH 2 SOLVER.BASE_LR 0.0025
# 多GPU
cd tools/
./train_net.py --num-gpus 8 \
--config-file ../configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml
4、评估模型性能
./train_net.py \
--config-file ../configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml \
--eval-only MODEL.WEIGHTS /path/to/checkpoint_file
更多的信息可以使用下面的命令查看:
./train_net.py -h
1.2 测试
1、从 model zoo 下载官方训好的模型
2、测试demo
# demo测试
cd demo/
python demo.py --config-file ../configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml \
--input input1.jpg input2.jpg \
[--other-options]
--opts MODEL.WEIGHTS detectron2://COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x/137849600/model_final_f10217.pkl
# 可修改细节
- To run on your webcam, replace --input files with --webcam.
- To run on a video, replace --input files with --video-input video.mp4.
- To run on cpu, add MODEL.DEVICE cpu after --opts.
- To save outputs to a directory (for images) or a file (for webcam or video), use --output.
https://detectron2.readthedocs.io/en/latest/tutorials/builtin_datasets.html
API地址



- engine:整合数据和model的过程,实现训练、测试
- data:model的输入
- modeling:solver(optimizer)的输入
- solver:优化器
- layers:构成modeling的基本层
- evaluation:评估
- config:读取配置文件
- projects:工程示例
- checkpoint:存储和加载模型权重
2.1 数据
./detectron2/data/

1、读取图片
./data/common.py
2、数据增强
./data/common.py
3、转化为batch
./data/build.py
4、修改数据路径
./data/datasets/

-
pascal voc

-
coco (
register_coco.py & coco.py)

修改超参数:
./configs/Base-RCNN-FPN.yaml

2.2 模型
./detectron2/modeling/

1、backbone
# backbone的抽象基类
# ./modeling/backbone/backbone.py

抽象类:
-
类, 是从一堆对象中抽象出来的, 比如猫类,狗类,人类
-
抽象类, 是从一堆类中抽象出来的, 比如上面的三个类可以抽取出动物类
-
抽象类的特点是不能给实例化, 只能被子类继承, 由子类实现了父类的抽象方法后, 子类才能被实例化
-
Python的abc提供了@abstractmethod装饰器实现抽象方法
build backbone
./modeling/backbone/build.py

backbone/resnet.py 中继承了 CNNBlockBase,定义了不同的Block,ResNet继承Backbone,并使用定义的block实现ResNet的backbone
当使用 from 模块名 import * 时,想要有一些变量不被调用,可以借助模块提供的 __all__ 变量:
- 该变量的值是一个列表,存储的是当前模块中一些成员(变量、函数或者类)的名称。通过在模块文件中设置
__all__变量,当其它文件以“from 模块名 import * ”的形式导入该模块时,该文件中只能使用__all__列表中指定的成员。 - 也就是说,只有以
“from 模块名 import *”形式导入的模块,当该模块设有__all__变量时,只能导入该变量指定的成员,未指定的成员是无法导入的。
注册与调用:
定义:
@BACKBONE_REGISTRY.register()
def build_resnet_backbone(cfg, input_shape):
return ResNet(stem, stages, out_features=out_features).freeze(freeze_at)
调用:./build.py中根据配置文件名调用之前Register好的backbone
backbone = BACKBONE_REGISTRY.get(backbone_name)(cfg, input_shape)
./modeling/backbone/fpn.py 文件又把build_resnet_backbone生产的resnet作为子结构输入,扩展了不同的FPN的backbone:
# resnet @BACKBONE_REGISTRY.register() def build_resnet_fpn_backbone(cfg, input_shape: ShapeSpec): # retinanet @BACKBONE_REGISTRY.register() def build_resnet_fpn_backbone(cfg, input_shape: ShapeSpec):
2、proposal 生成
./modeling/proposal_generator/build.py
根据配置文件调用相应的 proposal generator :
PROPOSAL_GENERATOR_REGISTRY.get(name)(cfg, input_shape)
# 1
@RPN_HEAD_REGISTRY.register()
class StandardRPNHead(nn.Module):
# 2
@PROPOSAL_GENERATOR_REGISTRY.register()
class RPN(nn.Module):
3、RoI Heads
接口:
./modeling/roi_heads/roi_heads.py
实现:
# 1
@ROI_HEADS_REGISTRY.register()
class Res5ROIHeads(ROIHeads):
# 2
@ROI_HEADS_REGISTRY.register()
class StandardROIHeads(ROIHeads):
4、mask head
def build_mask_head(cfg, input_shape):
name = cfg.MODEL.ROI_MASK_HEAD.NAME
return ROI_MASK_HEAD_REGISTRY.get(name)(cfg, input_shape)
5、keypoint head
def build_keypoint_head(cfg, input_shape):
name = cfg.MODEL.ROI_KEYPOINT_HEAD.NAME
return ROI_KEYPOINT_HEAD_REGISTRY.get(name)(cfg, input_shape)
6、执行流程
./modeling/meta_arch/

- batch_input 进行预处理
- 输入backbone进行特征提取
- 将feature和img输入给proposal_generator
- 将proposal 结果给到 RoI Heads
def forward(self, batched_inputs):
if not self.training:
return self.inference(batched_inputs)
images = self.preprocess_image(batched_inputs)
if "instances" in batched_inputs[0]:
gt_instances = [x["instances"].to(self.device) for x in batched_inputs]
else:
gt_instances = None
features = self.backbone(images.tensor)
if self.proposal_generator:
proposals, proposal_losses = self.proposal_generator(images, features, gt_instances)
else:
assert "proposals" in batched_inputs[0]
proposals = [x["proposals"].to(self.device) for x in batched_inputs]
proposal_losses = {
}
_, detector_losses = self.roi_heads(images, features, proposals, gt_instances)
if self.vis_period > 0:
storage = get_event_storage()
if storage.iter % self.vis_period == 0:
self.visualize_training(batched_inputs, proposals)
losses = {
}
losses.update(detector_losses)
losses.update(proposal_losses)
return losses
2.3 训练类的实现
./detectron2/engine/train_loop.py
1、HookBase 定义了四个阶段:
- before_train
- after_train
- before_step
- after_step
2、TrainerBase 对 hook 灵活调用,使用各个功能
3、SimpleTrainer (./train_loop.py) 继承自TrainerBase,对TrainerBase中预留接口的训练核心部分的方法def run_step(self)做了具体实现,包括推理计算loss以及backward:
4、DefaultTrainer(./defaults.py)继承自SimpleTrainer,实现了训练流程,包括创建model, optimizer, scheduler, dataloader,根据配置文件增加了辅助功能hooks类中的功能
2.4 训练
./tools/
可见GPU号修改:
os.environ['CUDA_VISIBLE_DEVIES'] = '0, 1, 2'
train_net.py中层层抽象,在之前TrainBase → \to → SimpleTrainer → \to →DefaultTrainer上又增加了一层抽象,添加evaluation模块的功能,以及inference with test-time augmentation功能
2.5 推理
./detectron2/engine/defaults.py
2.6 模型的加载和保存
1、两种保存模型的方法:
- 仅保存权重
# 保存
torch.save(model.state_dict(), path)
# 加载
model = Model()
model.load_state_dict(torch.load(path))
model.eval()
- 保存整个模型和对应权重
# 保存
torch.save(model, path)
# 加载
model = torch.load(path)
model.eval()
2、保存 checkpoint 的方法
完整的checkpoint一般保存了模型的 state_dict、优化器的state_dict、epoch等
- 保存checkpoint
torch.save({
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'loss': loss}, path)
- 加载checkpoint
checkpoitn = torch.load(path)
model.load_state_dict(checkpoint['model_state_dict'])
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
epoch = checkpoint['epoch']
loss = checkpoint['loss']
model.eval()
2.7 性能评估
./detectron2/evaluation/evaluator.py
2.8 日志存储
./engine/hooks.py
日志存储是通过 hook 来控制的,hooks.py 中的 after_step() 方法调用 writer.write() 进行日志的写入。