Ejemplo n.º 1
0
def test_backbone(module, feature):
    avail_model = getattr(backbones, module).supported_models
    for name in avail_model:
        if name in exclude_test:
            continue
        print(name, feature)
        pretrained = False
        if name not in no_pretrained and feature == "classifier":
            pretrained = True
        elif name != 'darknet53' and feature == 'tri_stage_fpn':
            network = backbones.get_backbone(name,
                                             pretrained=pretrained,
                                             feature_type=feature,
                                             n_classes=2,
                                             norm_layer=EvoNormBatch2d,
                                             norm_kwargs={'eps': 1e-3})
            assert all(not isinstance(m, torch.nn.BatchNorm2d)
                       for m in network.modules())
        network = backbones.get_backbone(name,
                                         pretrained=pretrained,
                                         feature_type=feature,
                                         n_classes=2)

        x = torch.rand(2, 3, 224, 224)
        x = network(x)

        if feature == "tri_stage_fpn":
            out_run = [o.size(1) for o in x]
            out_def = list(network.out_channels)[2:]
            assert out_run == out_def, "channel size defined in '{}' model ({}) " \
                "is not equal to output in runtime ({}).".format(name, out_def, out_run)
        elif feature == "classifier":
            assert x.size(1) == network.out_channels, "channel size defined in '{}' model ({}) is " \
                "not equal to output in runtime ({}).".format(name, network.out_channels, x.size())
        del network, x
Ejemplo n.º 2
0
def test_backbone_fail(module, feature):
    avail_model = getattr(backbones, module).supported_models
    for name in avail_model:
        if name in exclude_test:
            continue
        print(name, feature)
        pretrained = False
        if name not in no_pretrained and feature == "classifier":
            pretrained = True
        network = backbones.get_backbone(name,
                                         pretrained=pretrained,
                                         feature_type=feature,
                                         n_classes=2)

        channel = 2
        with pytest.raises(RuntimeError):
            x = torch.rand(1, channel, 224, 224)
            x = network(x)

            if feature == "tri_stage_fpn":
                out_run = [o.size(1) for o in x]
                out_def = list(network.out_channels)[2:]
                assert out_run != out_def, "channel size defined in '{}' model ({}) " \
                    "is not equal to output in runtime ({}).".format(name, out_def, out_run)
            elif feature == "classifier":
                assert x.size(1) != network.out_channels, "channel size defined in '{}' model ({}) is " \
                    "not equal to output in runtime ({}).".format(name, network.out_channels, x.size())
            del network, x
Ejemplo n.º 3
0
    def __init__(self,
                 backbone: str,
                 feature_type='tri_stage_fpn',
                 pretrained_backbone=False,
                 freeze_backbone=False,
                 *args,
                 **kwargs):
        super(BackbonePoolConnector, self).__init__()
        if not isinstance(backbone, str):
            raise RuntimeError(
                "expects backbone to be 'str' instance, got %s" %
                (type(backbone)))
        if not feature_type in supported_feature_type:
            raise RuntimeError("feature type of '%s' is not supported, "\
                "supported: %s" % (feature_type, supported_feature_type))

        if isinstance(backbone, str):
            if feature_type == "classifier" and "n_classes" not in kwargs:
                ## number of classes in backbone only required for classifier feature type
                raise RuntimeError("'n_classes' argument in model for classifier feature "\
                    "is not defined, make sure you have define it properly.")
            backbone = get_backbone(backbone,
                                    pretrained=pretrained_backbone,
                                    feature_type=feature_type,
                                    *args,
                                    **kwargs)
        self.backbone = backbone
        if freeze_backbone:
            self.backbone.requires_grad_(False)
Ejemplo n.º 4
0
def calculate_models_params_and_flops():

    backbone='darknet53'
    network = backbones.get_backbone(backbone, pretrained=False, feature_type='tri_stage_fpn', n_classes=1000)
    input = torch.randn(1, 3, 448, 448)
    bb_macs, _ = profile(network, inputs=(input, ),verbose=False)
    bb_params = summary(network,(3,448,448),device='cpu')[0].item()
    model_df = pd.DataFrame(columns=['model_name', 'params', 'mac/flops'])
    for key in model_argmap:
        model_cfg= create_model_cfg(key, model_argmap)
        model_components = create_model_components(model_cfg['name'],
                                                   preprocess_args=model_cfg['preprocess_args'],
                                                   network_args=model_cfg['network_args'],
                                                   loss_args=model_cfg['loss_args'],
                                                   postprocess_args=model_cfg['postprocess_args'],
                                                   stage='validate')
        network=model_components.network
        model_macs, model_params = profile(network, inputs=(input, ),verbose=False)
        if 'backbone' in model_cfg.network_args:
            model_macs-=bb_macs
            model_params-=bb_params
            key+='_head'
        model_macs_in_g=model_macs/(10**9)
        model_params_in_m=model_params/(10**6)
        print(key,model_params_in_m,model_macs_in_g)
        model_df = model_df.append({'model_name': key,
                                    'params': model_params_in_m,
                                    'mac/flops': model_macs_in_g}, ignore_index=True)
    model_df.to_csv('models_summary.txt',index=False)
Ejemplo n.º 5
0
def test_backbone(module):
    default_cfgs = getattr(backbones, module).default_cfgs
    for name, cfg in default_cfgs.items():
        if name in exclude_test:
            continue
        print(name)
        pretrained = False
        if name not in no_pretrained:
            pretrained = True

        network = backbones.get_backbone(name, pretrained=False, n_classes=2,
            norm_layer=EvoNormBatch2d, norm_kwargs={'eps': 1e-3})
        assert all(not isinstance(m, nn.BatchNorm2d) for m in network.modules())
        assert isinstance(network, backbones.BackboneBase)
        assert network.default_config == cfg
        assert network.name == name

        network = backbones.get_backbone(name, pretrained=pretrained, n_classes=2)

        stages = network.get_stages()
        assert len(stages) == 5
        assert isinstance(stages, (nn.Sequential, nn.ModuleList))

        classifier = network.get_classifier()
        assert isinstance(classifier, nn.Module)

        x = torch.rand(2, 3, 224, 224)
        out_run = []
        with torch.no_grad():
            for stage in stages:
                x = stage(x)
                out_run.append(x.size(1))
            x = classifier(x)

        out_def = network.stages_channel
        assert isinstance(out_def, tuple)
        assert tuple(out_run) == out_def, "channel size defined in '{}' model ({}) " \
            "is not equal to output in runtime ({}).".format(name, out_def, out_run)

        assert x.size(1) == network.num_classes, "channel size defined in '{}' model ({}) is " \
            "not equal to output in runtime ({}).".format(name, network.num_classes, x.size())
        del network, x
Ejemplo n.º 6
0
def calculate_backbone_params_and_flops():
    all_supported_backbones=backbones.all_models
    backbone_df = pd.DataFrame(columns=['backbone_name', 'params', 'mac/flops'])
    for backbone in all_supported_backbones:
        network = backbones.get_backbone(backbone, pretrained=False, feature_type='tri_stage_fpn', n_classes=1000)
        input = torch.randn(1, 3, 224, 224)
        macs, _ = profile(network, inputs=(input, ),verbose=False)
        params = summary(network,(3,224,224),device='cpu')[0].item()
        macs_in_g=macs/(10**9)
        params_in_m=params/(10**6)
        print(backbone,params_in_m,macs_in_g)
        backbone_df = backbone_df.append({'backbone_name': backbone,
                                          'params': params_in_m,
                                          'mac/flops': macs_in_g}, ignore_index=True)
    backbone_df.to_csv('backbones_summary.txt',index=False)
Ejemplo n.º 7
0
def test_backbone_fail(module):
    avail_model = getattr(backbones, module).supported_models
    for name in avail_model:
        if name in exclude_test:
            continue
        print(name)
        pretrained = False
        if name not in no_pretrained:
            pretrained = True

        network = backbones.get_backbone(name, pretrained=pretrained, n_classes=2)
        assert isinstance(network, backbones.BackboneBase)

        channel = 2
        with pytest.raises(RuntimeError):
            x = torch.rand(1, channel, 224, 224)
            x = network(x)
Ejemplo n.º 8
0
def test_reset_classifier(module):
    avail_model = getattr(backbones, module).supported_models
    backbone = backbones.get_backbone(avail_model[0])
    assert isinstance(backbone, backbones.BackboneBase)
    backbone.requires_grad_(False)
    backbone = backbone.eval()

    num_feature = backbone.num_classifer_feature
    num_classes = 9
    x = torch.randn(1, 3, 224, 224)

    ## change num_classes with default layer
    bb1 = deepcopy(backbone)
    bb1.reset_classifier(num_classes)
    bb1_out = bb1(x.clone())
    assert bb1.num_classes == num_classes
    assert bb1_out.size(1) == num_classes

    ## custom layer
    classifier = nn.Sequential(
        nn.Linear(num_feature, 512),
        nn.Dropout2d(0.2),
        nn.Linear(512, num_classes)
    )
    bb2 = deepcopy(backbone)
    bb2.reset_classifier(num_classes, classifier)
    bb2_out = bb2(x.clone())
    assert bb1.num_classes == num_classes
    assert bb2_out.size(1) == num_classes

    ## num_classes is negative
    bb3 = deepcopy(backbone)
    bb3.reset_classifier(-1)
    bb3_out = bb3(x.clone())
    assert bb3_out.size(1) == bb3.num_classifer_feature

    ## unknown type
    with pytest.raises(TypeError):
        backbone.reset_classifier(8, 'dummy')
Ejemplo n.º 9
0
    def __init__(self,
                 module: Union[str, BackboneBase, nn.Sequential, nn.ModuleList,
                               Sequence],
                 stages_output: Union[str, int, Sequence] = [2, 3, 4],
                 stages_channel: Union[Sequence] = None,
                 freeze: bool = False,
                 name: str = None,
                 **kwargs):
        super().__init__()

        stages = None
        reduce_stages_channel = False
        if isinstance(module, str):
            module = get_backbone(module, **kwargs)

        if isinstance(module, BackboneBase):
            name = module.name
            stages = module.get_stages()
            stages.add_module("classifier", module.get_classifier())
            if stages_channel is None:
                reduce_stages_channel = True
                stages_channel = list(
                    module.stages_channel) + [module.num_classes]
        elif isinstance(module, (nn.Sequential, nn.ModuleList)):
            stages = module
        elif isinstance(module, Sequence):
            stages = nn.Sequential(*module)
        else:
            raise TypeError(
                "'module' argument is expected to have 'str', 'BackboneBase', "
                "'nn.Sequential', 'nn.ModuleList', or list of 'nn.Module' type, got {}"
                .format(type(module)))

        self.stages_output = self._validate_stages_output(
            stages_output, len(stages), self._stages_output_str_map)

        max_stages = max(self.stages_output)
        for idx, (n, module) in enumerate(stages.named_children()):
            if idx > max_stages:
                break
            self.add_module(n, module)

        assert len(
            self
        ) == max_stages + 1, "This should not happened, please report as bug."

        if freeze:
            self.requires_grad_(False)
        self.freeze = freeze

        self._name = name if name else "backbone"
        self.hooks_handle = [
            ModuleIOHook(m) for n, m in enumerate(self)
            if n in self.stages_output
        ]

        if stages_channel is None:
            module_out = self.forward(torch.randn(2, 3, 224, 224))
            stages_channel = [o.size(1) for o in module_out]
        if reduce_stages_channel:
            stages_channel = [
                x for n, x in enumerate(stages_channel)
                if n in self.stages_output
            ]

        if len(stages_channel) != len(self.stages_output):
            raise RuntimeError(
                "length of 'stages_channel' ({}) and number of 'stages_output' ({}) "
                "is expected to be equal.".format(len(stages_channel),
                                                  len(self.stages_output)))
        self._stages_channel = tuple(stages_channel)
Ejemplo n.º 10
0
def test_backbone_class():
    x = torch.randn(2, 3, 224, 224)

    ## normal
    model = Backbone("resnet18", stages_output="tri_stage", norm_layer=EvoNormBatch2d)
    with torch.no_grad():
        y = model(x)
    assert model.name == "resnet18"
    assert model.stages_output == (2, 3, 4)
    assert model.stages_channel == (128, 256, 512)
    assert len(model.hooks_handle) == len(model.stages_output)
    assert len(model) == 5
    assert all(not isinstance(m, torch.nn.BatchNorm2d) for m in model.modules())
    assert tuple(o.size(1) for o in y) == model.stages_channel

    model = Backbone("resnet18", stages_output="classifier")
    with torch.no_grad():
        y = model(x)
    assert model.name == "resnet18"
    assert model.stages_output == (5,)
    assert model.stages_channel == (1000,)
    assert len(model.hooks_handle) == len(model.stages_output)
    assert len(model) == 6    ## 5 stages with classifier
    assert tuple(o.size(1) for o in y) == model.stages_channel

    module = backbones.get_backbone("resnet18")
    model = Backbone(module, stages_output="tri_stage")
    assert model.name == "resnet18"
    assert model.stages_output == (2, 3, 4)
    assert model.stages_channel == (128, 256, 512)
    model = Backbone(module, stages_output="classifier")
    assert model.name == "resnet18"
    assert model.stages_output == (5,)
    assert model.stages_channel == (1000,)


    stages_channel = [128, 256, 512]
    num_classes = 10
    stages = [
        nn.Sequential(
            nn.Conv2d(3, 128, 3, padding=1),
            nn.ReLU(),
            nn.BatchNorm2d(128)
        ),
        nn.Sequential(
            nn.Conv2d(128, 256, 3, stride=2, padding=1),
            nn.ReLU(),
            nn.BatchNorm2d(256)
        ),
        nn.Sequential(
            nn.Conv2d(256, 512, 3, stride=2, padding=1),
            nn.ReLU(),
            nn.BatchNorm2d(512)
        ),
    ]
    classifier = nn.Sequential(
        nn.AdaptiveAvgPool2d(1),
        nn.Flatten(1),
        nn.Linear(512, num_classes)
    )

    ## defined module
    model = Backbone(stages, stages_output=[0,1,2], stages_channel=stages_channel, name="dummy")
    assert model.name == "dummy"
    assert model.stages_output == (0,1,2)
    assert model.stages_channel == tuple(stages_channel)

    model = Backbone(nn.Sequential(*stages), stages_output=[0,1,2], stages_channel=stages_channel, name="dummy")
    assert model.name == "dummy"
    assert model.stages_output == (0,1,2)
    assert model.stages_channel == tuple(stages_channel)

    with pytest.raises(RuntimeError):
        Backbone(stages, stages_output=[0,1], stages_channel=stages_channel, name="dummy")

    ## infer channel output
    model = Backbone(stages, stages_output=[0,1,2])
    assert model.stages_output == (0,1,2)
    assert model.stages_channel == tuple(stages_channel)

    ## defined module with classifier
    module = stages + [classifier]
    model = Backbone(module, stages_output="classifier", stages_channel=[num_classes], name="dummy")
    assert model.name == "dummy"
    assert model.stages_output == (3,)
    assert model.stages_channel == (num_classes,)

    model = Backbone(nn.Sequential(*module), stages_output="classifier", stages_channel=[num_classes], name="dummy")
    assert model.name == "dummy"
    assert model.stages_output == (3,)
    assert model.stages_channel == (num_classes,)

    ## infer channel output
    model = Backbone(module, stages_output=-1)
    assert model.stages_output == (3,)
    assert model.stages_channel == (num_classes,)

    model = Backbone("resnet18", stages_output="classifier", freeze=True)
    assert all(not p.requires_grad for p in model.parameters())

    ## invalid module
    with pytest.raises(TypeError):
        Backbone({"invalid": stages}, stages_output=[0,1,2], stages_channel=stages_channel)