构造任意层数的金字塔(pytorch)

code

import torch
import torch.nn as nn
import torch.nn.functional as F


class ConvBnReLU(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride, padding, bias=True, dilation=1):
        super(ConvBnReLU, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding, bias=bias, dilation=dilation)
        self.bn = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        return self.relu(self.bn(self.conv(x)))


class FeatureNet(nn.Module):
    def __init__(self, inner_channels):
        super(FeatureNet, self).__init__()

        self.convs, self.inners, self.outputs = [], [], []

        for level in range(len(inner_channels)):
            if level == 0:
                self.convs.append(
                        ConvBnReLU(3, inner_channels[level], 3, 1, 1),)
                self.convs.append(
                    ConvBnReLU(inner_channels[level], inner_channels[level], 3, 1, 1),)

            else:
                self.convs.append(ConvBnReLU(inner_channels[level-1], inner_channels[level], 5, 2, 2),)
                self.convs.append(ConvBnReLU(inner_channels[level], inner_channels[level], 3, 1, 1),)
                self.convs.append(ConvBnReLU(inner_channels[level], inner_channels[level], 3, 1, 1),)
                self.outputs.append(nn.Conv2d(inner_channels[-1], inner_channels[level], 1, bias=False))

                if level != len(inner_channels)-1:
                    self.inners.append(nn.Conv2d(inner_channels[level], inner_channels[-1], 1, bias=True))

        self.inners.reverse()
        self.outputs.reverse()

        self.convs = nn.Sequential(*self.convs)
        self.inners = nn.Sequential(*self.inners)
        self.outputs = nn.Sequential(*self.outputs)

    def forward(self, x) :

        convx, outx = [], []
        for i, layer in enumerate(self.convs.children()):
            x = layer(x)
            if i == 1 or i%3 ==1:
                convx.append(x)

        convx.reverse()

        inner = convx[0]
        for level, x in enumerate(convx):
            if level == 0:
                outx.append(self.outputs[level](x))
            elif level != len(convx)-1:
                inner = F.interpolate(inner, scale_factor=2.0, mode="bilinear", align_corners=False)\
                            + self.inners[level-1](x)
                outx.append(self.outputs[level](inner))
            else:
                outx.append(x)

        outx.reverse()

        return outx #conv1, f1, f2, f3


if __name__=="__main__":
    x = torch.randint(1,255,(1,3,128,160)).float()
    net1 =  FeatureNet(inner_channels=[8, 16, 32, 64])
    net2 =  FeatureNet(inner_channels=[8, 16, 32, 64, 128])

    # print(net)
    outs1 = net1(x)
    outs2 = net2(x)

    for y in outs1:
        print(y.shape)

    for y in outs2:
        print(y.shape)

result

torch.Size([1, 8, 128, 160])
torch.Size([1, 16, 64, 80])
torch.Size([1, 32, 32, 40])
torch.Size([1, 64, 16, 20])
torch.Size([1, 8, 128, 160])
torch.Size([1, 16, 64, 80])
torch.Size([1, 32, 32, 40])
torch.Size([1, 64, 16, 20])
torch.Size([1, 128, 8, 10])

注:
网络构建好后,测试__init__()中的层是否可以被print出来,如果不能,无法加载到gpu

### 改进 ASPP 模块中空洞卷积的速率 在语义分割任务中,ASPP(Atrous Spatial Pyramid Pooling)模块通过多尺度上下文聚合来增强模型的表现力。然而,默认设置下的空洞卷积率可能并不总是最优的选择。为了优化这些参数并提升性能,可以从以下几个方面入手: #### 调整空洞比率配置 不同场景下最佳的空洞比例会有所差异。研究发现,在训练 DeepLab-LargeFOV 模型时,“poly” 学习策略相较于 “step” 更加高效[^2]。因此建议尝试多种组合方式,并结合具体数据集特点调整空洞卷积的具体数值。 #### 引入动态调节机制 考虑到图像内部结构复杂度不一的情况,固定不变的膨胀系数难以适应所有情况。为此可以在原有基础上引入自适应或可切换式的空洞卷积方案。例如,在目标检测领域提出的 Switchable Atrous Convolution 可根据不同位置自动选取合适的空洞级别来进行特征提取[^4]。这种方法不仅能够更好地捕捉物体边界信息,还能减少计算资源消耗。 #### 增强局部感受野覆盖范围 除了改变单个卷积核内的间距外,还可以考虑扩大整个网络的感受野面积。比如 ESPNet 中提到的有效空间金字塔结构就很好地解决了这一问题——通过对输入图片应用一系列具有渐增扩张因子的空间池化操作,使得最终输出具备更广泛的视野效果[^1]。 ```python import torch.nn as nn class OptimizedASPP(nn.Module): def __init__(self, in_channels, out_channels, rates=[6, 12, 18]): super(OptimizedASPP, self).__init__() # 定义多个带有不同空洞率的平行分支 self.branches = nn.ModuleList([ nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=3, dilation=rates[i], padding=rates[i]) for i in range(len(rates)) ]) def forward(self, x): outputs = [] for branch in self.branches: output = branch(x) outputs.append(output) return sum(outputs) model = OptimizedASPP(256, 128).cuda() input_tensor = torch.randn((1, 256, 64, 64)).cuda() output = model(input_tensor) print(f'Output shape: {output.shape}') ``` 上述代码展示了如何构建一个经过优化后的 ASPP 层实例。这里定义了一个 `OptimizedASPP` 类继承自 PyTorch 的 Module 并实现了前向传播逻辑。该实现允许用户指定任意数量的不同空洞率作为输入参数列表传递给构造函数,从而灵活控制各个子路径之间的关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值