Backbone之Res2net介绍

Res2Net

论文:https://arxiv.org/abs/1904.01169
代码:https://github.com/Res2Net/Res2Net-PretrainedModels

目前现在计算机视觉主流的任务如分类/检测/分割,都需要backbone骨干网络提取特征,在目前的诸多backbone中,都希望通过增加多尺度表征能力来进行性能提升,目前现在大部分网络是在一层一层上使用的多尺度。而本文的主角Res2net通过提出一种全新的CNN模块,通过在残差块里面构建多通道的残差连接,来代替单个3*3的卷积核,res2Net在更细粒度级别表示多尺度特征,同时还具有相当好的泛化性能,res2net能够嵌入到目前主流的CNN网络中去,例如resnet,resnext,DLA,以及senet,作者通过大量的消融试验证明了res2net的有效性

在这里插入图片描述
上图a是ResNet网络,图b是Res2Net,可以看出后者明显在残差单元(residual block)中插入更多带层级的残差连接结构(hierarchical residual-like connections)。具体来说,作者将一组3×3的卷积核替换为更小的一组过滤器,同时以分层的类残差方式来连接不同的过滤器组。

那么整个res2net的核心就是这个Bottle2neck

在这里插入图片描述

if scale == 1:
  self.nums = 1
else:
  self.nums = scale -1
if stype == 'stage':
    self.pool = nn.AvgPool2d(kernel_size=3, stride = stride, padding=1)
convs = []
bns = []
for i in range(self.nums):
  convs.append(nn.Conv2d(width, width, 
  kernel_size=3, stride = stride, padding=1, bias=False))
  bns.append(nn.BatchNorm2d(width))

通过这个for循环,共有scale-1个3*3的卷积核,但是由于通道channel使用width分离了,可以理解成
在这里插入图片描述

的宽度,所以参数数量大大减少,同样的,每一个3*3后都跟一个bn层。

最后就是关键部分Bottle2neck的forward:

def forward(self, x):
    residual = x

    out = self.conv1(x)
    out = self.bn1(out)
    out = self.relu(out)

    spx = torch.split(out, self.width, 1)
    for i in range(self.nums):
      if i==0 or self.stype=='stage':
        sp = spx[i]
      else:
        sp = sp + spx[i]
      sp = self.convs[i](sp)
      sp = self.relu(self.bns[i](sp))
      if i==0:
        out = sp
      else:
        out = torch.cat((out, sp), 1)
    if self.scale != 1 and self.stype=='normal':
      out = torch.cat((out, spx[self.nums]),1)
    elif self.scale != 1 and self.stype=='stage':
      out = torch.cat((out, self.pool(spx[self.nums])),1)

    out = self.conv3(out)
    out = self.bn3(out)

    if self.downsample is not None:
        residual = self.downsample(x)

    out += residual
    out = self.relu(out)

    return out

这个代码整体上其实就是整个res2net最核心的地方,前面没什么好说的,简单的一个CBR,后面就是怎么把原来resnet的3*3卷积,换成res2net的新残差块

在这里插入图片描述
这一段开始通过torch.split拆分特征向量,除了第一个branch不过3x3卷积之外,拆出来的每个branch通过3x3卷积之后与下一个branch进行cat之后一边往下走,一边再与下一个branch做cat。

毫无疑问,这样做之后输出的channel数量就是width*scale,最后接上一个1x1的卷积再次进行特征融合。这样res2net的核心结构就完成了,可以看出超参就2个,一个width一个scale,作者用了一种类似FPN的方式把resnet单个3x3卷积,替换成了这样的相对更加细粒度的卷积,虽然还是3x3,但是由于通道做了一个拆分,实际上参数量没有增加的很多

最后就没有什么好说的了,分类网络中很常见的一个pooling+fc

x = self.avgpool(x)
x = x.view(x.size(0), -1)
x = self.fc(x)

return x

在这里插入图片描述
在这里插入图片描述
这里直接拉论文的结论,可以从上面看出来相比较resnet-50,res2net-50在参数和实时性上面其实没什么增加,但是精度提升非常明显。同时res2net可以很好地用在其他网络上做一个硬提升,例如resnext,senet等等。

  • 4
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
感谢您的提问。关于MogaNet的backbone注册成为detectron2的backbone的步骤,我可以为您提供以下步骤: 1. 首先,您需要在detectron2中注册您的backbone。您可以使用detectron2中的build_backbone函数来完成此操作。例如,您可以在detectron2中的backbone.py文件中添加以下代码: ```python from detectron2.modeling.backbone import Backbone from detectron2.layers import ShapeSpec class MogaNetBackbone(Backbone): def __init__(self, cfg, input_shape: ShapeSpec): super().__init__() # 在这里添加您的backbone代码 def forward(self, x): # 在这里添加您的前向传递代码 return x def build_moganet_backbone(cfg, input_shape): return MogaNetBackbone(cfg, input_shape) ``` 2. 接下来,您需要在detectron2的config文件中指定您的backbone。例如,您可以在detectron2的config文件中添加以下代码: ```yaml MODEL: META_ARCHITECTURE: "GeneralizedRCNN" BACKBONE: NAME: "moganet_backbone" RESNETS: DEPTH: 50 OUT_FEATURES: ["res2", "res3", "res4", "res5"] ``` 3. 最后,您需要在您的代码中使用您的backbone。例如,您可以在您的训练脚本中添加以下代码: ```python from detectron2.config import get_cfg from detectron2.engine import DefaultTrainer from detectron2.modeling import build_model cfg = get_cfg() cfg.merge_from_file("path/to/config.yaml") cfg.MODEL.WEIGHTS = "path/to/weights.pth" model = build_model(cfg) trainer = DefaultTrainer(cfg) trainer.build_model(model) ``` 以上就是MogaNet的backbone注册成为detectron2的backbone的步骤。希望能对您有所帮助。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值