BackBone
发布日期:2021-05-14 15:18:16 浏览次数:42 分类:精选文章

本文共 4711 字,大约阅读时间需要 15 分钟。

Mish激活函数

Mish(密集依赖式激活函数)是一种新的激活函数,类似于Sigmoid函数,但其内部使用了tanh函数且无需额外学习参数。其公式可以表示为: $$ B a c k B o n e BackBone $$ $$ Mish(x) = x \cdot \tanh(\text{softplus}(x)) $$ 其中softplus函数可以通过下面的方式计算: $$ \text{softplus}(x) = \log(1 + e^x) $$

#卷积块CBM(conv + batchnorm + mish)

CBM卷积块由卷积层、batch normalization(BatchNorm)和Mish激活函数组成。其结构如下:

class BasicConv(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size=3, stride=1):
super(BasicConv, self).__init__()
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, kernel_size//2, bias=False)
self.bn = nn.BatchNorm2d(out_channels)
self.activation = Mish()
def forward(self, x):
x = self.conv(x)
x = self.bn(x)
x = self.activation(x)
return x

#CSP内部堆叠残差块

CSP网络的核心是在每个残差块中,通过两步卷积操作和交并连接实现特征重构。堆叠的残差块可以有效增强网络的深度和表达能力。

class Resblock(nn.Module):
def __init__(self, channels, hidden_channels=None):
super(Resblock, self).__init__()
if hidden_channels is None:
hidden_channels = channels
self.block = nn.Sequential(
BasicConv(channels, hidden_channels, kernel_size=1),
BasicConv(hidden_channels, channels, kernel_size=3)
)
def forward(self, x):
return x + self.block(x)

#CSP模块

CSP模块在堆叠多个Resblock后,通过切分、处理和重新连接来增强特征表达能力。其中,切分卷积层(split_conv)用于分离和调整特征图;block_conv用于特征图的深度增强;concat_conv则进行最终的特征图拼接。

class Resblock_body(nn.Module):
def __init__(self, in_channels, out_channels, num_blocks, first):
super(Resblock_body, self).__init__()
self.downsample_conv = BasicConv(in_channels, out_channels, kernel_size=3, stride=2)
if first:
self.split_conv0 = BasicConv(out_channels, out_channels, kernel_size=1)
self.split_conv1 = BasicConv(out_channels, out_channels, kernel_size=1)
self.blocks_conv = nn.Sequential(
Resblock(channels=out_channels, hidden_channels=out_channels//2),
BasicConv(out_channels, out_channels, kernel_size=1)
)
self.concat_conv = BasicConv(out_channels*2, out_channels, kernel_size=1)
else:
self.split_conv0 = BasicConv(out_channels, out_channels//2, kernel_size=1)
self.split_conv1 = BasicConv(out_channels, out_channels//2, kernel_size=1)
self.blocks_conv = nn.Sequential(
*[Resblock(channels=out_channels//2) for _ in range(num_blocks)],
BasicConv(out_channels//2, out_channels//2, kernel_size=1)
)
self.concat_conv = BasicConv(out_channels, out_channels, kernel_size=1)
def forward(self, x):
x = self.downsample_conv(x)
x0 = self.split_conv0(x)
x1 = self.split_conv1(x)
x1 = self.blocks_conv(x1)
x = torch.cat([x1, x0], dim=1)
x = self.concat_conv(x)
return x

#CSPDarkNet([1,2,8,8,4])

CSPDarkNet网络由多个CSP模块组成,特征通道数为[1,2,8,8,4]。其结构包括:

  • 初始卷积层conv1
  • 多个CSP模块(包括Resblock_body)
  • 最终输出层
  • class CSPDarkNet(nn.Module):
    def __init__(self, layers):
    super(CSPDarkNet, self).__init__()
    self.inplanes = 32
    self.conv1 = BasicConv(3, self.inplanes, kernel_size=3, stride=1)
    self.feature_channels = [64, 128, 256, 512, 1024]
    self.stages = nn.ModuleList([
    Resblock_body(self.inplanes, self.feature_channels[0], layers[0], first=True),
    Resblock_body(self.feature_channels[0], self.feature_channels[1], layers[1], first=False),
    Resblock_body(self.feature_channels[1], self.feature_channels[2], layers[2], first=False),
    Resblock_body(self.feature_channels[2], self.feature_channels[3], layers[3], first=False),
    Resblock_body(self.feature_channels[3], self.feature_channels[4], layers[4], first=False)
    ])
    self.num_features = 1
    #权值初始化
    for m in self.modules():
    if isinstance(m, nn.Conv2d):
    n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
    m.weight.data.normal_(0, math.sqrt(2. / n))
    elif isinstance(m, nn.BatchNorm2d):
    m.weight.data.fill_(1)
    m.bias.data.zero_()
    def forward(self, x):
    x = self.conv1(x)
    x = self.stages[0](x)
    x = self.stages[1](x)
    out3 = self.stages[2](x)
    out4 = self.stages[3](out3)
    out5 = self.stages[4](out4)
    return out3, out4, out5

    #测试

    可以通过以下代码测试CSPDarkNet网络:

    # 随机生成输入数据
    rgb = torch.randn(1, 3, 608, 608)
    # 定义网络backbone
    backbone = darknet53()
    # 前向传播
    out = backbone(rgb)
    # 打印输出大小
    print('-----'*5)
    print(out[0].shape)
    print('-----'*5)
    print(out[1].shape)
    print('-----'*5)
    print(out[2].shape)
    print('-----'*5)
    上一篇:Neck和Head
    下一篇:卷积块CBM(conv+batchnorm+mish)

    发表评论

    最新留言

    关注你微信了!
    [***.104.42.241]2025年04月13日 08时23分34秒