Example #1
0
    def _make_layer(self, inplanes, planes, num_blocks, stride=1):

        block = Sequential(
            nn.ZeroPad2d(1),
            nn.Conv2d(inplanes, planes, 3, stride=stride, bias=False),
            build_norm_layer(self._norm_cfg, planes)[1],
            nn.ReLU(),
        )

        for j in range(num_blocks):
            block.add(nn.Conv2d(planes, planes, 3, padding=1, bias=False))
            block.add(build_norm_layer(self._norm_cfg, planes)[1], )
            block.add(nn.ReLU())

        return block, planes
Example #2
0
    def _make_layer(self, inplanes, planes, num_blocks, stride=1):
        # 128, 128, 5, 1
        block = Sequential(
            nn.ZeroPad2d(1),   # to keep size of input and output feature map the same=128
            nn.Conv2d(inplanes, planes, 3, stride=stride, bias=False),
            build_norm_layer(self._norm_cfg, planes)[1],
            # nn.BatchNorm2d(planes, eps=1e-3, momentum=0.01),
            nn.ReLU(),
        )

        for j in range(num_blocks):
            block.add(nn.Conv2d(planes, planes, 3, padding=1, bias=False))
            block.add(build_norm_layer(self._norm_cfg, planes)[1],) # nn.BatchNorm2d(planes, eps=1e-3, momentum=0.01)
            block.add(nn.ReLU())

        return block, planes
Example #3
0
    def __init__(
        self,
        in_channels,
        num_cls,
        heads,
        head_conv=64,
        final_kernel=1,
        bn=False,
        init_bias=-2.19,
        **kwargs,
    ):
        super(DCNSepHead, self).__init__(**kwargs)

        # feature adaptation with dcn
        # use separate features for classification / regression
        self.feature_adapt_cls = FeatureAdaption(in_channels,
                                                 in_channels,
                                                 kernel_size=3,
                                                 deformable_groups=4)

        self.feature_adapt_reg = FeatureAdaption(in_channels,
                                                 in_channels,
                                                 kernel_size=3,
                                                 deformable_groups=4)

        # heatmap prediction head
        self.cls_head = Sequential(
            nn.Conv2d(in_channels,
                      head_conv,
                      kernel_size=3,
                      padding=1,
                      bias=True), nn.BatchNorm2d(64), nn.ReLU(inplace=True),
            nn.Conv2d(head_conv,
                      num_cls,
                      kernel_size=3,
                      stride=1,
                      padding=1,
                      bias=True))
        self.cls_head[-1].bias.data.fill_(init_bias)

        # other regression target
        self.task_head = SepHead(in_channels,
                                 heads,
                                 head_conv=head_conv,
                                 bn=bn,
                                 final_kernel=final_kernel)
Example #4
0
    def __init__(self,
                 layer_nums,
                 ds_layer_strides,
                 ds_num_filters,
                 us_layer_strides,
                 us_num_filters,
                 num_input_features,
                 norm_cfg=None,
                 name="rpn",
                 logger=None,
                 **kwargs):
        super(RPN, self).__init__()
        self._layer_strides = ds_layer_strides
        self._num_filters = ds_num_filters
        self._layer_nums = layer_nums
        self._upsample_strides = us_layer_strides
        self._num_upsample_filters = us_num_filters
        self._num_input_features = num_input_features

        if norm_cfg is None:
            norm_cfg = dict(type="BN", eps=1e-3, momentum=0.01)
        self._norm_cfg = norm_cfg

        assert len(self._layer_strides) == len(self._layer_nums)
        assert len(self._num_filters) == len(self._layer_nums)
        assert len(self._num_upsample_filters) == len(self._upsample_strides)

        self._upsample_start_idx = len(self._layer_nums) - len(
            self._upsample_strides)

        must_equal_list = []
        for i in range(len(self._upsample_strides)):
            # print(upsample_strides[i])
            must_equal_list.append(self._upsample_strides[i] / np.prod(
                self._layer_strides[:i + self._upsample_start_idx + 1]))

        for val in must_equal_list:
            assert val == must_equal_list[0]

        in_filters = [self._num_input_features, *self._num_filters[:-1]]
        blocks = []
        deblocks = []

        for i, layer_num in enumerate(self._layer_nums):
            block, num_out_filters = self._make_layer(
                in_filters[i],
                self._num_filters[i],
                layer_num,
                stride=self._layer_strides[i],
            )
            blocks.append(block)
            if i - self._upsample_start_idx >= 0:
                stride = (self._upsample_strides[i - self._upsample_start_idx])
                if stride > 1:
                    deblock = Sequential(
                        nn.ConvTranspose2d(
                            num_out_filters,
                            self._num_upsample_filters[
                                i - self._upsample_start_idx],
                            stride,
                            stride=stride,
                            bias=False,
                        ),
                        build_norm_layer(
                            self._norm_cfg,
                            self._num_upsample_filters[
                                i - self._upsample_start_idx],
                        )[1],
                        nn.ReLU(),
                    )
                else:
                    stride = np.round(1 / stride).astype(np.int64)
                    deblock = Sequential(
                        nn.Conv2d(
                            num_out_filters,
                            self._num_upsample_filters[
                                i - self._upsample_start_idx],
                            stride,
                            stride=stride,
                            bias=False,
                        ),
                        build_norm_layer(
                            self._norm_cfg,
                            self._num_upsample_filters[
                                i - self._upsample_start_idx],
                        )[1],
                        nn.ReLU(),
                    )
                deblocks.append(deblock)
        self.blocks = nn.ModuleList(blocks)
        self.deblocks = nn.ModuleList(deblocks)

        logger.info("Finish RPN Initialization")
Example #5
0
    def __init__(self,
                 layer_nums,
                 ds_layer_strides,
                 ds_num_filters,
                 us_layer_strides,
                 us_num_filters,
                 num_input_features,
                 norm_cfg=None,
                 name="rpn",
                 logger=None,
                 **kwargs):
        super(FFSA, self).__init__()
        self._layer_strides = ds_layer_strides  # [1,]
        self._num_filters = ds_num_filters  # [128,]
        self._layer_nums = layer_nums  # [5,]
        self._upsample_strides = us_layer_strides  # [1,]
        self._num_upsample_filters = us_num_filters  # [128,]
        self._num_input_features = num_input_features  # 128

        if norm_cfg is None:  # True
            norm_cfg = dict(type="BN", eps=1e-3, momentum=0.01)
        self._norm_cfg = norm_cfg

        self.bottom_up_block_0 = Sequential(
            nn.ZeroPad2d(1),
            nn.Conv2d(128, 128, 3, stride=1, bias=False),
            build_norm_layer(self._norm_cfg, 128)[1],
            nn.ReLU(),
            nn.Conv2d(
                in_channels=128,
                out_channels=128,
                kernel_size=3,
                stride=1,
                padding=1,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                128,
            )[1],
            nn.ReLU(),
            nn.Conv2d(
                in_channels=128,
                out_channels=128,
                kernel_size=3,
                stride=1,
                padding=1,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                128,
            )[1],
            nn.ReLU(),
        )

        self.bottom_up_block_1 = Sequential(
            # [200, 176] -> [100, 88]
            nn.Conv2d(
                in_channels=128,
                out_channels=256,
                kernel_size=3,
                stride=2,
                padding=1,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                256,
            )[1],
            nn.ReLU(),
            nn.Conv2d(
                in_channels=256,
                out_channels=256,
                kernel_size=3,
                stride=1,
                padding=1,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                256,
            )[1],
            nn.ReLU(),
            nn.Conv2d(
                in_channels=256,
                out_channels=256,
                kernel_size=3,
                stride=1,
                padding=1,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                256,
            )[1],
            nn.ReLU(),
        )

        self.trans_0 = Sequential(
            nn.Conv2d(
                in_channels=128,
                out_channels=128,
                kernel_size=1,
                stride=1,
                padding=0,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                128,
            )[1],
            nn.ReLU(),
        )

        self.trans_1 = Sequential(
            nn.Conv2d(
                in_channels=256,
                out_channels=256,
                kernel_size=1,
                stride=1,
                padding=0,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                256,
            )[1],
            nn.ReLU(),
        )

        self.deconv_block_0 = Sequential(
            nn.ConvTranspose2d(
                in_channels=256,
                out_channels=128,
                kernel_size=3,
                stride=2,
                padding=1,
                output_padding=1,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                128,
            )[1],
            nn.ReLU(),
        )

        self.deconv_block_1 = Sequential(
            nn.ConvTranspose2d(
                in_channels=256,
                out_channels=128,
                kernel_size=3,
                stride=2,
                padding=1,
                output_padding=1,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                128,
            )[1],
            nn.ReLU(),
        )

        self.conv_0 = Sequential(
            nn.Conv2d(
                in_channels=128,
                out_channels=128,
                kernel_size=3,
                stride=1,
                padding=1,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                128,
            )[1],
            nn.ReLU(),
        )

        self.w_0 = Sequential(
            nn.Conv2d(
                in_channels=128,
                out_channels=1,
                kernel_size=1,
                stride=1,
                padding=0,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                1,
            )[1],
        )

        self.conv_1 = Sequential(
            nn.Conv2d(
                in_channels=128,
                out_channels=128,
                kernel_size=3,
                stride=1,
                padding=1,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                128,
            )[1],
            nn.ReLU(),
        )

        self.w_1 = Sequential(
            nn.Conv2d(
                in_channels=128,
                out_channels=1,
                kernel_size=1,
                stride=1,
                padding=0,
                bias=False,
            ),
            build_norm_layer(
                self._norm_cfg,
                1,
            )[1],
        )

        logger.info("Finish RPN Initialization")
Example #6
0
    def __init__(
        self,
        in_channels,
        heads,
        head_conv=64,
        final_kernel=1,
        bn=False,
        init_bias=-2.19,
        **kwargs,
    ):
        super(SepHead, self).__init__(**kwargs)

        self.heads = heads
        for head in self.heads:
            classes, num_conv = self.heads[head]

            fc = Sequential()
            for i in range(num_conv - 1):
                fc.add(
                    nn.Conv2d(in_channels,
                              head_conv,
                              kernel_size=final_kernel,
                              stride=1,
                              padding=final_kernel // 2,
                              bias=True))
                if bn:
                    fc.add(nn.BatchNorm2d(head_conv))
                fc.add(nn.ReLU())

            fc.add(
                nn.Conv2d(head_conv,
                          classes,
                          kernel_size=final_kernel,
                          stride=1,
                          padding=final_kernel // 2,
                          bias=True))

            if 'hm' in head:
                fc[-1].bias.data.fill_(init_bias)
            else:
                for m in fc.modules():
                    if isinstance(m, nn.Conv2d):
                        kaiming_init(m)

            self.__setattr__(head, fc)
Example #7
0
    def __init__(self, layer_nums, ds_layer_strides, ds_num_filters, us_layer_strides, us_num_filters, num_input_features, norm_cfg=None, name="rpn", logger=None, **kwargs):

        super(RPN, self).__init__()
        self._layer_strides = ds_layer_strides       # [1,]
        self._num_filters = ds_num_filters           # [128,]
        self._layer_nums = layer_nums                # [5,]
        self._upsample_strides = us_layer_strides    # [1,]
        self._num_upsample_filters = us_num_filters  # [128,]
        self._num_input_features = num_input_features # 128

        if norm_cfg is None: # True
            norm_cfg = dict(type="BN", eps=1e-3, momentum=0.01)
        self._norm_cfg = norm_cfg

        assert len(self._layer_strides) == len(self._layer_nums)
        assert len(self._num_filters) == len(self._layer_nums)
        assert len(self._num_upsample_filters) == len(self._upsample_strides)

        self._upsample_start_idx = len(self._layer_nums) - len(self._upsample_strides)   # 0

        must_equal_list = []
        for i in range(len(self._upsample_strides)):
            must_equal_list.append(self._upsample_strides[i] / np.prod(self._layer_strides[: i + self._upsample_start_idx + 1]))  # [1]

        for val in must_equal_list:
            assert val == must_equal_list[0]

        in_filters = [self._num_input_features, *self._num_filters[:-1]]     # [128]
        blocks = []
        deblocks = []

        for i, layer_num in enumerate(self._layer_nums):
            block, num_out_filters = self._make_layer(in_filters[i], self._num_filters[i], layer_num, stride=self._layer_strides[i],)  # 128, 128, 5, 1
            blocks.append(block)
            if i - self._upsample_start_idx >= 0:
                deblock = Sequential(
                    nn.ConvTranspose2d(
                        num_out_filters,                                             # 128
                        self._num_upsample_filters[i - self._upsample_start_idx],    # 128
                        self._upsample_strides[i - self._upsample_start_idx],        # 1
                        stride=self._upsample_strides[i - self._upsample_start_idx], # 1
                        bias=False,
                    ),
                    # todo: attention here, add extra batch_norm implementation
                    build_norm_layer(self._norm_cfg, self._num_upsample_filters[i - self._upsample_start_idx],)[1],  # 128
                    nn.ReLU(),
                )
                deblocks.append(deblock)
        self.blocks = nn.ModuleList(blocks)
        '''
        6 层二维卷积
        self.blocks:
            (0): ZeroPad2d(padding=(1, 1, 1, 1), value=0.0)
            (1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), bias=False)
            (2): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
            (3): ReLU()
            (4): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
            (5): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
            (6): ReLU()
            (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
            (8): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
            (9): ReLU()
            (10): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
            (11): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
            (12): ReLU()
            (13): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
            (14): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
            (15): ReLU()
            (16): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
            (17): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
            (18): ReLU()

        '''
        self.deblocks = nn.ModuleList(deblocks)
        '''
        1层反卷积
        self.deblocks:
            (0): Sequential(
                (0): ConvTranspose2d(128, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
                (1): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
                (2): ReLU()
            )
        '''
        logger.info("Finish RPN Initialization")
Example #8
0
    def __init__(self,
                 layer_nums,
                 ds_layer_strides,
                 ds_num_filters,
                 us_layer_strides,
                 us_num_filters,
                 num_input_features,
                 norm_cfg=None,
                 name="rpn",
                 logger=None,
                 **kwargs):

        super(RPN, self).__init__()
        self._layer_strides = ds_layer_strides  # [1,]
        self._num_filters = ds_num_filters  # [128,]
        self._layer_nums = layer_nums  # [5,]
        self._upsample_strides = us_layer_strides  # [1,]
        self._num_upsample_filters = us_num_filters  # [128,]
        self._num_input_features = num_input_features  # 128

        if norm_cfg is None:  # True
            norm_cfg = dict(type="BN", eps=1e-3, momentum=0.01)
        self._norm_cfg = norm_cfg

        assert len(self._layer_strides) == len(self._layer_nums)
        assert len(self._num_filters) == len(self._layer_nums)
        assert len(self._num_upsample_filters) == len(self._upsample_strides)

        self._upsample_start_idx = len(self._layer_nums) - len(
            self._upsample_strides)  # 0

        must_equal_list = []
        for i in range(len(self._upsample_strides)):
            must_equal_list.append(self._upsample_strides[i] / np.prod(
                self._layer_strides[:i + self._upsample_start_idx + 1]))  # [1]

        for val in must_equal_list:
            assert val == must_equal_list[0]

        in_filters = [self._num_input_features,
                      *self._num_filters[:-1]]  # [128]
        blocks = []
        deblocks = []

        for i, layer_num in enumerate(self._layer_nums):
            block, num_out_filters = self._make_layer(
                in_filters[i],
                self._num_filters[i],
                layer_num,
                stride=self._layer_strides[i],
            )  # 128, 128, 5, 1
            blocks.append(block)
            if i - self._upsample_start_idx >= 0:
                deblock = Sequential(
                    nn.ConvTranspose2d(
                        num_out_filters,  # 128
                        self._num_upsample_filters[
                            i - self._upsample_start_idx],  # 128
                        self._upsample_strides[i -
                                               self._upsample_start_idx],  # 1
                        stride=self._upsample_strides[
                            i - self._upsample_start_idx],  # 1
                        bias=False,
                    ),
                    # todo: attention here, add extra batch_norm implementation
                    build_norm_layer(
                        self._norm_cfg,
                        self._num_upsample_filters[i -
                                                   self._upsample_start_idx],
                    )[1],  # 128
                    nn.ReLU(),
                )
                deblocks.append(deblock)
        self.blocks = nn.ModuleList(blocks)
        self.deblocks = nn.ModuleList(deblocks)
        logger.info("Finish RPN Initialization")
Example #9
0
    def __init__(self,
                 layer_nums,
                 ds_layer_strides,
                 ds_num_filters,
                 us_layer_strides,
                 us_num_filters,
                 num_input_features,
                 fpn_num_filters,
                 norm_cfg=None,
                 aggregation_method="concat",
                 include_stem_layer=False,
                 name="resnet_panoptic_fpn",
                 logger=None,
                 **kwargs):

        super(ResNet_Panoptic_FPN,
              self).__init__(layer_nums=layer_nums,
                             ds_layer_strides=ds_layer_strides,
                             ds_num_filters=ds_num_filters,
                             num_input_features=num_input_features,
                             fpn_num_filters=fpn_num_filters,
                             include_stem_layer=include_stem_layer,
                             norm_cfg=norm_cfg,
                             logger=logger,
                             **kwargs)

        self._upsample_strides = us_layer_strides
        self._num_upsample_filters = us_num_filters
        self._aggregation_method = aggregation_method

        assert len(self._num_upsample_filters) == len(self._upsample_strides)

        self._upsample_start_idx = len(self._layer_nums) - len(
            self._upsample_strides)

        must_equal_list = []
        for i in range(len(self._upsample_strides)):
            # print(upsample_strides[i])
            must_equal_list.append(self._upsample_strides[i] / np.prod(
                self._layer_strides[:i + self._upsample_start_idx + 1]))

        for val in must_equal_list:
            assert val == must_equal_list[0]

        deblocks = []

        for i, layer_num in enumerate(self._layer_nums):
            num_out_filters = self._fpn_num_filters
            if i - self._upsample_start_idx >= 0:
                stride = (self._upsample_strides[i - self._upsample_start_idx])
                if stride > 1:
                    deblock = Sequential(
                        nn.ConvTranspose2d(
                            num_out_filters,
                            self._num_upsample_filters[
                                i - self._upsample_start_idx],
                            stride,
                            stride=stride,
                            bias=False,
                        ),
                        build_norm_layer(
                            self._norm_cfg,
                            self._num_upsample_filters[
                                i - self._upsample_start_idx],
                        )[1],
                        nn.ReLU(),
                    )
                else:
                    stride = np.round(1 / stride).astype(np.int64)
                    deblock = Sequential(
                        nn.Conv2d(
                            num_out_filters,
                            self._num_upsample_filters[
                                i - self._upsample_start_idx],
                            stride,
                            stride=stride,
                            bias=False,
                        ),
                        build_norm_layer(
                            self._norm_cfg,
                            self._num_upsample_filters[
                                i - self._upsample_start_idx],
                        )[1],
                        nn.ReLU(),
                    )
                deblocks.append(deblock)
        self.deblocks = nn.ModuleList(deblocks)
        logger.info("Finished initializing panoptic-fpn.")
Example #10
0
    def __init__(self,
                 use_norm=True,
                 num_class=2,
                 layer_nums=[3, 3, 3, 3],
                 layer_strides=[2, 2, 2, 2],
                 num_filters=[64, 128, 256, 512],
                 upsample_strides=[1, 2, 4, 4],
                 num_upsample_filters=[64, 128, 256, 256, 448],
                 num_input_filters=128,
                 encode_background_as_zeros=True,
                 use_groupnorm=False,
                 num_groups=32,
                 box_code_size=7,
                 name='det_net'):
        super(det_net, self).__init__()
        assert len(layer_nums) == 4
        assert len(layer_strides) == len(layer_nums)
        assert len(num_filters) == len(layer_nums)
        assert len(upsample_strides) == len(layer_nums)
        # print('use norm or not')
        # print(use_norm)
        if use_norm:
            if use_groupnorm:
                BatchNorm2d = change_default_args(num_groups=num_groups,
                                                  eps=1e-3)(GroupNorm)
            else:
                BatchNorm2d = change_default_args(eps=1e-3, momentum=0.01)(
                    nn.BatchNorm2d)
            Conv2d = change_default_args(bias=False)(nn.Conv2d)
            ConvTranspose2d = change_default_args(bias=False)(
                nn.ConvTranspose2d)
        else:
            BatchNorm2d = Empty
            Conv2d = change_default_args(bias=True)(nn.Conv2d)
            ConvTranspose2d = change_default_args(bias=True)(
                nn.ConvTranspose2d)

        dimension_feature_map = num_filters  #[ 64, 128, 256, 512] # [256, 512, 512, 512]
        dimension_concate = num_upsample_filters  # last one for final output

        # ===============================================================
        # block0
        # ==============================================================
        flag = 0
        middle_layers = []
        for i in range(layer_nums[flag]):
            middle_layers.append(
                Conv2d(dimension_feature_map[flag],
                       dimension_feature_map[flag],
                       3,
                       padding=1))
            middle_layers.append(BatchNorm2d(dimension_feature_map[flag]))
            middle_layers.append(nn.ReLU())
        self.block0 = Sequential(*middle_layers)
        middle_layers = []
        self.downsample0 = Sequential(
            Conv2d(dimension_feature_map[flag],
                   dimension_concate[flag],
                   3,
                   stride=2),
            BatchNorm2d(dimension_concate[flag]),
            nn.ReLU(),
        )

        # ===============================================================
        # block1
        # ==============================================================
        flag = 1
        middle_layers = []
        for i in range(layer_nums[flag]):
            middle_layers.append(
                Conv2d(dimension_feature_map[flag],
                       dimension_feature_map[flag],
                       3,
                       padding=1))
            middle_layers.append(BatchNorm2d(dimension_feature_map[flag]))
            middle_layers.append(nn.ReLU())
        self.block1 = Sequential(*middle_layers)

        # ===============================================================
        # block2
        # ==============================================================
        flag = 2
        middle_layers = []
        for i in range(layer_nums[flag]):
            middle_layers.append(
                Conv2d(dimension_feature_map[flag],
                       dimension_feature_map[flag],
                       3,
                       padding=1))
            middle_layers.append(BatchNorm2d(dimension_feature_map[flag]))
            middle_layers.append(nn.ReLU())
        self.block2 = Sequential(*middle_layers)

        # ===============================================================
        # block3
        # ==============================================================
        flag = 3
        middle_layers = []
        for i in range(layer_nums[flag]):
            middle_layers.append(
                Conv2d(dimension_feature_map[flag],
                       dimension_feature_map[flag],
                       3,
                       padding=1))
            middle_layers.append(BatchNorm2d(dimension_feature_map[flag]))
            middle_layers.append(nn.ReLU())
        self.block3 = Sequential(*middle_layers)
        self.upsample3 = Sequential(
            ConvTranspose2d(dimension_feature_map[flag],
                            dimension_concate[flag],
                            3,
                            stride=2),
            BatchNorm2d(dimension_concate[flag]),
            nn.ReLU(),
        )

        # ==============================================================
        # convlution after concatating block3 and block2
        # ==============================================================
        middle_layers = []
        middle_layers.append(
            Conv2d((dimension_concate[3] + dimension_feature_map[2]),
                   dimension_concate[2],
                   3,
                   padding=1))
        middle_layers.append(BatchNorm2d(dimension_concate[2]))
        middle_layers.append(nn.ReLU())
        middle_layers.append(
            Conv2d(dimension_concate[2], dimension_concate[2], 3, padding=1))
        middle_layers.append(BatchNorm2d(dimension_concate[2]))
        middle_layers.append(nn.ReLU())
        # upsampling
        middle_layers.append(
            ConvTranspose2d(dimension_concate[2],
                            dimension_concate[2],
                            3,
                            stride=2))
        middle_layers.append(BatchNorm2d(dimension_concate[2]))
        middle_layers.append(nn.ReLU())

        self.upsample2_after_concate_fuse32 = Sequential(*middle_layers)

        # ==============================================================
        # convlution after concatating block2, block1 and block0
        # ==============================================================
        middle_layers = []
        middle_layers.append(
            Conv2d((dimension_concate[0] + dimension_feature_map[1] +
                    dimension_concate[2]),
                   dimension_concate[4],
                   3,
                   padding=1))
        middle_layers.append(BatchNorm2d(dimension_concate[4]))
        middle_layers.append(nn.ReLU())
        middle_layers.append(
            Conv2d(dimension_concate[4], dimension_concate[4], 3, padding=1))
        middle_layers.append(BatchNorm2d(dimension_concate[4]))
        middle_layers.append(nn.ReLU())
        self.output_after_concate_fuse210 = Sequential(*middle_layers)