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)) ]
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
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)
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)
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)
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)