手把手教你在Detectron2中搭建自己的Backbone

手把手教你在Detectron2中搭建自己的Backbone

0、准备主干网络

准备一个Bockbone,我们以最新的RepVGG为例:

RepVGG的链接如下:DingXiaoH/RepVGG: RepVGG: Making VGG-style ConvNets Great Again (github.com)

查看:yaml文件:OUT_FEATURES: [“res2”, “res3”, “res4”, “res5”]

修改主干网络,返回一个字典

class RepVGG(nn.Module):

    def __init__(self, num_blocks, width_multiplier=None, override_groups_map=None, deploy=False, use_se=False):
        super(RepVGG, self).__init__()

        assert len(width_multiplier) == 4

        self.deploy = deploy
        self.override_groups_map = override_groups_map or dict()
        self.use_se = use_se

        assert 0 not in self.override_groups_map

        self.in_planes = min(64, int(64 * width_multiplier[0]))

        self.stage0 = RepVGGBlock(in_channels=3, out_channels=self.in_planes, kernel_size=3, stride=2, padding=1, deploy=self.deploy, use_se=self.use_se)
        self.cur_layer_idx = 1
        self.stage1 = self._make_stage(int(64 * width_multiplier[0]), num_blocks[0], stride=2)
        self.stage2 = self._make_stage(int(128 * width_multiplier[1]), num_blocks[1], stride=2)
        self.stage3 = self._make_stage(int(256 * width_multiplier[2]), num_blocks[2], stride=2)
        self.stage4 = self._make_stage(int(512 * width_multiplier[3]), num_blocks[3], stride=2)
        # self.gap = nn.AdaptiveAvgPool2d(output_size=1)
        # self.linear = nn.Linear(int(512 * width_multiplier[3]), num_classes)


    def _make_stage(self, planes, num_blocks, stride):
        strides = [stride] + [1]*(num_blocks-1)
        blocks = []
        for stride in strides:
            cur_groups = self.override_groups_map.get(self.cur_layer_idx, 1)
            blocks.append(RepVGGBlock(in_channels=self.in_planes, out_channels=planes, kernel_size=3,
                                      stride=stride, padding=1, groups=cur_groups, deploy=self.deploy, use_se=self.use_se))
            self.in_planes = planes
            self.cur_layer_idx += 1
        return nn.Sequential(*blocks)

    def forward(self, x):
        output = {}
        out = self.stage0(x)
        out = self.stage1(out)
        output["res2"] = out
        out = self.stage2(out)
        output["res3"] = out
        out = self.stage3(out)
        output["res4"] = out
        out = self.stage4(out)
        output["res5"] = out

        # out = self.gap(out)
        # out = out.view(out.size(0), -1)
        # out = self.linear(out)
        return output

1、网络需要继承Backbone基类

class RepVGG(nn.Module):->class RepVGG(Backbone):

2、继承Backbone类的output_shape(self)方法

def __init__(self, num_blocks, width_multiplier=None, override_groups_map=None, deploy=False, use_se=False):
    super(RepVGG, self).__init__()
    ...
    self.out_features_names = ["res2", "res3", "res4", "res5"]
    self._out_feature_channels = { # 每一个stage输出的通道数
        'res2': 48,
        'res3': 96,
        'res4': 192,
        'res5': 1280,
    }
    self._out_feature_strides = { # 步幅
        'res2': 4,
        'res3': 8,
        'res4': 16,
        'res5': 32,
    }

def output_shape(self):
    """
	Returns:
		dict[str->ShapeSpec]
	"""
    # this is a backward-compatible default
    return {
        name: ShapeSpec(
            channels=self._out_feature_channels[name], stride=self._out_feature_strides[name]
        )
        for name in self.out_features_names
    }

3、注册RepVGG主干网络

这里这些参数也可以通过cfg来专递,这里简便起见,直接返回模型。

@BACKBONE_REGISTRY.register()
def build_repvgg_backbone(cfg, input_shape):
    deploy = None
    model = RepVGG(num_blocks=[2, 4, 14, 1],
                  width_multiplier=[0.75, 0.75, 0.75, 2.5], override_groups_map=None, deploy=deploy)
    return model

4、在_init_()中写入build_repvgg_backbone

from .repvgg import build_repvgg_backbone

5、删除目录中的build文件,重新编译网络

python setup.py build develop

6、在yaml文件中写入repvgg

MODEL:
    NAME: "build_repvgg_backbone"

7、附录 repvgg预训练模型下载地址

百度网盘 请输入提取码 (baidu.com)

提取码:rvgg

参考链接:DingXiaoH/RepVGG: RepVGG: Making VGG-style ConvNets Great Again (github.com)

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: 您好,关于在detectron2正确引入resnest,我可以给您一些指导。首先,您需要下载resnest的代码,并将其放在detectron2的目录下。然后,在detectron2的配置文件,您需要将backbone的类型设置为resnest,并指定相应的参数。最后,在训练或测试时,您可以像使用其他backbone一样使用resnest。以下是一些示例代码: 1. 下载resnest代码并放置在detectron2目录下: ``` git clone https://github.com/zhanghang1989/ResNeSt.git mv ResNeSt detectron2/models/ ``` 2. 在detectron2配置文件指定resnest的参数: ``` MODEL: ... BACKBONE: NAME: "build_resnest_backbone" RESNEST: DEPTH: 50 OUT_FEATURES: ["resnest_stage3", "resnest_stage4", "resnest_stage5"] ... ``` 3. 在训练或测试时使用resnest: ``` from detectron2.config import get_cfg from detectron2.engine import DefaultTrainer, DefaultPredictor from detectron2.modeling import build_model cfg = get_cfg() cfg.merge_from_file("path/to/config.yaml") model = build_model(cfg) trainer = DefaultTrainer(cfg) predictor = DefaultPredictor(cfg) ``` ### 回答2: 要在Detectron2正确引入ResNeSt并使其能够像其他backbone一样容易引用,需要按照以下步骤进行操作: 1. 首先,下载ResNeSt的代码库并将其放置在Detectron2的相应位置。 2. 接下来,在Detectron2的文件夹创建一个新的Python文件,命名为"resnest_backbone.py"。 3. 在"resnest_backbone.py",引入必要的库和模块: ``` from detectron2.modeling.backbone import Backbone from detectron2.layers import ShapeSpec import torch.nn as nn import torch.nn.functional as F import torchvision.models as models ``` 4. 定义一个新的类"ResNeStBackbone",并继承自Detectron2的Backbone类: ``` class ResNeStBackbone(Backbone): def __init__(self, cfg, input_shape: ShapeSpec): super().__init__() # 在这里添加ResNeSt的网络结构,可以参考Detectron2自带的模型代码进行修改 # 例如,可以使用ResNeSt50作为backbone: self.resnest = models.resnest.resnest50(pretrained=True) self.out_features = cfg.MODEL.RESNETS.OUT_FEATURES ``` 5. 实现ResNeStBackbone类的前向传播方法"forward": ``` def forward(self, image): # 根据ResNeSt的网络结构进行前向传播计算 # 例如,获得网络的输出特征图: x = self.resnest.conv1(image) x = self.resnest.bn1(x) x = self.resnest.relu(x) x = self.resnest.maxpool(x) x = self.resnest.layer1(x) x = self.resnest.layer2(x) x = self.resnest.layer3(x) x = self.resnest.layer4(x) return {"res4": x} ``` 6. 最后,将"resnest_backbone.py"文件的新backbone注册到Detectron2的配置文件: ``` from detectron2.config import CfgNode from .resnest_backbone import ResNeStBackbone def add_resnest_config(cfg: CfgNode): # 添加新backbone的配置 cfg.MODEL.RESNEST = CfgNode() cfg.MODEL.RESNEST.OUT_FEATURES = ("res4",) # 在这里定义输出的特征名称,可以根据需求进行修改 def build_resnest_backbone(cfg, input_shape): backbone = ResNeStBackbone(cfg, input_shape) return backbone ``` 在Detectron2的配置文件添加以下内容,以使用ResNeSt作为backbone: ``` MODEL: ... BACKBONE: NAME: "build_resnest_backbone" RESNETS: DEPTH: 50 OUT_FEATURES: ["res4"] ... ``` 完成上述步骤后,就能在Detectron2正确引入ResNeSt并将其作为backbone使用了。 ### 回答3: 要在Detectron2正确引入ResNeSt作为backbone,并能够像其他backbone一样容易引用,需要按照以下步骤进行操作: 步骤一:下载ResNeSt源代码和预训练模型。 1. 在终端运行以下命令克隆ResNeSt仓库:git clone https://github.com/zhanghang1989/ResNeSt.git 2. 使用预训练模型,可以在ResNeSt的GitHub页面(https://github.com/zhanghang1989/ResNeSt)找到。 步骤二:创建新的backbone类。 1. 在Detectron2源代码找到backbone文件夹,在其创建一个新的Python文件(例如:resnest.py)。 2. 在新的Python文件导入必要的库,例如:torch、torchvision、Detectron2的相关组件等。 (以下代码假设ResNeSt为ResNet50的变种) 3. 定义一个类ResNeSt,继承Backbone基类。重写__init__方法,其初始化ResNeSt网络,并加载预训练的权重: ```python import torch import torch.nn as nn import torchvision.models as models from detectron2.modeling import Backbone class ResNeSt(Backbone): def __init__(self, cfg, backbone_name="resnest50"): super(ResNeSt, self).__init__() self.model = models.__dict__[backbone_name](pretrained=True) if cfg.MODEL.BACKBONE.FREEZE: for param in self.model.parameters(): param.requires_grad = False def forward(self, x): return self.model(x) ``` 步骤三:注册backbone类。 1. 打开Detectron2的模型注册文件(model_zoo.py)。 2. 导入之前创建的ResNeSt类。 3. 在`BACKBONE_REGISTRY`注册ResNeSt类: ```python from .backbone.resnest import ResNeSt ... BACKBONE_REGISTRY = Registry({ "resnest": ResNeSt, ... }) ... def build_backbone(cfg): ... name = cfg.MODEL.BACKBONE.NAME ... backbone = BACKBONE_REGISTRY.get(name)(cfg) ... return backbone ``` 步骤四:在配置文件引用ResNeSt。 1. 打开Detectron2的配置文件(例如:configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml)。 2. 在MODEL指定BACKBONE的名称为"resnest”。 至此,ResNeSt已经可以像其他backbone一样容易地引用了。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值