Пример #1
0
    def __init__(self, inp, oup, stride, expand_ratio):
        super(InvertedResidual, self).__init__()
        self.stride = stride
        assert stride in [1, 2]

        hidden_dim = int(round(inp * expand_ratio))
        self.use_res_connect = self.stride == 1 and inp == oup

        if expand_ratio == 1:
            self.conv = nn.Sequential(
                # dw
                Conv2d(hidden_dim, hidden_dim, 3, stride, 1, groups=hidden_dim, bias=False),
                BatchNorm2d(hidden_dim),
                nn.ReLU6(inplace=True),
                # pw-linear
                Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
                BatchNorm2d(oup),
            )
        else:
            self.conv = nn.Sequential(
                # pw
                Conv2d(inp, hidden_dim, 1, 1, 0, bias=False),
                BatchNorm2d(hidden_dim),
                nn.ReLU6(inplace=True),
                # dw
                Conv2d(hidden_dim, hidden_dim, 3, stride, 1, groups=hidden_dim, bias=False),
                BatchNorm2d(hidden_dim),
                nn.ReLU6(inplace=True),
                # pw-linear
                Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
                BatchNorm2d(oup),
            )
Пример #2
0
    def __init__(self, C):
        super(SEModule, self).__init__()
        mid = max(C // self.reduction, 8)
        conv1 = Conv2d(C, mid, 1, 1, 0)
        conv2 = Conv2d(mid, C, 1, 1, 0)

        self.op = nn.Sequential(nn.AdaptiveAvgPool2d(1), conv1,
                                nn.ReLU(inplace=True), conv2, nn.Sigmoid())
Пример #3
0
 def __init__(self, C_in, C_out, stride):
     assert stride in [1, 2]
     ops = [
         Conv2d(C_in, C_in, 3, stride, 1, bias=False),
         BatchNorm2d(C_in),
         nn.ReLU(inplace=True),
         Conv2d(C_in, C_out, 3, 1, 1, bias=False),
         BatchNorm2d(C_out),
     ]
     super(CascadeConv3x3, self).__init__(*ops)
     self.res_connect = (stride == 1) and (C_in == C_out)
 def make_conv(
     in_channels, out_channels, kernel_size, stride=1, dilation=1
 ):
     conv = Conv2d(
         in_channels, 
         out_channels, 
         kernel_size=kernel_size, 
         stride=stride, 
         padding=dilation * (kernel_size - 1) // 2, 
         dilation=dilation, 
         bias=False if use_gn else True
     )
     # Caffe2 implementation uses XavierFill, which in fact
     # corresponds to kaiming_uniform_ in PyTorch
     nn.init.kaiming_uniform_(conv.weight, a=1)
     if not use_gn:
         nn.init.constant_(conv.bias, 0)
     module = [conv,]
     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)
     return conv
def make_conv3x3(
    in_channels, 
    out_channels, 
    dilation=1, 
    stride=1, 
    use_gn=False,
    use_relu=False,
    kaiming_init=True
):
    conv = Conv2d(
        in_channels, 
        out_channels, 
        kernel_size=3, 
        stride=stride, 
        padding=dilation, 
        dilation=dilation, 
        bias=False if use_gn else True
    )
    if kaiming_init:
        nn.init.kaiming_normal_(
            conv.weight, mode="fan_out", nonlinearity="relu"
        )
    else:
        torch.nn.init.normal_(conv.weight, std=0.01)
    if not use_gn:
        nn.init.constant_(conv.bias, 0)
    module = [conv,]
    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)
    return conv
    def __init__(self, cfg, in_channels):
        super(KeypointRCNNFeatureExtractor, self).__init__()

        resolution = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_RESOLUTION
        scales = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_SCALES
        sampling_ratio = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_SAMPLING_RATIO
        pooler = Pooler(
            output_size=(resolution, resolution),
            scales=scales,
            sampling_ratio=sampling_ratio,
        )
        self.pooler = pooler

        input_features = in_channels
        layers = cfg.MODEL.ROI_KEYPOINT_HEAD.CONV_LAYERS
        next_feature = input_features
        self.blocks = []
        for layer_idx, layer_features in enumerate(layers, 1):
            layer_name = "conv_fcn{}".format(layer_idx)
            module = Conv2d(next_feature, layer_features, 3, stride=1, padding=1)
            nn.init.kaiming_normal_(module.weight, mode="fan_out", nonlinearity="relu")
            nn.init.constant_(module.bias, 0)
            self.add_module(layer_name, module)
            next_feature = layer_features
            self.blocks.append(layer_name)
        self.out_channels = layer_features
Пример #7
0
    def __init__(self, C_in, C_out, expansion, stride):
        assert stride in [1, 2]
        self.res_connect = (stride == 1) and (C_in == C_out)

        C_mid = _get_divisible_by(C_in * expansion, 8, 8)

        ops = [
            # pw
            Conv2d(C_in, C_mid, 1, 1, 0, bias=False),
            BatchNorm2d(C_mid),
            nn.ReLU(inplace=True),
            # shift
            Shift(C_mid, 5, stride, 2),
            # pw-linear
            Conv2d(C_mid, C_out, 1, 1, 0, bias=False),
            BatchNorm2d(C_out),
        ]
        super(ShiftBlock5x5, self).__init__(*ops)
Пример #8
0
    def __init__(self, cfg, norm_func):
        super(BaseStem, self).__init__()

        out_channels = cfg.MODEL.RESNETS.STEM_OUT_CHANNELS

        self.conv1 = Conv2d(
            3, out_channels, kernel_size=7, stride=2, padding=3, bias=False
        )
        self.bn1 = norm_func(out_channels)

        for l in [self.conv1,]:
            nn.init.kaiming_uniform_(l.weight, a=1)
Пример #9
0
    def __init__(self, in_channels, bottleneck_channels, out_channels,
                 num_groups, stride_in_1x1, stride, dilation, norm_func,
                 dcn_config):
        """
        Args:
            in_channels (int): Number of input channels.
            out_channels (int): Number of output channels.
            stride (int): Stride for the first conv.
            norm (str or callable): normalization for all conv layers.
                See :func:`layers.get_norm` for supported format.
        """
        super().__init__()

        if in_channels != out_channels:
            self.shortcut = Conv2d(in_channels,
                                   out_channels,
                                   kernel_size=1,
                                   stride=stride,
                                   bias=False)
            self.bn_shortcut = norm_func(out_channels)
        else:
            self.shortcut = None

        self.conv1 = Conv2d(in_channels,
                            out_channels,
                            kernel_size=3,
                            stride=stride,
                            padding=1,
                            bias=False)
        self.bn1 = norm_func(out_channels)
        self.conv2 = Conv2d(out_channels,
                            out_channels,
                            kernel_size=3,
                            stride=1,
                            padding=1,
                            bias=False)
        self.bn2 = norm_func(out_channels)
        for layer in [self.conv1, self.conv2, self.shortcut]:
            if layer is not None:  # shortcut can be None
                nn.init.kaiming_uniform_(layer.weight, a=1)
Пример #10
0
    def __init__(
        self,
        input_depth,
        output_depth,
        kernel,
        stride,
        pad,
        no_bias,
        use_relu,
        bn_type,
        group=1,
        *args,
        **kwargs
    ):
        super(ConvBNRelu, self).__init__()

        assert use_relu in ["relu", None]
        if isinstance(bn_type, (list, tuple)):
            assert len(bn_type) == 2
            assert bn_type[0] == "gn"
            gn_group = bn_type[1]
            bn_type = bn_type[0]
        assert bn_type in ["bn", "af", "gn", None]
        assert stride in [1, 2, 4]

        op = Conv2d(
            input_depth,
            output_depth,
            kernel_size=kernel,
            stride=stride,
            padding=pad,
            bias=not no_bias,
            groups=group,
            *args,
            **kwargs
        )
        nn.init.kaiming_normal_(op.weight, mode="fan_out", nonlinearity="relu")
        if op.bias is not None:
            nn.init.constant_(op.bias, 0.0)
        self.add_module("conv", op)

        if bn_type == "bn":
            bn_op = BatchNorm2d(output_depth)
        elif bn_type == "gn":
            bn_op = nn.GroupNorm(num_groups=gn_group, num_channels=output_depth)
        elif bn_type == "af":
            bn_op = FrozenBatchNorm2d(output_depth)
        if bn_type is not None:
            self.add_module("bn", bn_op)

        if use_relu == "relu":
            self.add_module("relu", nn.ReLU(inplace=True))
    def __init__(self, cfg, in_channels):
        super(MaskRCNNConv1x1Predictor, self).__init__()
        num_classes = cfg.MODEL.ROI_BOX_HEAD.NUM_CLASSES
        num_inputs = in_channels

        self.mask_fcn_logits = Conv2d(num_inputs, num_classes, 1, 1, 0)

        for name, param in self.named_parameters():
            if "bias" in name:
                nn.init.constant_(param, 0)
            elif "weight" in name:
                # Caffe2 implementation uses MSRAFill, which in fact
                # corresponds to kaiming_normal_ in PyTorch
                nn.init.kaiming_normal_(param, mode="fan_out", nonlinearity="relu")
Пример #12
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

        # dcn could be none here
        with_dcn = dcn_config and 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)
Пример #13
0
    def __init__(
        self,
        in_channels,
        bottleneck_channels,
        out_channels,
        num_groups,
        stride_in_1x1,
        stride,
        dilation,
    ):
        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), )
            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)

        # avoid to use name "conv" to avoid error in loading pretrained weights
        self.con1 = Conv2d(
            in_channels,
            bottleneck_channels,
            kernel_size=1,
            stride=stride_1x1,
        )
        # TODO: specify init for the above
        self.con2 = Conv2d(bottleneck_channels,
                           bottleneck_channels,
                           kernel_size=3,
                           stride=stride_3x3,
                           padding=dilation,
                           groups=num_groups,
                           dilation=dilation)
        nn.init.kaiming_uniform_(self.con2.weight, a=1)

        self.con3 = Conv2d(
            bottleneck_channels,
            out_channels,
            kernel_size=1,
        )

        for l in [
                self.con1,
                self.con3,
        ]:
            nn.init.kaiming_uniform_(l.weight, a=1)
Пример #14
0
def conv_1x1_bn(inp, oup):
    return nn.Sequential(Conv2d(inp, oup, 1, 1, 0, bias=False),
                         BatchNorm2d(oup), nn.ReLU6(inplace=True))
Пример #15
0
def conv_bn(inp, oup, stride):
    return nn.Sequential(Conv2d(inp, oup, 3, stride, 1, bias=False),
                         BatchNorm2d(oup), nn.ReLU6(inplace=True))
Пример #16
0
    def __init__(self, cfg, norm_func):
        super(BaseStem, self).__init__()

        out_channels = cfg.MODEL.RESNETS.STEM_OUT_CHANNELS
        self.aa = cfg.MODEL.RESNETS.STEM_AA
        self.no_maxpool = cfg.MODEL.RESNETS.STEM_NO_MAXPOOL

        if cfg.MODEL.RESNETS.STEM_3X3X3:
            self.conv1 = nn.Sequential(
                Conv2d(3,
                       out_channels // 2,
                       kernel_size=3,
                       stride=2,
                       padding=1,
                       bias=False),
                FrozenBatchNorm2d(out_channels // 2, True),
                Conv2d(out_channels // 2,
                       out_channels // 4,
                       kernel_size=3,
                       stride=1,
                       padding=1,
                       bias=False),
                FrozenBatchNorm2d(out_channels // 4, True),
                Conv2d(out_channels // 4,
                       out_channels,
                       kernel_size=3,
                       stride=1,
                       padding=1,
                       bias=False),
            )
            for modules in [
                    self.conv1,
            ]:
                for l in modules.modules():
                    if isinstance(l, Conv2d):
                        nn.init.kaiming_uniform_(l.weight, a=1)
        else:
            self.conv1 = Conv2d(3,
                                out_channels,
                                kernel_size=7,
                                stride=2,
                                padding=3,
                                bias=False)
            nn.init.kaiming_uniform_(self.conv1.weight, a=1)

        self.bn1 = norm_func(out_channels)

        if self.aa:
            self.maxpool = nn.Sequential(*[
                nn.MaxPool2d(kernel_size=2, stride=1),
                Downsample(filt_size=3, stride=2, channels=out_channels)
            ])
        if self.no_maxpool:
            self.maxpool = nn.Sequential(
                Conv2d(out_channels,
                       out_channels // 2,
                       kernel_size=3,
                       stride=1,
                       padding=1,
                       bias=False),
                FrozenBatchNorm2d(out_channels // 2, True),
                Conv2d(out_channels // 2,
                       out_channels,
                       kernel_size=3,
                       stride=2,
                       padding=1,
                       bias=False),
            )
            for i in self.maxpool.modules():
                nn.init.kaiming_uniform_(i.weight, a=1)

        for l in [
                self.conv1,
        ]:
            nn.init.kaiming_uniform_(l.weight, a=1)
Пример #17
0
    def __init__(
        self,
        in_channels,
        bottleneck_channels,
        out_channels,
        num_groups,
        stride_in_1x1,
        stride,
        dilation,
        norm_func,
        dcn_config,
        cfg=None,
    ):
        super(Bottleneck, self).__init__()

        self.downsample = None
        self.aa = cfg.MODEL.RESNETS.BOTTLENECK_AA
        if in_channels != out_channels:
            down_stride = stride if dilation == 1 else 1
            if down_stride > 1 and self.aa:
                self.downsample = nn.Sequential(
                    OrderedDict([('aa',
                                  Downsample(filt_size=3,
                                             stride=stride,
                                             channels=in_channels)),
                                 ('conv',
                                  Conv2d(in_channels,
                                         out_channels,
                                         kernel_size=1,
                                         stride=1,
                                         bias=False)),
                                 ('norm', norm_func(out_channels))]))
            else:
                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)

        if stride_1x1 > 1 and self.aa:
            self.conv1 = nn.Sequential(
                OrderedDict([('aa',
                              Downsample(filt_size=2,
                                         stride=stride_1x1,
                                         channels=in_channels)),
                             ('conv',
                              Conv2d(
                                  in_channels,
                                  bottleneck_channels,
                                  kernel_size=1,
                                  stride=1,
                                  bias=False,
                              ))]))
            for i in self.conv1.modules():
                if isinstance(i, Conv2d):
                    nn.init.kaiming_uniform_(i.weight, a=1)
        else:
            self.conv1 = Conv2d(
                in_channels,
                bottleneck_channels,
                kernel_size=1,
                stride=stride_1x1,
                bias=False,
            )
            nn.init.kaiming_uniform_(self.conv1.weight, a=1)
        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)
        elif stride_3x3 > 1 and self.aa:
            self.conv2 = nn.Sequential(
                OrderedDict([('conv',
                              Conv2d(bottleneck_channels,
                                     bottleneck_channels,
                                     kernel_size=3,
                                     stride=1,
                                     padding=dilation,
                                     bias=False,
                                     groups=num_groups,
                                     dilation=dilation)),
                             ('aa',
                              Downsample(filt_size=3,
                                         stride=stride_3x3,
                                         channels=bottleneck_channels))]))
            for i in self.conv2.modules():
                if isinstance(i, Conv2d):
                    nn.init.kaiming_uniform_(i.weight, a=1)
        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)
Пример #18
0
    def __init__(self, in_channels, bottleneck_channels, out_channels,
                 num_groups, stride_in_1x1, stride, dilation, norm_func,
                 dcn_config):
        super(GrowResNeXtBottleneck, self).__init__()

        self.downsample = None
        self.embryo_channels = 8
        self.embryo_grow_tic = 0
        self.embryo_grow_tic_threshold = 2
        self.adults_volume = 32
        self.adults_channels = self.embryo_channels * self.adults_volume
        self.adults_occupied = torch.zeros((self.adults_volume))
        self.adults_bns = [None] * self.adults_volume
        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
        # 策略:Xembryo和adults采用不同的optimizer,embryo长得快,成熟期或掐表或判定。
        #       embryo成熟后,导入adults空白部分,相应的配套conv1 conv3 也要妥善转入。
        #       adults的导入要管理好。要测试bn导入前后的影响,不行就强行多adults_bn。
        #       adults的各个体要用进废退,市占率低的要有序退出,允许embryo再生。
        #       adults的首尾1*1conv要细心设计其初始化。
        #       对不同的类成立其weight库,因为有些weight的被使用与这类物体的出现频率相关。

        # stride_1x1, stride_3x3 = (stride, 1) if stride_in_1x1 else (1, stride)

        self.embryo_conv1 = Conv2d(in_channels,
                                   self.embryo_channels,
                                   1,
                                   stride,
                                   bias=False)
        self.embryo_bn1 = norm_func(self.embryo_channels)

        self.embryo_conv2 = Conv2d(self.embryo_channels,
                                   self.embryo_channels,
                                   3,
                                   1,
                                   padding=dilation,
                                   bias=False,
                                   dilation=dilation)
        self.embryo_bn2 = norm_func(self.embryo_channels)

        self.embryo_conv3 = Conv2d(self.embryo_channels,
                                   out_channels,
                                   1,
                                   bias=False)
        self.embryo_bn3 = norm_func(out_channels)

        # TODO: specify init for self.conv1 1*1conv
        # TODO: try to init with spercific rules, or just init once then never change.
        nn.init.kaiming_uniform_(self.embryo_conv1.weight, a=1)
        nn.init.kaiming_uniform_(self.embryo_conv2.weight, a=1)
        nn.init.kaiming_uniform_(self.embryo_conv3.weight, a=1)
        self.embryo_init_reserve = {
            "embryo_conv1": self.embryo_conv1.state_dict(),
            "embryo_conv2": self.embryo_conv2.state_dict(),
            "embryo_conv3": self.embryo_conv3.state_dict(),
            "embryo_bn1": self.embryo_bn1.state_dict(),
            "embryo_bn2": self.embryo_bn2.state_dict(),
            "embryo_bn3": self.embryo_bn3.state_dict(),
        }

        self.adults_conv1 = Conv2d(in_channels,
                                   self.adults_channels,
                                   1,
                                   stride,
                                   bias=False)
        self.adults_conv2 = Conv2d(self.adults_channels,
                                   self.adults_channels,
                                   3,
                                   1,
                                   padding=dilation,
                                   bias=False,
                                   dilation=dilation)
        # padding=dilation, bias=False, dilation=dilation, groups=self.adults_volume)
        self.adults_conv3 = Conv2d(self.adults_channels,
                                   out_channels,
                                   1,
                                   bias=False)

        # TODO: adults 三层卷积的group和初始化要细心设计
        self.adults_conv1.weight.data.zero_()
        self.adults_conv2.weight.data.zero_()
        self.adults_conv3.weight.data.zero_()
Пример #19
0
    def __init__(
            self,
            in_channels,  # bottleneck的输入channels
            bottleneck_channels,  # bottleneck压缩后的channels
            out_channels,  # bottleneck的输出channels
            num_groups,  # bottleneck分组的num
            stride_in_1x1,  # 在每个stage的开始的1x1conv中的stride
            stride,  # 卷积步长
            dilation,  # 空洞卷积的间隔
            norm_func  # 用哪一个归一化函数
    ):
        super(Bottleneck, self).__init__()

        # downsample: 当 bottleneck 的输入和输出的 channels 不相等时, 则需要采用一定的策略
        # 在原文中, 有 A, B, C三种策略, 本文采用的是 B 策略(也是原文推荐的)
        # 即只有在输入输出通道数不相等时才使用 projection shortcuts,
        # 也就是利用参数矩阵映射使得输入输出的 channels 相等
        self.downsample = None
        # 当输入输出通道数不同时, 额外添加一个1×1的卷积层使得输入通道数映射成输出通道数
        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=2的卷积用在stage3-5的第一个1x1conv上,现在用在
        # 3x3conv里,但是这里因为是原来框架的,我打印出来还是在1x1conv上,系没有删除注释
        # 因为下面调用的时候都是stride_in_1x1=True
        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
        #dcn_config字典中有键"stage_with_dcn",则返回对应的值,否则为False

        self.conv2 = Conv2d(bottleneck_channels,
                            bottleneck_channels,
                            kernel_size=3,
                            stride=stride_3x3,
                            padding=dilation,
                            bias=False,
                            groups=num_groups,
                            dilation=dilation)
        self.bn2 = norm_func(bottleneck_channels)
        # 创建bottleneck的第3层卷积层
        self.conv3 = Conv2d(bottleneck_channels,
                            out_channels,
                            kernel_size=1,
                            bias=False)
        self.bn3 = norm_func(out_channels)

        for l in [
                self.conv1,
                self.conv2,
                self.conv3,
        ]:
            nn.init.kaiming_uniform_(l.weight, a=1)