Ejemplo n.º 1
0
    def __init__(self,
                 in_channels,
                 sparse_shape,
                 order=('conv', 'norm', 'act'),
                 norm_cfg=dict(type='BN1d', eps=1e-3, momentum=0.01),
                 base_channels=16,
                 output_channels=128,
                 encoder_channels=((16, ), (32, 32, 32), (64, 64, 64), (64, 64,
                                                                        64)),
                 encoder_paddings=((1, ), (1, 1, 1), (1, 1, 1), ((0, 1, 1), 1,
                                                                 1)),
                 block_type='conv_module'):
        super().__init__()
        assert block_type in ['conv_module', 'basicblock']
        self.sparse_shape = sparse_shape
        self.in_channels = in_channels
        self.order = order
        self.base_channels = base_channels
        self.output_channels = output_channels
        self.encoder_channels = encoder_channels
        self.encoder_paddings = encoder_paddings
        self.stage_num = len(self.encoder_channels)
        self.fp16_enabled = False
        # Spconv init all weight on its own

        assert isinstance(order, tuple) and len(order) == 3
        assert set(order) == {'conv', 'norm', 'act'}

        if self.order[0] != 'conv':  # pre activate
            self.conv_input = make_sparse_convmodule(in_channels,
                                                     self.base_channels,
                                                     3,
                                                     norm_cfg=norm_cfg,
                                                     padding=1,
                                                     indice_key='subm1',
                                                     conv_type='SubMConv3d',
                                                     order=('conv', ))
        else:  # post activate
            self.conv_input = make_sparse_convmodule(in_channels,
                                                     self.base_channels,
                                                     3,
                                                     norm_cfg=norm_cfg,
                                                     padding=1,
                                                     indice_key='subm1',
                                                     conv_type='SubMConv3d')

        encoder_out_channels = self.make_encoder_layers(make_sparse_convmodule,
                                                        norm_cfg,
                                                        self.base_channels,
                                                        block_type=block_type)

        self.conv_out = make_sparse_convmodule(encoder_out_channels,
                                               self.output_channels,
                                               kernel_size=(3, 1, 1),
                                               stride=(2, 1, 1),
                                               norm_cfg=norm_cfg,
                                               padding=0,
                                               indice_key='spconv_down2',
                                               conv_type='SparseConv3d')
Ejemplo n.º 2
0
def test_make_sparse_convmodule():
    from mmdet3d.ops import make_sparse_convmodule

    voxel_features = torch.tensor([[6.56126, 0.9648336, -1.7339306, 0.315],
                                   [6.8162713, -2.480431, -1.3616394, 0.36],
                                   [11.643568, -4.744306, -1.3580885, 0.16],
                                   [23.482342, 6.5036807, 0.5806964, 0.35]],
                                  dtype=torch.float32)  # n, point_features
    coordinates = torch.tensor(
        [[0, 12, 819, 131], [0, 16, 750, 136], [1, 16, 705, 232],
         [1, 35, 930, 469]],
        dtype=torch.int32)  # n, 4(batch, ind_x, ind_y, ind_z)

    # test
    input_sp_tensor = spconv.SparseConvTensor(voxel_features, coordinates,
                                              [41, 1600, 1408], 2)

    sparse_block0 = make_sparse_convmodule(4,
                                           16,
                                           3,
                                           'test0',
                                           stride=1,
                                           padding=0,
                                           conv_type='SubMConv3d',
                                           norm_cfg=dict(type='BN1d',
                                                         eps=1e-3,
                                                         momentum=0.01),
                                           order=('conv', 'norm', 'act'))
    assert isinstance(sparse_block0[0], spconv.SubMConv3d)
    assert sparse_block0[0].in_channels == 4
    assert sparse_block0[0].out_channels == 16
    assert isinstance(sparse_block0[1], torch.nn.BatchNorm1d)
    assert sparse_block0[1].eps == 0.001
    assert sparse_block0[1].momentum == 0.01
    assert isinstance(sparse_block0[2], torch.nn.ReLU)

    # test forward
    out_features = sparse_block0(input_sp_tensor)
    assert out_features.features.shape == torch.Size([4, 16])

    sparse_block1 = make_sparse_convmodule(4,
                                           16,
                                           3,
                                           'test1',
                                           stride=1,
                                           padding=0,
                                           conv_type='SparseInverseConv3d',
                                           norm_cfg=dict(type='BN1d',
                                                         eps=1e-3,
                                                         momentum=0.01),
                                           order=('norm', 'act', 'conv'))
    assert isinstance(sparse_block1[0], torch.nn.BatchNorm1d)
    assert isinstance(sparse_block1[1], torch.nn.ReLU)
    assert isinstance(sparse_block1[2], spconv.SparseInverseConv3d)
def test_make_sparse_convmodule():
    with pytest.raises(AssertionError):
        # assert invalid order setting
        make_sparse_convmodule(
            in_channels=4,
            out_channels=8,
            kernel_size=3,
            indice_key='rcnn_part2',
            norm_cfg=dict(type='BN1d'),
            order=('norm', 'act', 'conv', 'norm'))

        # assert invalid type of order
        make_sparse_convmodule(
            in_channels=4,
            out_channels=8,
            kernel_size=3,
            indice_key='rcnn_part2',
            norm_cfg=dict(type='BN1d'),
            order=['norm', 'conv'])

        # assert invalid elements of order
        make_sparse_convmodule(
            in_channels=4,
            out_channels=8,
            kernel_size=3,
            indice_key='rcnn_part2',
            norm_cfg=dict(type='BN1d'),
            order=('conv', 'normal', 'activate'))

    sparse_convmodule = make_sparse_convmodule(
        in_channels=4,
        out_channels=64,
        kernel_size=3,
        padding=1,
        indice_key='rcnn_part0',
        norm_cfg=dict(type='BN1d', eps=0.001, momentum=0.01))

    assert isinstance(sparse_convmodule[0], SubMConv3d)
    assert isinstance(sparse_convmodule[1], BatchNorm1d)
    assert isinstance(sparse_convmodule[2], ReLU)
    assert sparse_convmodule[1].num_features == 64
    assert sparse_convmodule[1].eps == 0.001
    assert sparse_convmodule[1].affine is True
    assert sparse_convmodule[1].track_running_stats is True
    assert isinstance(sparse_convmodule[2], ReLU)
    assert sparse_convmodule[2].inplace is True

    pre_act = make_sparse_convmodule(
        in_channels=4,
        out_channels=8,
        kernel_size=3,
        indice_key='rcnn_part1',
        norm_cfg=dict(type='BN1d'),
        order=('norm', 'act', 'conv'))
    assert isinstance(pre_act[0], BatchNorm1d)
    assert isinstance(pre_act[1], ReLU)
    assert isinstance(pre_act[2], SubMConv3d)
Ejemplo n.º 4
0
    def __init__(self,
                 num_classes,
                 seg_in_channels,
                 part_in_channels,
                 seg_conv_channels=None,
                 part_conv_channels=None,
                 merge_conv_channels=None,
                 down_conv_channels=None,
                 shared_fc_channels=None,
                 cls_channels=None,
                 reg_channels=None,
                 dropout_ratio=0.1,
                 roi_feat_size=14,
                 with_corner_loss=True,
                 bbox_coder=dict(type='DeltaXYZWLHRBBoxCoder'),
                 conv_cfg=dict(type='Conv1d'),
                 norm_cfg=dict(type='BN1d', eps=1e-3, momentum=0.01),
                 loss_bbox=dict(type='SmoothL1Loss',
                                beta=1.0 / 9.0,
                                loss_weight=2.0),
                 loss_cls=dict(type='CrossEntropyLoss',
                               use_sigmoid=True,
                               reduction='none',
                               loss_weight=1.0)):
        super(PartA2BboxHead, self).__init__()
        self.num_classes = num_classes
        self.with_corner_loss = with_corner_loss
        self.bbox_coder = build_bbox_coder(bbox_coder)
        self.loss_bbox = build_loss(loss_bbox)
        self.loss_cls = build_loss(loss_cls)
        self.use_sigmoid_cls = loss_cls.get('use_sigmoid', False)

        assert down_conv_channels[-1] == shared_fc_channels[0]

        # init layers
        part_channel_last = part_in_channels
        part_conv = []
        for i, channel in enumerate(part_conv_channels):
            part_conv.append(
                make_sparse_convmodule(part_channel_last,
                                       channel,
                                       3,
                                       padding=1,
                                       norm_cfg=norm_cfg,
                                       indice_key=f'rcnn_part{i}',
                                       conv_type='SubMConv3d'))
            part_channel_last = channel
        self.part_conv = spconv.SparseSequential(*part_conv)

        seg_channel_last = seg_in_channels
        seg_conv = []
        for i, channel in enumerate(seg_conv_channels):
            seg_conv.append(
                make_sparse_convmodule(seg_channel_last,
                                       channel,
                                       3,
                                       padding=1,
                                       norm_cfg=norm_cfg,
                                       indice_key=f'rcnn_seg{i}',
                                       conv_type='SubMConv3d'))
            seg_channel_last = channel
        self.seg_conv = spconv.SparseSequential(*seg_conv)

        self.conv_down = spconv.SparseSequential()

        merge_conv_channel_last = part_channel_last + seg_channel_last
        merge_conv = []
        for i, channel in enumerate(merge_conv_channels):
            merge_conv.append(
                make_sparse_convmodule(merge_conv_channel_last,
                                       channel,
                                       3,
                                       padding=1,
                                       norm_cfg=norm_cfg,
                                       indice_key='rcnn_down0'))
            merge_conv_channel_last = channel

        down_conv_channel_last = merge_conv_channel_last
        conv_down = []
        for i, channel in enumerate(down_conv_channels):
            conv_down.append(
                make_sparse_convmodule(down_conv_channel_last,
                                       channel,
                                       3,
                                       padding=1,
                                       norm_cfg=norm_cfg,
                                       indice_key='rcnn_down1'))
            down_conv_channel_last = channel

        self.conv_down.add_module('merge_conv',
                                  spconv.SparseSequential(*merge_conv))
        self.conv_down.add_module(
            'max_pool3d', spconv.SparseMaxPool3d(kernel_size=2, stride=2))
        self.conv_down.add_module('down_conv',
                                  spconv.SparseSequential(*conv_down))

        shared_fc_list = []
        pool_size = roi_feat_size // 2
        pre_channel = shared_fc_channels[0] * pool_size**3
        for k in range(1, len(shared_fc_channels)):
            shared_fc_list.append(
                ConvModule(pre_channel,
                           shared_fc_channels[k],
                           1,
                           padding=0,
                           conv_cfg=conv_cfg,
                           norm_cfg=norm_cfg,
                           inplace=True))
            pre_channel = shared_fc_channels[k]

            if k != len(shared_fc_channels) - 1 and dropout_ratio > 0:
                shared_fc_list.append(nn.Dropout(dropout_ratio))

        self.shared_fc = nn.Sequential(*shared_fc_list)

        # Classification layer
        channel_in = shared_fc_channels[-1]
        cls_channel = 1
        cls_layers = []
        pre_channel = channel_in
        for k in range(0, len(cls_channels)):
            cls_layers.append(
                ConvModule(pre_channel,
                           cls_channels[k],
                           1,
                           padding=0,
                           conv_cfg=conv_cfg,
                           norm_cfg=norm_cfg,
                           inplace=True))
            pre_channel = cls_channels[k]
        cls_layers.append(
            ConvModule(pre_channel,
                       cls_channel,
                       1,
                       padding=0,
                       conv_cfg=conv_cfg,
                       act_cfg=None))
        if dropout_ratio >= 0:
            cls_layers.insert(1, nn.Dropout(dropout_ratio))

        self.conv_cls = nn.Sequential(*cls_layers)

        # Regression layer
        reg_layers = []
        pre_channel = channel_in
        for k in range(0, len(reg_channels)):
            reg_layers.append(
                ConvModule(pre_channel,
                           reg_channels[k],
                           1,
                           padding=0,
                           conv_cfg=conv_cfg,
                           norm_cfg=norm_cfg,
                           inplace=True))
            pre_channel = reg_channels[k]
        reg_layers.append(
            ConvModule(pre_channel,
                       self.bbox_coder.code_size,
                       1,
                       padding=0,
                       conv_cfg=conv_cfg,
                       act_cfg=None))
        if dropout_ratio >= 0:
            reg_layers.insert(1, nn.Dropout(dropout_ratio))

        self.conv_reg = nn.Sequential(*reg_layers)

        self.init_weights()
Ejemplo n.º 5
0
    def __init__(self,
                 in_channels,
                 sparse_shape,
                 order=('conv', 'norm', 'act'),
                 norm_cfg=dict(type='BN1d', eps=1e-3, momentum=0.01),
                 base_channels=16,
                 output_channels=128,
                 encoder_channels=((16, ), (32, 32, 32), (64, 64, 64), (64, 64,
                                                                        64)),
                 encoder_paddings=((1, ), (1, 1, 1), (1, 1, 1), ((0, 1, 1), 1,
                                                                 1)),
                 block_type='conv_module',
                 IMG_CHANNELS=[3, 256, 256, 256, 256],
                 POINT_CHANNELS=[16, 32, 64, 64],
                 ADD_Image_Attention=True):
        super().__init__()
        assert block_type in ['conv_module', 'basicblock']
        self.sparse_shape = sparse_shape
        self.in_channels = in_channels
        self.order = order
        self.base_channels = base_channels
        self.output_channels = output_channels
        self.encoder_channels = encoder_channels
        self.encoder_paddings = encoder_paddings
        self.stage_num = len(self.encoder_channels)
        self.fp16_enabled = False
        self.add_image_attention = ADD_Image_Attention
        # Spconv init all weight on its own

        assert isinstance(order, tuple) and len(order) == 3
        assert set(order) == {'conv', 'norm', 'act'}
        self.Fusion_Conv = nn.ModuleList()
        for i in range(len(IMG_CHANNELS) - 1):
            if self.add_image_attention:
                self.Fusion_Conv.append(
                    Atten_Fusion_Conv(IMG_CHANNELS[i + 1], POINT_CHANNELS[i],
                                      POINT_CHANNELS[i]))

        self.point_fc = nn.Linear(176, 64, bias=False)
        self.point_cls = nn.Linear(64, 1, bias=False)
        self.point_reg = nn.Linear(64, 3, bias=False)

        if self.order[0] != 'conv':  # pre activate
            self.conv_input = make_sparse_convmodule(in_channels,
                                                     self.base_channels,
                                                     3,
                                                     norm_cfg=norm_cfg,
                                                     padding=1,
                                                     indice_key='subm1',
                                                     conv_type='SubMConv3d',
                                                     order=('conv', ))
        else:  # post activate
            self.conv_input = make_sparse_convmodule(in_channels,
                                                     self.base_channels,
                                                     3,
                                                     norm_cfg=norm_cfg,
                                                     padding=1,
                                                     indice_key='subm1',
                                                     conv_type='SubMConv3d')

        encoder_out_channels = self.make_encoder_layers(make_sparse_convmodule,
                                                        norm_cfg,
                                                        self.base_channels,
                                                        block_type=block_type)

        self.conv_out = make_sparse_convmodule(encoder_out_channels,
                                               self.output_channels,
                                               kernel_size=(3, 1, 1),
                                               stride=(2, 1, 1),
                                               norm_cfg=norm_cfg,
                                               padding=0,
                                               indice_key='spconv_down2',
                                               conv_type='SparseConv3d')