    def __init__(self,
                 depth=50,
                 ch_in=64,
                 variant='b',
                 lr_mult_list=[1.0, 1.0, 1.0, 1.0],
                 groups=1,
                 base_width=64,
                 norm_type='bn',
                 norm_decay=0,
                 freeze_norm=True,
                 freeze_at=0,
                 return_idx=[0, 1, 2, 3],
                 dcn_v2_stages=[-1],
                 num_stages=4,
                 std_senet=False):
        """
        Residual Network, see https://arxiv.org/abs/1512.03385

        Args:
            depth (int): ResNet depth, should be 18, 34, 50, 101, 152.
            ch_in (int): output channel of first stage, default 64
            variant (str): ResNet variant, supports 'a', 'b', 'c', 'd' currently
            lr_mult_list (list): learning rate ratio of different resnet stages(2,3,4,5),
                                 lower learning rate ratio is need for pretrained model
                                 got using distillation(default as [1.0, 1.0, 1.0, 1.0]).
            groups (int): group convolution cardinality
            base_width (int): base width of each group convolution
            norm_type (str): normalization type, 'bn', 'sync_bn' or 'affine_channel'
            norm_decay (float): weight decay for normalization layer weights
            freeze_norm (bool): freeze normalization layers
            freeze_at (int): freeze the backbone at which stage
            return_idx (list): index of the stages whose feature maps are returned
            dcn_v2_stages (list): index of stages who select deformable conv v2
            num_stages (int): total num of stages
            std_senet (bool): whether use senet, default True
        """
        super(ResNet, self).__init__()
        self._model_type = 'ResNet' if groups == 1 else 'ResNeXt'
        assert num_stages >= 1 and num_stages <= 4
        self.depth = depth
        self.variant = variant
        self.groups = groups
        self.base_width = base_width
        self.norm_type = norm_type
        self.norm_decay = norm_decay
        self.freeze_norm = freeze_norm
        self.freeze_at = freeze_at
        if isinstance(return_idx, Integral):
            return_idx = [return_idx]
        assert max(return_idx) < num_stages, \
            'the maximum return index must smaller than num_stages, ' \
            'but received maximum return index is {} and num_stages ' \
            'is {}'.format(max(return_idx), num_stages)
        self.return_idx = return_idx
        self.num_stages = num_stages
        assert len(lr_mult_list) == 4, \
            "lr_mult_list length must be 4 but got {}".format(len(lr_mult_list))
        if isinstance(dcn_v2_stages, Integral):
            dcn_v2_stages = [dcn_v2_stages]
        assert max(dcn_v2_stages) < num_stages

        if isinstance(dcn_v2_stages, Integral):
            dcn_v2_stages = [dcn_v2_stages]
        assert max(dcn_v2_stages) < num_stages
        self.dcn_v2_stages = dcn_v2_stages

        block_nums = ResNet_cfg[depth]
        na = NameAdapter(self)

        conv1_name = na.fix_c1_stage_name()
        if variant in ['c', 'd']:
            conv_def = [
                [3, ch_in // 2, 3, 2, "conv1_1"],
                [ch_in // 2, ch_in // 2, 3, 1, "conv1_2"],
                [ch_in // 2, ch_in, 3, 1, "conv1_3"],
            ]
        else:
            conv_def = [[3, ch_in, 7, 2, conv1_name]]
        self.conv1 = nn.Sequential()
        for (c_in, c_out, k, s, _name) in conv_def:
            # self.conv1.add_sublayer(
            #     _name,
            #     ConvNormLayer(
            #         ch_in=c_in,
            #         ch_out=c_out,
            #         filter_size=k,
            #         stride=s,
            #         groups=1,
            #         act='relu',
            #         norm_type=norm_type,
            #         norm_decay=norm_decay,
            #         freeze_norm=freeze_norm,
            #         lr=1.0))
            self.conv1.add_module(_name,
                                  ConvNormLayer(
                                      ch_in=c_in,
                                      ch_out=c_out,
                                      filter_size=k,
                                      stride=s,
                                      groups=1,
                                      act='relu',
                                      norm_type=norm_type,
                                      norm_decay=norm_decay,
                                      freeze_norm=freeze_norm,
                                      lr=1.0)
                                  )

        self.ch_in = ch_in
        ch_out_list = [64, 128, 256, 512]
        block = BottleNeck if depth >= 50 else BasicBlock

        self._out_channels = [block.expansion * v for v in ch_out_list]
        self._out_strides = [4, 8, 16, 32]

        # self.res_layers = []
        self.res_layers = nn.ModuleList()

        for i in range(num_stages):
            lr_mult = lr_mult_list[i]
            stage_num = i + 2
            res_name = "res{}".format(stage_num)
            # res_layer = self.add_sublayer(
            #     res_name,
            #     Blocks(
            #         block,
            #         self.ch_in,
            #         ch_out_list[i],
            #         count=block_nums[i],
            #         name_adapter=na,
            #         stage_num=stage_num,
            #         variant=variant,
            #         groups=groups,
            #         base_width=base_width,
            #         lr=lr_mult,
            #         norm_type=norm_type,
            #         norm_decay=norm_decay,
            #         freeze_norm=freeze_norm,
            #         dcn_v2=(i in self.dcn_v2_stages),
            #         std_senet=std_senet))
            # self.res_layers.append(res_layer)

            self.res_layers.add_module(res_name,
                                       Blocks(
                                           block,
                                           self.ch_in,
                                           ch_out_list[i],
                                           count=block_nums[i],
                                           name_adapter=na,
                                           stage_num=stage_num,
                                           variant=variant,
                                           groups=groups,
                                           base_width=base_width,
                                           lr=lr_mult,
                                           norm_type=norm_type,
                                           norm_decay=norm_decay,
                                           freeze_norm=freeze_norm,
                                           dcn_v2=(i in self.dcn_v2_stages),
                                           std_senet=std_senet)
                                       )

            self.ch_in = self._out_channels[i]
Residual Network, see https://arxiv.org/abs/1512.03385

Args:
depth (int): ResNet depth, should be 18, 34, 50, 101, 152.
ch_in (int): output channel of first stage, default 64
variant (str): ResNet variant, supports 'a', 'b', 'c', 'd' currently
lr_mult_list (list): learning rate ratio of different resnet stages(2,3,4,5),
lower learning rate ratio is need for pretrained model
got using distillation(default as [1.0, 1.0, 1.0, 1.0]).
groups (int): group convolution cardinality
base_width (int): base width of each group convolution
norm_type (str): normalization type, 'bn', 'sync_bn' or 'affine_channel'
norm_decay (float): weight decay for normalization layer weights
freeze_norm (bool): freeze normalization layers
freeze_at (int): freeze the backbone at which stage
return_idx (list): index of the stages whose feature maps are returned
dcn_v2_stages (list): index of stages who select deformable conv v2
num_stages (int): total num of stages
std_senet (bool): whether use senet, default True
ptstructure/layout/ptppyolov2/ppyolov2_resnet.py