Exemple #1
0
def DFConv3x3(in_channels, out_channels, module_name, postfix, stride=1, groups=1, kernel_size=3, 
                with_modulated_dcn=None, deformable_groups=None):
    """3x3 convolution with padding"""
    return [
        (f'{module_name}_{postfix}/conv',
         DFConv2d(in_channels, out_channels, with_modulated_dcn=with_modulated_dcn,
            kernel_size=kernel_size, stride=stride, groups=groups, 
            deformable_groups=deformable_groups, bias=False)),
        (f'{module_name}_{postfix}/norm',
            group_norm(out_channels) if _GN else FrozenBatchNorm2d(out_channels)
        ),
        (f'{module_name}_{postfix}/relu', nn.ReLU(inplace=True))
    ]
Exemple #2
0
def make_blocks(
    layers,
    input_size,
    pattern='',
    parent=None,
    dilation=1,
    use_gn=True,
    use_dcn=False,
    dcn_config={},
):
    next_feature = input_size
    blocks = []
    for layer_idx, layer_features in enumerate(layers, 1):
        layer_name = pattern + "{}".format(layer_idx)
        if use_dcn:
            module = DFConv2d(
                next_feature,
                layer_features,
                with_modulated_dcn=dcn_config.get("with_modulated_dcn", False),
                kernel_size=3,
                stride=1,
                groups=1,
                dilation=dilation,
                deformable_groups=dcn_config.get("deformable_groups", 1),
                bias=False if use_gn else True,
            )
            module = [
                module,
            ]
            if use_gn:
                module.append(group_norm(layer_features))
            module.append(nn.ReLU(inplace=True))
            if len(module) > 1:
                module = nn.Sequential(*module)
        else:
            module = make_conv3x3(next_feature,
                                  layer_features,
                                  dilation=dilation,
                                  stride=1,
                                  use_gn=use_gn,
                                  use_relu=True)
        if parent is not None:
            parent.add_module(layer_name, module)
        next_feature = layer_features
        blocks.append(layer_name)
    return blocks, next_feature
Exemple #3
0
    def __init__(self,
                 inplanes,
                 outplanes,
                 stride=1,
                 dilation=1,
                 cardinality=1,
                 base_width=64,
                 batch_norm=FrozenBatchNorm2d,
                 with_dcn=False):
        super(DlaBottleneck, self).__init__()
        self.stride = stride
        mid_planes = int(
            math.floor(outplanes * (base_width / 64)) * cardinality)
        mid_planes = mid_planes // self.expansion

        self.conv1 = Conv2d(inplanes, mid_planes, kernel_size=1, bias=False)
        self.bn1 = batch_norm(mid_planes)
        if with_dcn:
            self.conv2 = DFConv2d(mid_planes,
                                  mid_planes,
                                  with_modulated_dcn=False,
                                  kernel_size=3,
                                  stride=stride,
                                  bias=False,
                                  dilation=dilation,
                                  groups=cardinality)
        else:
            self.conv2 = Conv2d(mid_planes,
                                mid_planes,
                                kernel_size=3,
                                stride=stride,
                                padding=dilation,
                                bias=False,
                                dilation=dilation,
                                groups=cardinality)
        self.bn2 = batch_norm(mid_planes)
        self.conv3 = Conv2d(mid_planes, outplanes, kernel_size=1, bias=False)
        self.bn3 = batch_norm(outplanes)
        self.relu = nn.ReLU(inplace=True)
Exemple #4
0
 def make_deconv(in_channels,
                 out_channels,
                 kernel_size=3,
                 stride=1,
                 dilation=1):
     deconv = DFConv2d(in_channels,
                       out_channels,
                       with_modulated_dcn=False,
                       kernel_size=kernel_size,
                       stride=stride,
                       groups=1,
                       dilation=dilation,
                       deformable_groups=1,
                       bias=False)
     module = [
         deconv,
     ]
     if use_gn:
         module.append(group_norm(out_channels))
     if use_relu:
         module.append(nn.ReLU(inplace=True))
     if len(module) > 1:
         return nn.Sequential(*module)
Exemple #5
0
    def __init__(self, in_channels, bottleneck_channels, out_channels,
                 num_groups, stride_in_1x1, stride, dilation, norm_func,
                 dcn_config):
        super(Bottleneck, self).__init__()

        self.downsample = None
        if in_channels != out_channels:
            down_stride = stride if dilation == 1 else 1
            self.downsample = nn.Sequential(
                Conv2d(in_channels,
                       out_channels,
                       kernel_size=1,
                       stride=down_stride,
                       bias=False),
                norm_func(out_channels),
            )
            for modules in [
                    self.downsample,
            ]:
                for l in modules.modules():
                    if isinstance(l, Conv2d):
                        nn.init.kaiming_uniform_(l.weight, a=1)

        if dilation > 1:
            stride = 1  # reset to be 1

        # The original MSRA ResNet models have stride in the first 1x1 conv
        # The subsequent fb.torch.resnet and Caffe2 ResNe[X]t implementations have
        # stride in the 3x3 conv
        stride_1x1, stride_3x3 = (stride, 1) if stride_in_1x1 else (1, stride)

        self.conv1 = Conv2d(
            in_channels,
            bottleneck_channels,
            kernel_size=1,
            stride=stride_1x1,
            bias=False,
        )
        self.bn1 = norm_func(bottleneck_channels)
        # TODO: specify init for the above
        with_dcn = dcn_config.get("stage_with_dcn", False)
        if with_dcn:
            deformable_groups = dcn_config.get("deformable_groups", 1)
            with_modulated_dcn = dcn_config.get("with_modulated_dcn", False)
            self.conv2 = DFConv2d(bottleneck_channels,
                                  bottleneck_channels,
                                  with_modulated_dcn=with_modulated_dcn,
                                  kernel_size=3,
                                  stride=stride_3x3,
                                  groups=num_groups,
                                  dilation=dilation,
                                  deformable_groups=deformable_groups,
                                  bias=False)
        else:
            self.conv2 = Conv2d(bottleneck_channels,
                                bottleneck_channels,
                                kernel_size=3,
                                stride=stride_3x3,
                                padding=dilation,
                                bias=False,
                                groups=num_groups,
                                dilation=dilation)
            nn.init.kaiming_uniform_(self.conv2.weight, a=1)

        self.bn2 = norm_func(bottleneck_channels)

        self.conv3 = Conv2d(bottleneck_channels,
                            out_channels,
                            kernel_size=1,
                            bias=False)
        self.bn3 = norm_func(out_channels)

        for l in [
                self.conv1,
                self.conv3,
        ]:
            nn.init.kaiming_uniform_(l.weight, a=1)
Exemple #6
0
    def __init__(self, in_channels, bottleneck_channels, out_channels,
                 num_groups, stride_in_1x1, stride, dilation, norm_func,
                 dcn_config, dw_config):
        super(Bottleneck, self).__init__()

        self.downsample = None
        if in_channels != out_channels:
            down_stride = stride if dilation == 1 else 1
            self.downsample = nn.Sequential(
                Conv2d(in_channels,
                       out_channels,
                       kernel_size=1,
                       stride=down_stride,
                       bias=False),
                norm_func(out_channels),
            )
            for modules in [
                    self.downsample,
            ]:
                for l in modules.modules():
                    if isinstance(l, Conv2d):
                        nn.init.kaiming_uniform_(l.weight, a=1)

        if dilation > 1:
            stride = 1  # reset to be 1

        # The original MSRA ResNet models have stride in the first 1x1 conv
        # The subsequent fb.torch.resnet and Caffe2 ResNe[X]t implementations have
        # stride in the 3x3 conv
        stride_1x1, stride_3x3 = (stride, 1) if stride_in_1x1 else (1, stride)

        self.conv1 = Conv2d(
            in_channels,
            bottleneck_channels,
            kernel_size=1,
            stride=stride_1x1,
            bias=False,
        )
        self.bn1 = norm_func(bottleneck_channels)
        # TODO: specify init for the above
        with_dcn = dcn_config.get("stage_with_dcn", False)
        if with_dcn:
            deformable_groups = dcn_config.get("deformable_groups", 1)
            with_modulated_dcn = dcn_config.get("with_modulated_dcn", False)
            self.conv2 = DFConv2d(bottleneck_channels,
                                  bottleneck_channels,
                                  with_modulated_dcn=with_modulated_dcn,
                                  kernel_size=3,
                                  stride=stride_3x3,
                                  groups=num_groups,
                                  dilation=dilation,
                                  deformable_groups=deformable_groups,
                                  bias=False)
        else:
            self.conv2 = Conv2d(bottleneck_channels,
                                bottleneck_channels,
                                kernel_size=3,
                                stride=stride_3x3,
                                padding=dilation,
                                bias=False,
                                groups=num_groups,
                                dilation=dilation)
            nn.init.kaiming_uniform_(self.conv2.weight, a=1)

        self.bn2 = norm_func(bottleneck_channels)

        self.conv3 = Conv2d(bottleneck_channels,
                            out_channels,
                            kernel_size=1,
                            bias=False)
        self.bn3 = norm_func(out_channels)
        self.with_dw = dw_config.get("stage_with_dw", False)
        if self.with_dw:
            self.insert_pos = dw_config.get('insert_pos', 'after1x1')
            assert self.insert_pos in ['after1x1', 'after3x3', 'afterAdd']
            if self.insert_pos == 'afterAdd':
                dw_block = DynamicWeightsCat11
                dw_channels = out_channels
            elif self.insert_pos == 'after3x3':
                dw_block = ReDynamicWeightsCat33  #ReDynamicWeightsCat33, DeformDGMN
                dw_channels = bottleneck_channels
            dw_group = dw_config.get('group', 1)
            dw_kernel = dw_config.get('kernel', 3)
            dw_dilation = dw_config.get('dilation', (1, 4, 8, 12))
            dw_shuffle = dw_config.get('shuffle', False)
            dw_deform = dw_config.get('deform', 'none')
            self.dw_block = dw_block(channels=dw_channels,
                                     group=dw_group,
                                     kernel=dw_kernel,
                                     dilation=dw_dilation,
                                     shuffle=dw_shuffle,
                                     deform=dw_deform)
        else:
            self.dw_block = None

        for l in [
                self.conv1,
                self.conv3,
        ]:
            nn.init.kaiming_uniform_(l.weight, a=1)
    def __init__(
        self,
        in_channels,
        bottleneck_channels,
        out_channels,
        num_groups=1,
        stride_in_1x1=True,
        stride=1,
        dilation=1,
        dcn_config={},
        use_se=False,
        ):
        super(BasicWithFixedBatchNorm, self).__init__()
        self.downsample = None
        assert dilation == 1
        norm_func = frozen_batch_norm
        if in_channels != out_channels:
            down_stride = stride if dilation == 1 else 1
            self.downsample = nn.Sequential(
                Conv2d(
                    in_channels, out_channels,
                    kernel_size=1, stride=down_stride, bias=False
                ),
                norm_func(out_channels),
            )
            for modules in [self.downsample,]:
                for l in modules.modules():
                    if isinstance(l, Conv2d):
                        nn.init.kaiming_uniform_(l.weight, a=1)

        if dilation > 1:
            # copied from BottleNet.
            stride = 1 # reset to be 1
        self.conv1 = conv3x3(in_channels, out_channels, stride)
        self.bn1 = norm_func(out_channels)
        self.relu = nn.ReLU(inplace=True)

        with_dcn = dcn_config.get("stage_with_dcn", False)
        if with_dcn:
            deformable_groups = dcn_config.get("deformable_groups", 1)
            with_modulated_dcn = dcn_config.get("with_modulated_dcn", False)
            self.conv2 = DFConv2d(
                out_channels,
                out_channels,
                with_modulated_dcn=with_modulated_dcn,
                kernel_size=3,
                stride=1,
                groups=num_groups,
                dilation=dilation,
                deformable_groups=deformable_groups,
                bias=False,
            )
        else:
            self.conv2 = conv3x3(out_channels, out_channels,
                    groups=num_groups)
            nn.init.kaiming_uniform_(self.conv2.weight, a=1)

        self.bn2 = norm_func(out_channels)
        self.stride = stride

        if use_se:
            from mtorch.seresnext import SEResNext
            self.seblock = SEResNext.SEBlock(out_channels, reduction_ratio=16)
            for l in [self.seblock.fc0, self.seblock.fc1,]:
                nn.init.kaiming_uniform_(l.weight, a=1)
                nn.init.zeros_(l.bias)
        else:
            self.seblock = None

        for l in [self.conv1,]:
            nn.init.kaiming_uniform_(l.weight, a=1)
    def __init__(self, cfg, in_channels):
        """
        Arguments:
            in_channels (int): number of channels of the input feature
            num_anchors (int): number of anchors to be predicted
        """
        super(DCN_RetinaNetHead, self).__init__()
        # TODO: Implement the sigmoid version first.
        self.factor = cfg.MODEL.DCN.BRANCH_FACTOR
        num_classes = cfg.MODEL.RETINANET.NUM_CLASSES - 1
        num_anchors = len(cfg.MODEL.RETINANET.ASPECT_RATIOS) \
                      * cfg.MODEL.RETINANET.SCALES_PER_OCTAVE

        self.num_branch = num_anchors
        cls_branch = []

        for branch in range(self.num_branch):
            # first 256-32 dcn
            for i in range(cfg.MODEL.RETINANET.NUM_CONVS - 1):
                cls_branch.append(
                    nn.Conv2d(in_channels,
                              in_channels,
                              kernel_size=3,
                              stride=1,
                              padding=1))
                cls_branch.append(nn.ReLU())

            cls_branch.append(
                DFConv2d(in_channels,
                         in_channels,
                         kernel_size=3,
                         stride=1,
                         with_modulated_dcn=False,
                         need_offset=True))
            cls_branch.append(nn.ReLU())
            # second-forth 32-32 dcn
            #             for i in range(cfg.MODEL.RETINANET.NUM_CONVS - 1):
            #                 cls_branch.append(
            #                     DFConv2d(
            #                         in_channels // self.factor,
            #                         in_channels // self.factor,
            #                         kernel_size=3,
            #                         stride=1,
            #                         with_modulated_dcn=False,
            #                         need_offset=True
            #                     )
            #                 )
            #                 cls_branch.append(nn.ReLU())
            # cls_logits
            cls_branch.append(
                nn.Conv2d(in_channels,
                          1 * num_classes,
                          kernel_size=3,
                          stride=1,
                          padding=1))
            self.add_module('cls_branch_{:d}'.format(branch),
                            nn.Sequential(*cls_branch))

            # Initialization
            m = getattr(self, "cls_branch_" + str(branch))
            for module in m:
                if isinstance(module, nn.Conv2d):
                    torch.nn.init.normal_(module.weight, std=0.01)
                    torch.nn.init.constant_(module.bias, 0)
            cls_branch = []

        # No initialization because DFConv2d has been initialization in the DFConv2d.py

        # retinanet_bias_init
        for branch in range(self.num_branch):
            # the last one is cls_logits
            m = getattr(self, "cls_branch_" + str(branch))
            prior_prob = cfg.MODEL.RETINANET.PRIOR_PROB
            bias_value = -math.log((1 - prior_prob) / prior_prob)
            torch.nn.init.constant_(m[-1].bias, bias_value)