Beispiel #1
0
def test_aspp():
    # test aspp with normal conv
    aspp = ASPP(128, out_channels=512, mid_channels=128, dilations=(6, 12, 18))
    assert aspp.convs[0].activate.__class__.__name__ == 'ReLU'
    assert aspp.convs[0].conv.out_channels == 128
    assert aspp.convs[1].__class__.__name__ == 'ConvModule'
    for conv_idx in range(1, 4):
        assert aspp.convs[conv_idx].conv.dilation[0] == 6 * conv_idx
    x = torch.rand(2, 128, 8, 8)
    output = aspp(x)
    assert output.shape == (2, 512, 8, 8)

    # test aspp with separable conv
    aspp = ASPP(128, separable_conv=True)
    assert aspp.convs[1].__class__.__name__ == 'DepthwiseSeparableConvModule'
    x = torch.rand(2, 128, 8, 8)
    output = aspp(x)
    assert output.shape == (2, 256, 8, 8)

    # test aspp with ReLU6
    aspp = ASPP(128, dilations=(12, 24, 36), act_cfg=dict(type='ReLU6'))
    assert aspp.convs[0].activate.__class__.__name__ == 'ReLU6'
    for conv_idx in range(1, 4):
        assert aspp.convs[conv_idx].conv.dilation[0] == 12 * conv_idx
    x = torch.rand(2, 128, 8, 8)
    output = aspp(x)
    assert output.shape == (2, 256, 8, 8)
Beispiel #2
0
    def __init__(self,
                 in_channels,
                 batch_norm=False,
                 aspp=False,
                 dilations=None):
        super(VGG16, self).__init__()
        self.batch_norm = batch_norm
        self.aspp = aspp
        self.dilations = dilations

        self.layer1 = self._make_layer(in_channels, 64, 2)
        self.layer2 = self._make_layer(64, 128, 2)
        self.layer3 = self._make_layer(128, 256, 3)
        self.layer4 = self._make_layer(256, 512, 3)
        self.layer5 = self._make_layer(512, 512, 3)

        self.conv6 = nn.Conv2d(512, 512, kernel_size=1)
        if self.batch_norm:
            self.bn = nn.BatchNorm2d(512)
        self.relu = nn.ReLU(inplace=True)

        if self.aspp:
            self.aspp = ASPP(512, dilations=self.dilations)
            self.out_channels = 256
        else:
            self.out_channels = 512
Beispiel #3
0
    def __init__(self,
                 in_channels,
                 out_stride=32,
                 width_mult=1,
                 index_mode='m2o',
                 aspp=True,
                 norm_cfg=dict(type='BN'),
                 freeze_bn=False,
                 use_nonlinear=True,
                 use_context=True):
        super().__init__()
        if out_stride not in [16, 32]:
            raise ValueError(f'out_stride must 16 or 32, got {out_stride}')

        self.out_stride = out_stride
        self.width_mult = width_mult

        # we name the index network in the paper index_block
        if index_mode == 'holistic':
            index_block = HolisticIndexBlock
        elif index_mode in ('o2o', 'm2o'):
            index_block = partial(DepthwiseIndexBlock, mode=index_mode)
        else:
            raise NameError('Unknown index block mode {}'.format(index_mode))

        # default setting
        initial_channels = 32
        inverted_residual_setting = [
            # expand_ratio, input_chn, output_chn, num_blocks, stride, dilation
            [1, initial_channels, 16, 1, 1, 1],
            [6, 16, 24, 2, 2, 1],
            [6, 24, 32, 3, 2, 1],
            [6, 32, 64, 4, 2, 1],
            [6, 64, 96, 3, 1, 1],
            [6, 96, 160, 3, 2, 1],
            [6, 160, 320, 1, 1, 1],
        ]

        # update layer setting according to width_mult
        initial_channels = int(initial_channels * width_mult)
        for layer_setting in inverted_residual_setting:
            # update in_channels and out_channels
            layer_setting[1] = int(layer_setting[1] * self.width_mult)
            layer_setting[2] = int(layer_setting[2] * self.width_mult)

        if out_stride == 32:
            # It should be noted that layers 0 is not an InvertedResidual layer
            # but a ConvModule. Thus, the index of InvertedResidual layer in
            # downsampled_layers starts at 1.
            self.downsampled_layers = [0, 2, 3, 4, 6]
        else:  # out_stride is 16
            self.downsampled_layers = [0, 2, 3, 4]
            # if out_stride is 16, then increase the dilation of the last two
            # InvertedResidual layer to increase the receptive field
            inverted_residual_setting[5][5] = 2
            inverted_residual_setting[6][5] = 2

        # build the first layer
        self.layers = nn.ModuleList([
            ConvModule(in_channels,
                       initial_channels,
                       3,
                       padding=1,
                       norm_cfg=norm_cfg,
                       act_cfg=dict(type='ReLU6'))
        ])
        # build bottleneck layers
        for layer_setting in inverted_residual_setting:
            self.layers.append(self._make_layer(layer_setting, norm_cfg))

        # freeze encoder batch norm layers
        if freeze_bn:
            self.freeze_bn()

        # build index blocks
        self.index_layers = nn.ModuleList()
        for layer in self.downsampled_layers:
            # inverted_residual_setting begins at layer1, the in_channels
            # of layer1 is the out_channels of layer0
            self.index_layers.append(
                index_block(inverted_residual_setting[layer][1], norm_cfg,
                            use_context, use_nonlinear))
        self.avg_pool = nn.AvgPool2d(2, stride=2)

        if aspp:
            dilation = (2, 4, 8) if out_stride == 32 else (6, 12, 18)
            self.dconv = ASPP(320 * self.width_mult,
                              160,
                              mid_channels=int(256 * self.width_mult),
                              dilations=dilation,
                              norm_cfg=norm_cfg,
                              act_cfg=dict(type='ReLU6'),
                              separable_conv=True)
        else:
            self.dconv = ConvModule(320 * self.width_mult,
                                    160,
                                    1,
                                    norm_cfg=norm_cfg,
                                    act_cfg=dict(type='ReLU6'))

        self.out_channels = 160