Ejemplo n.º 1
0
    def __init__(self, cfg):
        super().__init__()
        self._cfg = cfg
        assert len(cfg.MODEL.PIXEL_MEAN) == len(cfg.MODEL.PIXEL_STD)
        self.register_buffer(
            "pixel_mean",
            torch.Tensor(cfg.MODEL.PIXEL_MEAN).view(1, -1, 1, 1))
        self.register_buffer(
            "pixel_std",
            torch.Tensor(cfg.MODEL.PIXEL_STD).view(1, -1, 1, 1))

        # fmt: off
        # backbone
        bn_norm = cfg.MODEL.BACKBONE.NORM
        num_splits = cfg.MODEL.BACKBONE.NORM_SPLIT
        with_se = cfg.MODEL.BACKBONE.WITH_SE
        # fmt :on

        backbone = build_backbone(cfg)
        self.backbone = nn.Sequential(backbone.conv1, backbone.bn1,
                                      backbone.relu, backbone.maxpool,
                                      backbone.layer1, backbone.layer2,
                                      backbone.layer3[0])
        res_conv4 = nn.Sequential(*backbone.layer3[1:])
        res_g_conv5 = backbone.layer4

        res_p_conv5 = nn.Sequential(
            Bottleneck(1024,
                       512,
                       bn_norm,
                       num_splits,
                       False,
                       with_se,
                       downsample=nn.Sequential(
                           nn.Conv2d(1024, 2048, 1, bias=False),
                           get_norm(bn_norm, 2048, num_splits))),
            Bottleneck(2048, 512, bn_norm, num_splits, False, with_se),
            Bottleneck(2048, 512, bn_norm, num_splits, False, with_se))
        res_p_conv5.load_state_dict(backbone.layer4.state_dict())

        # branch1
        self.b1 = nn.Sequential(copy.deepcopy(res_conv4),
                                copy.deepcopy(res_g_conv5))
        self.b1_head = build_reid_heads(cfg)

        # branch2
        self.b2 = nn.Sequential(copy.deepcopy(res_conv4),
                                copy.deepcopy(res_p_conv5))
        self.b2_head = build_reid_heads(cfg)
        self.b21_head = build_reid_heads(cfg)
        self.b22_head = build_reid_heads(cfg)

        # branch3
        self.b3 = nn.Sequential(copy.deepcopy(res_conv4),
                                copy.deepcopy(res_p_conv5))
        self.b3_head = build_reid_heads(cfg)
        self.b31_head = build_reid_heads(cfg)
        self.b32_head = build_reid_heads(cfg)
        self.b33_head = build_reid_heads(cfg)
Ejemplo n.º 2
0
    def __init__(self,
                 backbone,
                 num_classes,
                 last_stride,
                 with_ibn,
                 gcb,
                 stage_with_gcb,
                 pretrain=True,
                 model_path=''):
        super().__init__()
        self.num_classes = num_classes
        if 'resnet' in backbone:
            self.base = ResNet.from_name(backbone, last_stride, with_ibn, gcb,
                                         stage_with_gcb)
            self.base.load_pretrain(model_path)
            self.in_planes = 2048
        elif 'osnet' in backbone:
            if with_ibn:
                self.base = osnet_ibn_x1_0(pretrained=pretrain)
            else:
                self.base = osnet_x1_0(pretrained=pretrain)
            self.in_planes = 512
        else:
            print(f'not support {backbone} backbone')

        # global branch
        self.global_reduction = nn.Sequential(
            nn.Conv2d(self.in_planes, 512, 1), nn.BatchNorm2d(512),
            nn.ReLU(True))

        self.gap = nn.AdaptiveAvgPool2d(1)
        self.global_bn = bn2d_no_bias(512)
        self.global_classifier = nn.Linear(512, self.num_classes, bias=False)

        # mask brach
        self.part = Bottleneck(2048, 512)
        self.batch_drop = BatchDrop(1.0, 0.33)
        self.part_pool = nn.AdaptiveMaxPool2d(1)

        self.part_reduction = nn.Sequential(nn.Conv2d(self.in_planes, 1024, 1),
                                            nn.BatchNorm2d(1024),
                                            nn.ReLU(True))
        self.part_bn = bn2d_no_bias(1024)
        self.part_classifier = nn.Linear(1024, self.num_classes, bias=False)

        # initialize
        self.part.apply(weights_init_kaiming)
        self.global_reduction.apply(weights_init_kaiming)
        self.part_reduction.apply(weights_init_kaiming)
        self.global_classifier.apply(weights_init_classifier)
        self.part_classifier.apply(weights_init_classifier)
Ejemplo n.º 3
0
    def __init__(self, cfg):
        super().__init__()
        self.register_buffer(
            "pixel_mean",
            torch.Tensor(cfg.MODEL.PIXEL_MEAN).view(1, -1, 1, 1))
        self.register_buffer(
            "pixel_std",
            torch.Tensor(cfg.MODEL.PIXEL_STD).view(1, -1, 1, 1))
        self._cfg = cfg

        # backbone
        bn_norm = cfg.MODEL.BACKBONE.NORM
        num_splits = cfg.MODEL.BACKBONE.NORM_SPLIT
        with_se = cfg.MODEL.BACKBONE.WITH_SE

        backbone = build_backbone(cfg)
        self.backbone = nn.Sequential(backbone.conv1, backbone.bn1,
                                      backbone.relu, backbone.maxpool,
                                      backbone.layer1, backbone.layer2,
                                      backbone.layer3[0])
        res_conv4 = nn.Sequential(*backbone.layer3[1:])
        res_g_conv5 = backbone.layer4

        res_p_conv5 = nn.Sequential(
            Bottleneck(1024,
                       512,
                       bn_norm,
                       num_splits,
                       False,
                       with_se,
                       downsample=nn.Sequential(
                           nn.Conv2d(1024, 2048, 1, bias=False),
                           get_norm(bn_norm, 2048, num_splits))),
            Bottleneck(2048, 512, bn_norm, num_splits, False, with_se),
            Bottleneck(2048, 512, bn_norm, num_splits, False, with_se))
        res_p_conv5.load_state_dict(backbone.layer4.state_dict())

        if cfg.MODEL.HEADS.POOL_LAYER == 'avgpool':
            pool_layer = nn.AdaptiveAvgPool2d(1)
        elif cfg.MODEL.HEADS.POOL_LAYER == 'maxpool':
            pool_layer = nn.AdaptiveMaxPool2d(1)
        elif cfg.MODEL.HEADS.POOL_LAYER == 'gempool':
            pool_layer = GeneralizedMeanPoolingP()
        else:
            pool_layer = nn.Identity()

        # head
        in_feat = cfg.MODEL.HEADS.IN_FEAT
        num_classes = cfg.MODEL.HEADS.NUM_CLASSES
        # branch1
        self.b1 = nn.Sequential(copy.deepcopy(res_conv4),
                                copy.deepcopy(res_g_conv5))
        self.b1_pool = self._build_pool_reduce(pool_layer, reduce_dim=in_feat)

        self.b1_head = build_reid_heads(cfg, in_feat, num_classes,
                                        nn.Identity())

        # branch2
        self.b2 = nn.Sequential(copy.deepcopy(res_conv4),
                                copy.deepcopy(res_p_conv5))
        self.b2_pool = self._build_pool_reduce(pool_layer, reduce_dim=in_feat)
        self.b2_head = build_reid_heads(cfg, in_feat, num_classes,
                                        nn.Identity())

        self.b21_pool = self._build_pool_reduce(pool_layer, reduce_dim=in_feat)
        self.b21_head = build_reid_heads(cfg, in_feat, num_classes,
                                         nn.Identity())

        self.b22_pool = self._build_pool_reduce(pool_layer, reduce_dim=in_feat)
        self.b22_head = build_reid_heads(cfg, in_feat, num_classes,
                                         nn.Identity())

        # branch3
        self.b3 = nn.Sequential(copy.deepcopy(res_conv4),
                                copy.deepcopy(res_p_conv5))
        self.b3_pool = self._build_pool_reduce(pool_layer, reduce_dim=in_feat)
        self.b3_head = build_reid_heads(cfg, in_feat, num_classes,
                                        nn.Identity())

        self.b31_pool = self._build_pool_reduce(pool_layer, reduce_dim=in_feat)
        self.b31_head = build_reid_heads(cfg, in_feat, num_classes,
                                         nn.Identity())

        self.b32_pool = self._build_pool_reduce(pool_layer, reduce_dim=in_feat)
        self.b32_head = build_reid_heads(cfg, in_feat, num_classes,
                                         nn.Identity())

        self.b33_pool = self._build_pool_reduce(pool_layer, reduce_dim=in_feat)
        self.b33_head = build_reid_heads(cfg, in_feat, num_classes,
                                         nn.Identity())
Ejemplo n.º 4
0
class BDNet(nn.Module):
    def __init__(self,
                 backbone,
                 num_classes,
                 last_stride,
                 with_ibn,
                 gcb,
                 stage_with_gcb,
                 pretrain=True,
                 model_path=''):
        super().__init__()
        self.num_classes = num_classes
        if 'resnet' in backbone:
            self.base = ResNet.from_name(backbone, last_stride, with_ibn, gcb,
                                         stage_with_gcb)
            self.base.load_pretrain(model_path)
            self.in_planes = 2048
        elif 'osnet' in backbone:
            if with_ibn:
                self.base = osnet_ibn_x1_0(pretrained=pretrain)
            else:
                self.base = osnet_x1_0(pretrained=pretrain)
            self.in_planes = 512
        else:
            print(f'not support {backbone} backbone')

        # global branch
        self.global_reduction = nn.Sequential(
            nn.Conv2d(self.in_planes, 512, 1), nn.BatchNorm2d(512),
            nn.ReLU(True))

        self.gap = nn.AdaptiveAvgPool2d(1)
        self.global_bn = bn2d_no_bias(512)
        self.global_classifier = nn.Linear(512, self.num_classes, bias=False)

        # mask brach
        self.part = Bottleneck(2048, 512)
        self.batch_drop = BatchDrop(1.0, 0.33)
        self.part_pool = nn.AdaptiveMaxPool2d(1)

        self.part_reduction = nn.Sequential(nn.Conv2d(self.in_planes, 1024, 1),
                                            nn.BatchNorm2d(1024),
                                            nn.ReLU(True))
        self.part_bn = bn2d_no_bias(1024)
        self.part_classifier = nn.Linear(1024, self.num_classes, bias=False)

        # initialize
        self.part.apply(weights_init_kaiming)
        self.global_reduction.apply(weights_init_kaiming)
        self.part_reduction.apply(weights_init_kaiming)
        self.global_classifier.apply(weights_init_classifier)
        self.part_classifier.apply(weights_init_classifier)

    def forward(self, x, label=None):
        # feature extractor
        feat = self.base(x)

        # global branch
        g_feat = self.global_reduction(feat)
        g_feat = self.gap(g_feat)  # (bs, 512, 1, 1)
        g_bn_feat = self.global_bn(g_feat)  # (bs, 512, 1, 1)
        g_bn_feat = g_bn_feat.view(-1, g_bn_feat.shape[1])  # (bs, 512)

        # mask branch
        p_feat = self.part(feat)
        p_feat = self.batch_drop(p_feat)
        p_feat = self.part_pool(p_feat)  # (bs, 512, 1, 1)
        p_feat = self.part_reduction(p_feat)
        p_bn_feat = self.part_bn(p_feat)
        p_bn_feat = p_bn_feat.view(-1, p_bn_feat.shape[1])  # (bs, 512)

        if self.training:
            global_cls = self.global_classifier(g_bn_feat)
            part_cls = self.part_classifier(p_bn_feat)
            return global_cls, part_cls, g_feat.view(
                -1, g_feat.shape[1]), p_feat.view(-1, p_feat.shape[1])

        return torch.cat([g_bn_feat, p_bn_feat], dim=1)

    def load_params_wo_fc(self, state_dict):
        state_dict.pop('global_classifier.weight')
        state_dict.pop('part_classifier.weight')

        res = self.load_state_dict(state_dict, strict=False)
        print(f'missing keys {res.missing_keys}')
        # assert str(res.missing_keys) == str(['classifier.weight',]), 'issue loading pretrained weights'

    def unfreeze_all_layers(self, ):
        self.train()
        for p in self.parameters():
            p.requires_grad = True

    def unfreeze_specific_layer(self, names):
        if isinstance(names, str):
            names = [names]

        for name, module in self.named_children():
            if name in names:
                module.train()
                for p in module.parameters():
                    p.requires_grad = True
            else:
                module.eval()
                for p in module.parameters():
                    p.requires_grad = False
Ejemplo n.º 5
0
    def from_config(cls, cfg):
        bn_norm = cfg.MODEL.BACKBONE.NORM
        with_se = cfg.MODEL.BACKBONE.WITH_SE

        all_blocks = build_backbone(cfg)

        # backbone
        backbone = nn.Sequential(all_blocks.conv1, all_blocks.bn1,
                                 all_blocks.relu, all_blocks.maxpool,
                                 all_blocks.layer1, all_blocks.layer2,
                                 all_blocks.layer3[0])
        res_conv4 = nn.Sequential(*all_blocks.layer3[1:])
        res_g_conv5 = all_blocks.layer4

        res_p_conv5 = nn.Sequential(
            Bottleneck(1024,
                       512,
                       bn_norm,
                       False,
                       with_se,
                       downsample=nn.Sequential(
                           nn.Conv2d(1024, 2048, 1, bias=False),
                           get_norm(bn_norm, 2048))),
            Bottleneck(2048, 512, bn_norm, False, with_se),
            Bottleneck(2048, 512, bn_norm, False, with_se))
        res_p_conv5.load_state_dict(all_blocks.layer4.state_dict())

        # branch
        neck1 = nn.Sequential(copy.deepcopy(res_conv4),
                              copy.deepcopy(res_g_conv5))
        b1_head = build_heads(cfg)

        # branch2
        neck2 = nn.Sequential(copy.deepcopy(res_conv4),
                              copy.deepcopy(res_p_conv5))
        b2_head = build_heads(cfg)
        b21_head = build_heads(cfg)
        b22_head = build_heads(cfg)

        # branch3
        neck3 = nn.Sequential(copy.deepcopy(res_conv4),
                              copy.deepcopy(res_p_conv5))
        b3_head = build_heads(cfg)
        b31_head = build_heads(cfg)
        b32_head = build_heads(cfg)
        b33_head = build_heads(cfg)

        return {
            'backbone': backbone,
            'neck1': neck1,
            'neck2': neck2,
            'neck3': neck3,
            'b1_head': b1_head,
            'b2_head': b2_head,
            'b21_head': b21_head,
            'b22_head': b22_head,
            'b3_head': b3_head,
            'b31_head': b31_head,
            'b32_head': b32_head,
            'b33_head': b33_head,
            'pixel_mean': cfg.MODEL.PIXEL_MEAN,
            'pixel_std': cfg.MODEL.PIXEL_STD,
            'loss_kwargs': {
                # loss name
                'loss_names': cfg.MODEL.LOSSES.NAME,

                # loss hyperparameters
                'ce': {
                    'eps': cfg.MODEL.LOSSES.CE.EPSILON,
                    'alpha': cfg.MODEL.LOSSES.CE.ALPHA,
                    'scale': cfg.MODEL.LOSSES.CE.SCALE
                },
                'tri': {
                    'margin': cfg.MODEL.LOSSES.TRI.MARGIN,
                    'norm_feat': cfg.MODEL.LOSSES.TRI.NORM_FEAT,
                    'hard_mining': cfg.MODEL.LOSSES.TRI.HARD_MINING,
                    'scale': cfg.MODEL.LOSSES.TRI.SCALE
                },
                'circle': {
                    'margin': cfg.MODEL.LOSSES.CIRCLE.MARGIN,
                    'gamma': cfg.MODEL.LOSSES.CIRCLE.GAMMA,
                    'scale': cfg.MODEL.LOSSES.CIRCLE.SCALE
                },
                'cosface': {
                    'margin': cfg.MODEL.LOSSES.COSFACE.MARGIN,
                    'gamma': cfg.MODEL.LOSSES.COSFACE.GAMMA,
                    'scale': cfg.MODEL.LOSSES.COSFACE.SCALE
                }
            }
        }