From 3fd9c9b116a2e791512a855525465b89bea51251 Mon Sep 17 00:00:00 2001 From: zengyi <963525814@qq.com> Date: Tue, 6 Dec 2022 17:34:32 +0800 Subject: [PATCH 1/9] dcff deploy revision --- .../dcff/dcff_compact_resnet_8xb32_in1k.py | 3 + .../mmcls/dcff/dcff_resnet_8xb32_in1k.py | 4 + ..._compact_faster_rcnn_resnet50_8xb4_coco.py | 4 + .../dcff_faster_rcnn_resnet50_8xb4_coco.py | 9 +- ...f_compact_topdown_heatmap_resnet50_coco.py | 4 + .../dcff_topdown_heatmap_resnet50_coco.py | 10 +- ...pact_pointrend_resnet50_8xb2_cityscapes.py | 3 + ...dcff_pointrend_resnet50_8xb2_cityscapes.py | 8 +- mmrazor/engine/__init__.py | 7 +- mmrazor/engine/runner/__init__.py | 4 +- mmrazor/engine/runner/iteprune_val_loop.py | 46 ++++++ mmrazor/models/algorithms/pruning/dcff.py | 32 +--- .../algorithms/pruning/ite_prune_algorithm.py | 26 +++- .../test_units/test_dcff_channel_unit.py | 3 +- tests/test_runners/test_iteprune_val_loop.py | 142 ++++++++++++++++++ 15 files changed, 252 insertions(+), 53 deletions(-) create mode 100644 mmrazor/engine/runner/iteprune_val_loop.py create mode 100644 tests/test_runners/test_iteprune_val_loop.py diff --git a/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py b/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py index 66a2587cd..379e54abc 100644 --- a/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py +++ b/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py @@ -2,4 +2,7 @@ # model settings model = _base_.model +# Avoid pruning_ratio check in mutator +model['fix_subnet'] = 'configs/pruning/mmcls/dcff/fix_subnet.yaml' +model['target_pruning_ratio'] = None model['is_deployed'] = True diff --git a/configs/pruning/mmcls/dcff/dcff_resnet_8xb32_in1k.py b/configs/pruning/mmcls/dcff/dcff_resnet_8xb32_in1k.py index 34a9a15c7..cdaf4e924 100644 --- a/configs/pruning/mmcls/dcff/dcff_resnet_8xb32_in1k.py +++ b/configs/pruning/mmcls/dcff/dcff_resnet_8xb32_in1k.py @@ -75,7 +75,11 @@ parse_cfg=dict( type='BackwardTracer', loss_calculator=dict(type='ImageClassifierPseudoLoss'))), + fix_subnet=None, + data_preprocessor=None, target_pruning_ratio=target_pruning_ratio, step_freq=1, linear_schedule=False, is_deployed=False) + +val_cfg = dict(_delete_=True, type='mmrazor.ItePruneValLoop') diff --git a/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py b/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py index 7efb17b7e..c16a15080 100644 --- a/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py +++ b/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py @@ -2,4 +2,8 @@ # model settings model = _base_.model +model = _base_.model +# Avoid pruning_ratio check in mutator +model['fix_subnet'] = 'configs/pruning/mmdet/dcff/fix_subnet.yaml' +model['target_pruning_ratio'] = None model['is_deployed'] = True diff --git a/configs/pruning/mmdet/dcff/dcff_faster_rcnn_resnet50_8xb4_coco.py b/configs/pruning/mmdet/dcff/dcff_faster_rcnn_resnet50_8xb4_coco.py index d19828b73..7387529b3 100644 --- a/configs/pruning/mmdet/dcff/dcff_faster_rcnn_resnet50_8xb4_coco.py +++ b/configs/pruning/mmdet/dcff/dcff_faster_rcnn_resnet50_8xb4_coco.py @@ -65,10 +65,6 @@ _delete_=True) train_cfg = dict(max_epochs=120, val_interval=1) -# !dataset config -# ========================================================================== -# data preprocessor - model = dict( _scope_='mmrazor', type='DCFF', @@ -76,8 +72,7 @@ mutator_cfg=dict( type='DCFFChannelMutator', channel_unit_cfg=dict( - type='DCFFChannelUnit', - units='configs/pruning/mmdet/dcff/resnet_det.json'), + type='DCFFChannelUnit', default_args=dict(choice_mode='ratio')), parse_cfg=dict( type='BackwardTracer', loss_calculator=dict(type='TwoStageDetectorPseudoLoss'))), @@ -89,4 +84,4 @@ model_wrapper = dict( type='mmcv.MMDistributedDataParallel', find_unused_parameters=True) -val_cfg = dict(_delete_=True) +val_cfg = dict(_delete_=True, type='mmrazor.ItePruneValLoop') diff --git a/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py b/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py index 8ec4867b2..90d4d45b7 100644 --- a/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py +++ b/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py @@ -2,4 +2,8 @@ # model settings model = _base_.model +model = _base_.model +# Avoid pruning_ratio check in mutator +model['fix_subnet'] = 'configs/pruning/mmpose/dcff/fix_subnet.yaml' +model['target_pruning_ratio'] = None model['is_deployed'] = True diff --git a/configs/pruning/mmpose/dcff/dcff_topdown_heatmap_resnet50_coco.py b/configs/pruning/mmpose/dcff/dcff_topdown_heatmap_resnet50_coco.py index 3981a54b4..24e15b59e 100644 --- a/configs/pruning/mmpose/dcff/dcff_topdown_heatmap_resnet50_coco.py +++ b/configs/pruning/mmpose/dcff/dcff_topdown_heatmap_resnet50_coco.py @@ -108,13 +108,11 @@ model = dict( _scope_='mmrazor', type='DCFF', - architecture=dict( - cfg_path='mmcls::resnet/resnet50_8xb32_in1k.py', pretrained=False), + architecture=architecture, mutator_cfg=dict( type='DCFFChannelMutator', channel_unit_cfg=dict( - type='DCFFChannelUnit', - units='configs/pruning/mmpose/dcff/resnet_pose.json'), + type='DCFFChannelUnit', default_args=dict(choice_mode='ratio')), parse_cfg=dict( type='BackwardTracer', loss_calculator=dict(type='TopdownPoseEstimatorPseudoLoss'))), @@ -125,7 +123,7 @@ dataset_type = 'CocoDataset' data_mode = 'topdown' -data_root = 'data/coco' +data_root = 'data/coco/' file_client_args = dict(backend='disk') @@ -186,3 +184,5 @@ type='mmpose.CocoMetric', ann_file=data_root + 'annotations/person_keypoints_val2017.json') test_evaluator = val_evaluator + +val_cfg = dict(_delete_=True, type='mmrazor.ItePruneValLoop') diff --git a/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py b/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py index 2914b7d84..df46d3430 100644 --- a/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py +++ b/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py @@ -2,4 +2,7 @@ # model settings model = _base_.model +# Avoid pruning_ratio check in mutator +model['fix_subnet'] = 'configs/pruning/mmseg/dcff/fix_subnet.yaml' +model['target_pruning_ratio'] = None model['is_deployed'] = True diff --git a/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes.py b/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes.py index 8e4b7f342..fc25a56d5 100644 --- a/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes.py +++ b/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes.py @@ -80,13 +80,11 @@ model = dict( _scope_='mmrazor', type='DCFF', - architecture=dict( - cfg_path='mmcls::resnet/resnet50_8xb32_in1k.py', pretrained=False), + architecture=_base_.architecture, mutator_cfg=dict( type='DCFFChannelMutator', channel_unit_cfg=dict( - type='DCFFChannelUnit', - units='configs/pruning/mmseg/dcff/resnet_seg.json'), + type='DCFFChannelUnit', default_args=dict(choice_mode='ratio')), parse_cfg=dict( type='BackwardTracer', loss_calculator=dict(type='CascadeEncoderDecoderPseudoLoss'))), @@ -97,3 +95,5 @@ model_wrapper = dict( type='mmcv.MMDistributedDataParallel', find_unused_parameters=True) + +val_cfg = dict(_delete_=True, type='mmrazor.ItePruneValLoop') diff --git a/mmrazor/engine/__init__.py b/mmrazor/engine/__init__.py index f2df86a83..19028dd5d 100644 --- a/mmrazor/engine/__init__.py +++ b/mmrazor/engine/__init__.py @@ -3,13 +3,14 @@ from .optimizers import SeparateOptimWrapperConstructor from .runner import (AutoSlimValLoop, DartsEpochBasedTrainLoop, DartsIterBasedTrainLoop, EvolutionSearchLoop, - GreedySamplerTrainLoop, SelfDistillValLoop, - SingleTeacherDistillValLoop, SlimmableValLoop) + GreedySamplerTrainLoop, ItePruneValLoop, + SelfDistillValLoop, SingleTeacherDistillValLoop, + SlimmableValLoop) __all__ = [ 'SeparateOptimWrapperConstructor', 'DumpSubnetHook', 'SingleTeacherDistillValLoop', 'DartsEpochBasedTrainLoop', 'DartsIterBasedTrainLoop', 'SlimmableValLoop', 'EvolutionSearchLoop', 'GreedySamplerTrainLoop', 'AutoSlimValLoop', 'EstimateResourcesHook', - 'SelfDistillValLoop' + 'SelfDistillValLoop', 'ItePruneValLoop' ] diff --git a/mmrazor/engine/runner/__init__.py b/mmrazor/engine/runner/__init__.py index 9715a4e6b..2c3fd98df 100644 --- a/mmrazor/engine/runner/__init__.py +++ b/mmrazor/engine/runner/__init__.py @@ -3,11 +3,13 @@ from .darts_loop import DartsEpochBasedTrainLoop, DartsIterBasedTrainLoop from .distill_val_loop import SelfDistillValLoop, SingleTeacherDistillValLoop from .evolution_search_loop import EvolutionSearchLoop +from .iteprune_val_loop import ItePruneValLoop from .slimmable_val_loop import SlimmableValLoop from .subnet_sampler_loop import GreedySamplerTrainLoop __all__ = [ 'SingleTeacherDistillValLoop', 'DartsEpochBasedTrainLoop', 'DartsIterBasedTrainLoop', 'SlimmableValLoop', 'EvolutionSearchLoop', - 'GreedySamplerTrainLoop', 'AutoSlimValLoop', 'SelfDistillValLoop' + 'GreedySamplerTrainLoop', 'AutoSlimValLoop', 'SelfDistillValLoop', + 'ItePruneValLoop' ] diff --git a/mmrazor/engine/runner/iteprune_val_loop.py b/mmrazor/engine/runner/iteprune_val_loop.py new file mode 100644 index 000000000..4bfd43522 --- /dev/null +++ b/mmrazor/engine/runner/iteprune_val_loop.py @@ -0,0 +1,46 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp + +from mmengine import fileio +from mmengine.runner import ValLoop + +from mmrazor.registry import LOOPS +from mmrazor.structures import export_fix_subnet + + +@LOOPS.register_module() +class ItePruneValLoop(ValLoop): + """Pruning loop for validation. Export fixed subnet configs. + + Args: + runner (Runner): A reference of runner. + dataloader (Dataloader or dict): A dataloader object or a dict to + build a dataloader. + evaluator (Evaluator or dict or list): Used for computing metrics. + fp16 (bool): Whether to enable fp16 validation. Defaults to + False. + """ + + def run(self): + """Launch validation.""" + self.runner.call_hook('before_val') + self.runner.call_hook('before_val_epoch') + self.runner.model.eval() + for idx, data_batch in enumerate(self.dataloader): + self.run_iter(idx, data_batch) + + # compute metrics + metrics = self.evaluator.evaluate(len(self.dataloader.dataset)) + self._save_fix_subnet() + self.runner.call_hook('after_val_epoch', metrics=metrics) + self.runner.call_hook('after_val') + return metrics + + def _save_fix_subnet(self): + """Save model subnet config.""" + fix_subnet = export_fix_subnet(self.model) + save_name = 'fix_subnet.yaml' + fileio.dump(fix_subnet, osp.join(self.runner.work_dir, save_name)) + self.runner.logger.info( + 'export finished and ' + f'{save_name} saved in {self.runner.work_dir}.') diff --git a/mmrazor/models/algorithms/pruning/dcff.py b/mmrazor/models/algorithms/pruning/dcff.py index 12c827556..e09199903 100644 --- a/mmrazor/models/algorithms/pruning/dcff.py +++ b/mmrazor/models/algorithms/pruning/dcff.py @@ -8,10 +8,9 @@ from mmengine.model import BaseModel from mmengine.structures import BaseDataElement -from mmrazor.models.mutables import BaseMutable from mmrazor.models.mutators import DCFFChannelMutator from mmrazor.registry import MODELS -from mmrazor.structures.subnet.fix_subnet import _dynamic_to_static +from mmrazor.utils import ValidFixMutable from .ite_prune_algorithm import ItePruneAlgorithm, ItePruneConfigManager LossResults = Dict[str, torch.Tensor] @@ -30,8 +29,8 @@ class DCFF(ItePruneAlgorithm): Args: architecture (Union[BaseModel, Dict]): The model to be pruned. mutator_cfg (Union[Dict, ChannelMutator], optional): The config - of a mutator. Defaults to dict( type='ChannelMutator', - channel_unit_cfg=dict( type='SequentialMutableChannelUnit')). + of a mutator. Defaults to dict( type='DCFFChannelMutator', + channel_unit_cfg=dict( type='DCFFChannelUnit')). data_preprocessor (Optional[Union[Dict, nn.Module]], optional): Defaults to None. target_pruning_ratio (dict, optional): The prune-target. The template @@ -56,6 +55,7 @@ def __init__(self, mutator_cfg: Union[Dict, DCFFChannelMutator] = dict( type=' DCFFChannelMutator', channel_unit_cfg=dict(type='DCFFChannelUnit')), + fix_subnet: Optional[ValidFixMutable] = None, data_preprocessor: Optional[Union[Dict, nn.Module]] = None, target_pruning_ratio: Optional[Dict[str, float]] = None, step_freq=1, @@ -64,27 +64,9 @@ def __init__(self, linear_schedule=False, is_deployed=False) -> None: # invalid param prune_times, reset after message_hub get [max_epoch] - super().__init__(architecture, mutator_cfg, data_preprocessor, - target_pruning_ratio, step_freq, prune_times, - init_cfg, linear_schedule) - self.is_deployed = is_deployed - if (self.is_deployed): - # To static ops for loaded pruned network. - self._deploy() - - def _fix_archtecture(self): - for module in self.architecture.modules(): - if isinstance(module, BaseMutable): - if not module.is_fixed: - module.fix_chosen(None) - - def _deploy(self): - config = self.prune_config_manager.prune_at(self._iter) - self.mutator.set_choices(config) - self.mutator.fix_channel_mutables() - self._fix_archtecture() - _dynamic_to_static(self.architecture) - self.is_deployed = True + super().__init__(architecture, mutator_cfg, fix_subnet, + data_preprocessor, target_pruning_ratio, step_freq, + prune_times, init_cfg, linear_schedule, is_deployed) def _calc_temperature(self, cur_num: int, max_num: int): """Calculate temperature param.""" diff --git a/mmrazor/models/algorithms/pruning/ite_prune_algorithm.py b/mmrazor/models/algorithms/pruning/ite_prune_algorithm.py index d0aab73fd..2c0362e64 100644 --- a/mmrazor/models/algorithms/pruning/ite_prune_algorithm.py +++ b/mmrazor/models/algorithms/pruning/ite_prune_algorithm.py @@ -10,6 +10,7 @@ from mmrazor.models.mutables import MutableChannelUnit from mmrazor.models.mutators import ChannelMutator from mmrazor.registry import MODELS +from mmrazor.utils import ValidFixMutable from ..base import BaseAlgorithm LossResults = Dict[str, torch.Tensor] @@ -97,6 +98,8 @@ class ItePruneAlgorithm(BaseAlgorithm): mutator_cfg (Union[Dict, ChannelMutator], optional): The config of a mutator. Defaults to dict( type='ChannelMutator', channel_unit_cfg=dict( type='SequentialMutableChannelUnit')). + fix_subnet (str | dict | :obj:`FixSubnet`): The path of yaml file or + loaded dict or built :obj:`FixSubnet`. Defaults to None. data_preprocessor (Optional[Union[Dict, nn.Module]], optional): Defaults to None. target_pruning_ratio (dict, optional): The prune-target. The template @@ -110,6 +113,8 @@ class ItePruneAlgorithm(BaseAlgorithm): Defaults to None. linear_schedule (bool, optional): flag to set linear ratio schedule. Defaults to True. + is_deployed (bool, optional): flag to set deployed algorithm. + Defaults to False. """ def __init__(self, @@ -118,12 +123,14 @@ def __init__(self, type='ChannelMutator', channel_unit_cfg=dict( type='SequentialMutableChannelUnit')), + fix_subnet: Optional[ValidFixMutable] = None, data_preprocessor: Optional[Union[Dict, nn.Module]] = None, target_pruning_ratio: Optional[Dict[str, float]] = None, - step_freq=-1, - prune_times=-1, + step_freq=1, + prune_times=1, init_cfg: Optional[Dict] = None, - linear_schedule=True) -> None: + linear_schedule=True, + is_deployed=False) -> None: super().__init__(architecture, data_preprocessor, init_cfg) @@ -132,10 +139,17 @@ def __init__(self, self.step_freq = step_freq self.prune_times = prune_times self.linear_schedule = linear_schedule + self.is_deployed = is_deployed - # mutator - self.mutator: ChannelMutator = MODELS.build(mutator_cfg) - self.mutator.prepare_from_supernet(self.architecture) + if self.is_deployed: + assert fix_subnet is not None + # Avoid circular import + from mmrazor.structures import load_fix_subnet + load_fix_subnet(self.architecture, fix_subnet) + else: + # init mutator + self.mutator: ChannelMutator = MODELS.build(mutator_cfg) + self.mutator.prepare_from_supernet(self.architecture) def group_target_pruning_ratio( self, target: Dict[str, float], diff --git a/tests/test_models/test_mutables/test_mutable_channel/test_units/test_dcff_channel_unit.py b/tests/test_models/test_mutables/test_mutable_channel/test_units/test_dcff_channel_unit.py index d0462886c..bb587c7af 100644 --- a/tests/test_models/test_mutables/test_mutable_channel/test_units/test_dcff_channel_unit.py +++ b/tests/test_models/test_mutables/test_mutable_channel/test_units/test_dcff_channel_unit.py @@ -9,8 +9,7 @@ from mmrazor.structures.graph import ModuleGraph as ModuleGraph from .....data.models import LineModel -DEVICE = torch.device('cuda:0') if torch.cuda.is_available() \ - else torch.device('cpu') +DEVICE = torch.device('cpu') class TestDCFFChannelUnit(TestCase): diff --git a/tests/test_runners/test_iteprune_val_loop.py b/tests/test_runners/test_iteprune_val_loop.py new file mode 100644 index 000000000..ad241bde0 --- /dev/null +++ b/tests/test_runners/test_iteprune_val_loop.py @@ -0,0 +1,142 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import copy +import shutil +import tempfile +from unittest import TestCase + +import torch +import torch.nn as nn +from mmengine.config import Config +from mmengine.evaluator import BaseMetric +from mmengine.model import BaseModel +from mmengine.runner import Runner +from torch.utils.data import Dataset + +from mmrazor.engine import ItePruneValLoop +from mmrazor.registry import DATASETS, METRICS, MODELS + + +def collate_fn(data_batch): + return data_batch + + +MODEL_CFG = dict( + _scope_='mmcls', + type='ImageClassifier', + backbone=dict( + type='ResNet', + depth=18, + num_stages=4, + out_indices=(3, ), + style='pytorch'), + neck=dict(type='GlobalAveragePooling'), + head=dict( + type='LinearClsHead', + num_classes=1000, + in_channels=512, + loss=dict(type='CrossEntropyLoss', loss_weight=1.0), + topk=(1, 5), + )) + + +@MODELS.register_module() +class ToyModel_ItePruneValLoop(BaseModel): + + def __init__(self): + super().__init__() + self.conv1 = nn.Conv2d(3, 16, 3, 1, 1) + self.conv2 = nn.Conv2d(16, 16, 3, 1, 1) + + def forward(self, inputs, data_samples, mode='tensor'): + inputs = torch.stack(inputs) + labels = torch.stack(data_samples) + outputs = self.conv1(inputs) + outputs = self.conv2(outputs) + outputs = torch.mean(outputs, (1, 2, 3)) + + if mode == 'tensor': + return outputs + elif mode == 'loss': + loss = (labels - outputs).sum() + outputs = dict(loss=loss) + return outputs + elif mode == 'predict': + outputs = dict(log_vars=dict(a=1, b=0.5)) + return outputs + + +@DATASETS.register_module() +class ToyDataset_ItePruneValLoop(Dataset): + METAINFO = dict() # type: ignore + data = torch.randn(12, 3, 32, 32) + label = torch.ones(12) + + @property + def metainfo(self): + return self.METAINFO + + def __len__(self): + return self.data.size(0) + + def __getitem__(self, index): + return dict(inputs=self.data[index], data_samples=self.label[index]) + + +@METRICS.register_module() +class ToyMetric_ItePruneValLoop(BaseMetric): + + def __init__(self, collect_device='cpu', dummy_metrics=None): + super().__init__(collect_device=collect_device) + self.dummy_metrics = dummy_metrics + + def process(self, data_samples, predictions): + result = {'acc': 1} + self.results.append(result) + + def compute_metrics(self, results): + return dict(acc=1) + + +class TestItePruneValLoop(TestCase): + + def setUp(self): + self.temp_dir = tempfile.mkdtemp() + + val_dataloader = dict( + dataset=dict(type='ToyDataset_ItePruneValLoop'), + sampler=dict(type='DefaultSampler', shuffle=False), + batch_size=3, + num_workers=0) + val_evaluator = dict(type='ToyMetric_ItePruneValLoop') + + val_loop_cfg = dict( + default_scope='mmrazor', + model=dict(type='ToyModel_ItePruneValLoop'), + work_dir=self.temp_dir, + val_dataloader=val_dataloader, + val_evaluator=val_evaluator, + val_cfg=dict(type='ItePruneValLoop'), + custom_hooks=[], + default_hooks=dict( + runtime_info=dict(type='RuntimeInfoHook'), + timer=dict(type='IterTimerHook'), + logger=dict(type='LoggerHook'), + param_scheduler=dict(type='ParamSchedulerHook'), + checkpoint=dict( + type='CheckpointHook', interval=1, by_epoch=True), + sampler_seed=dict(type='DistSamplerSeedHook')), + launcher='none', + env_cfg=dict(dist_cfg=dict(backend='nccl')), + ) + self.val_loop_cfg = Config(val_loop_cfg) + + def tearDown(self): + shutil.rmtree(self.temp_dir) + + def test_init(self): + cfg = copy.deepcopy(self.val_loop_cfg) + cfg.experiment_name = 'test_init_self' + runner = Runner.from_cfg(cfg) + loop = runner.build_val_loop(cfg.val_cfg) + + self.assertIsInstance(loop, ItePruneValLoop) From fb70f780b74170bdedfcba438f98b380f5fca996 Mon Sep 17 00:00:00 2001 From: zengyi <963525814@qq.com> Date: Fri, 9 Dec 2022 14:15:15 +0800 Subject: [PATCH 2/9] tempsave --- ...n_backbone_resnet50_resnet18_8xb32_in1k.py | 2 +- ...ff_pointrend_resnet50_8xb2_cityscapes_1.py | 99 +++++++++++++++++++ .../architectures/backbones/prune_backbone.py | 34 +++++++ mmrazor/structures/subnet/fix_subnet.py | 59 ++++++++--- .../test_algorithms/test_dcff_network.py | 41 ++++++++ 5 files changed, 219 insertions(+), 16 deletions(-) create mode 100644 configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes_1.py create mode 100644 mmrazor/models/architectures/backbones/prune_backbone.py diff --git a/configs/distill/mmcls/abloss/abloss_pretrain_backbone_resnet50_resnet18_8xb32_in1k.py b/configs/distill/mmcls/abloss/abloss_pretrain_backbone_resnet50_resnet18_8xb32_in1k.py index d24ef0eac..ac8e7eee3 100644 --- a/configs/distill/mmcls/abloss/abloss_pretrain_backbone_resnet50_resnet18_8xb32_in1k.py +++ b/configs/distill/mmcls/abloss/abloss_pretrain_backbone_resnet50_resnet18_8xb32_in1k.py @@ -4,7 +4,7 @@ 'mmcls::_base_/default_runtime.py' ] -teacher_ckpt = 'https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth' # noqa: E501 +teacher_ = 'https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth' # noqa: E501 model = dict( _scope_='mmrazor', type='SingleTeacherDistill', diff --git a/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes_1.py b/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes_1.py new file mode 100644 index 000000000..aeb62adf5 --- /dev/null +++ b/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes_1.py @@ -0,0 +1,99 @@ +_base_ = [ + # TODO: use autoaug pipeline. + 'mmseg::_base_/datasets/cityscapes.py', + 'mmseg::_base_/schedules/schedule_160k.py', + 'mmseg::_base_/default_runtime.py', + './pointrend_resnet50.py' +] + +optim_wrapper = dict( + type='OptimWrapper', + optimizer=dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005), + clip_grad=dict(max_norm=25, norm_type=2), + _delete_=True) +train_cfg = dict(type='IterBasedTrainLoop', max_iters=160000, val_interval=800) + +param_scheduler = [ + # warm up + dict(type='LinearLR', by_epoch=False, start_factor=0.1, begin=0, end=200), + dict( + type='PolyLR', + eta_min=1e-4, + power=0.9, + begin=200, + end=80000, + by_epoch=False, + ) +] + +stage_ratio_1 = 0.65 +stage_ratio_2 = 0.6 +stage_ratio_3 = 0.9 +stage_ratio_4 = 0.7 + +# the config template of target_pruning_ratio can be got by +# python ./tools/get_channel_units.py {config_file} --choice +target_pruning_ratio = { + 'backbone.layer1.0.conv1_(0, 64)_64': stage_ratio_1, + 'backbone.layer1.0.conv2_(0, 64)_64': stage_ratio_2, + 'backbone.layer1.0.conv3_(0, 256)_256': stage_ratio_3, + 'backbone.layer1.1.conv1_(0, 64)_64': stage_ratio_1, + 'backbone.layer1.1.conv2_(0, 64)_64': stage_ratio_2, + 'backbone.layer1.2.conv1_(0, 64)_64': stage_ratio_1, + 'backbone.layer1.2.conv2_(0, 64)_64': stage_ratio_2, + # block 1 [0.8, 0.8] downsample=[0.9] + 'backbone.layer2.0.conv1_(0, 128)_128': stage_ratio_1, + 'backbone.layer2.0.conv2_(0, 128)_128': stage_ratio_2, + 'backbone.layer2.0.conv3_(0, 512)_512': stage_ratio_3, + 'backbone.layer2.1.conv1_(0, 128)_128': stage_ratio_1, + 'backbone.layer2.1.conv2_(0, 128)_128': stage_ratio_2, + 'backbone.layer2.2.conv1_(0, 128)_128': stage_ratio_1, + 'backbone.layer2.2.conv2_(0, 128)_128': stage_ratio_2, + 'backbone.layer2.3.conv1_(0, 128)_128': stage_ratio_1, + 'backbone.layer2.3.conv2_(0, 128)_128': stage_ratio_2, + # block 2 [0.8, 0.8] downsample=[0.9] + 'backbone.layer3.0.conv1_(0, 256)_256': stage_ratio_1, + 'backbone.layer3.0.conv2_(0, 256)_256': stage_ratio_2, + 'backbone.layer3.0.conv3_(0, 1024)_1024': stage_ratio_3, + 'backbone.layer3.1.conv1_(0, 256)_256': stage_ratio_1, + 'backbone.layer3.1.conv2_(0, 256)_256': stage_ratio_2, + 'backbone.layer3.2.conv1_(0, 256)_256': stage_ratio_1, + 'backbone.layer3.2.conv2_(0, 256)_256': stage_ratio_2, + 'backbone.layer3.3.conv1_(0, 256)_256': stage_ratio_4, + 'backbone.layer3.3.conv2_(0, 256)_256': stage_ratio_4, + 'backbone.layer3.4.conv1_(0, 256)_256': stage_ratio_4, + 'backbone.layer3.4.conv2_(0, 256)_256': stage_ratio_4, + 'backbone.layer3.5.conv1_(0, 256)_256': stage_ratio_4, + 'backbone.layer3.5.conv2_(0, 256)_256': stage_ratio_4, + # block 3 [0.8, 0.8]*2+[0.8, 0.85]*2 downsample=[0.9] + 'backbone.layer4.0.conv1_(0, 512)_512': stage_ratio_4, + 'backbone.layer4.0.conv2_(0, 512)_512': stage_ratio_4, + 'backbone.layer4.0.conv3_(0, 2048)_2048': stage_ratio_3, + 'backbone.layer4.1.conv1_(0, 512)_512': stage_ratio_4, + 'backbone.layer4.1.conv2_(0, 512)_512': stage_ratio_4, + 'backbone.layer4.2.conv1_(0, 512)_512': stage_ratio_4, + 'backbone.layer4.2.conv2_(0, 512)_512': stage_ratio_4 + # block 4 [0.85, 0.85] downsample=[0.9] +} + +# model settings +model = dict( + _scope_='mmrazor', + type='DCFF', + architecture=_base_.architecture, + mutator_cfg=dict( + type='DCFFChannelMutator', + channel_unit_cfg=dict( + type='DCFFChannelUnit', default_args=dict(choice_mode='ratio')), + parse_cfg=dict( + type='BackwardTracer', + loss_calculator=dict(type='CascadeEncoderDecoderPseudoLoss'))), + target_pruning_ratio=target_pruning_ratio, + step_freq=1, + linear_schedule=False, + is_deployed=False) + +model_wrapper = dict( + type='mmcv.MMDistributedDataParallel', find_unused_parameters=True) + +val_cfg = dict(_delete_=True, type='mmrazor.ItePruneValLoop') diff --git a/mmrazor/models/architectures/backbones/prune_backbone.py b/mmrazor/models/architectures/backbones/prune_backbone.py new file mode 100644 index 000000000..0fec3c63a --- /dev/null +++ b/mmrazor/models/architectures/backbones/prune_backbone.py @@ -0,0 +1,34 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import copy +from typing import Dict, List, Optional, Tuple, Union + +import torch +import torch.nn as nn +from mmcv.cnn import build_activation_layer, build_norm_layer +from torch import Tensor + +from mmrazor.registry import MODELS + +@MODELS.register_module() +class PruneBackbone(nn.Module): + """Backbone of Prune Network. Reset Backbone param by subnet.yaml. + + Args: + """ + + def __init__(self, + source_model: Union[BaseModel, Dict], + fix_subnet: Optional[ValidFixMutable] = None, + init_cfg: Optional[Dict] = None) -> None: + super().__init__(init_cfg) + + self.source_model = MODELS.build(source_model) + self.fix_subnet = fix_subnet + self.init_cfg = init_cfg + self.update(self, fix_subnet) + + def update_subnet(self, fix_subnet): + + + def forward(self, x): + return self.forward(x) diff --git a/mmrazor/structures/subnet/fix_subnet.py b/mmrazor/structures/subnet/fix_subnet.py index 538a88dac..a4fad689c 100644 --- a/mmrazor/structures/subnet/fix_subnet.py +++ b/mmrazor/structures/subnet/fix_subnet.py @@ -80,8 +80,17 @@ def load_fix_subnet(model: nn.Module, def export_fix_subnet(model: nn.Module, - dump_derived_mutable: bool = False) -> FixMutable: - """Export subnet that can be loaded by :func:`load_fix_subnet`.""" + dump_derived_mutable: bool = False, + export_weight: bool = False) -> FixMutable: + """Export subnet that can be loaded by :func:`load_fix_subnet`. + + Args: + model (nn.Module): The target model to export. + dump_derived_mutable (bool): Dump information for all derived mutables. + Default to False. + export_weight (bool): Export entire subnet when set to True. + Export choice of mutables when set to False. Default to False. + """ if dump_derived_mutable: print_log( 'Trying to dump information of all derived mutables, ' @@ -92,17 +101,37 @@ def export_fix_subnet(model: nn.Module, from mmrazor.models.mutables import DerivedMutable, MutableChannelContainer from mmrazor.models.mutables.base_mutable import BaseMutable - fix_subnet = dict() - for name, module in model.named_modules(): - if isinstance(module, BaseMutable): - if isinstance(module, - (MutableChannelContainer, - DerivedMutable)) and not dump_derived_mutable: - continue - - if module.alias: - fix_subnet[module.alias] = module.dump_chosen() - else: - fix_subnet[name] = module.dump_chosen() + if export_weight: + # export subnet ckpt + fix_subnet = dict() + for name, module in model.named_modules(): + if isinstance(module, BaseMutable): + if isinstance(module, + (MutableChannelContainer, + DerivedMutable)) and not dump_derived_mutable: + continue + + if module.alias: + fix_subnet[module.alias] = module.dump_chosen() + else: + fix_subnet[name] = module.dump_chosen() + + return fix_subnet + else: + # export mutable's current_choice + fix_subnet = dict() + for name, module in model.named_modules(): + print("name, module:", name) + if isinstance(module, BaseMutable): + print("name, base:", name) + if isinstance(module, + (MutableChannelContainer, + DerivedMutable)) and not dump_derived_mutable: + continue + + if module.alias: + fix_subnet[module.alias] = module.dump_chosen() + else: + fix_subnet[name] = module.dump_chosen() - return fix_subnet + return fix_subnet diff --git a/tests/test_models/test_algorithms/test_dcff_network.py b/tests/test_models/test_algorithms/test_dcff_network.py index fd108a172..a57b5e798 100644 --- a/tests/test_models/test_algorithms/test_dcff_network.py +++ b/tests/test_models/test_algorithms/test_dcff_network.py @@ -12,6 +12,7 @@ from mmrazor.models.algorithms.pruning.ite_prune_algorithm import \ ItePruneConfigManager from mmrazor.registry import MODELS +from mmrazor.structures import export_fix_subnet # @TASK_UTILS.register_module() @@ -229,3 +230,43 @@ def test_group_target_ratio(self): algorithm.forward( data['inputs'], data['data_samples'], mode='loss') self.assertEqual(algorithm.step_freq, epoch_step * iter_per_epoch) + + def test_export_subnet(self): + + model = MODELS.build(MODEL_CFG) + mutator = MODELS.build(MUTATOR_CONFIG_FLOAT) + mutator.prepare_from_supernet(model) + mutator.set_choices(mutator.sample_choices()) + prune_target = mutator.choice_template + + custom_groups = [[ + 'backbone.layer1.0.conv1_(0, 64)_64', + 'backbone.layer1.1.conv1_(0, 64)_64' + ]] + mutator_cfg = copy.deepcopy(MUTATOR_CONFIG_FLOAT) + mutator_cfg['custom_groups'] = custom_groups + + iter_per_epoch = 10 + epoch_step = 2 + epoch = 6 + data = self.fake_cifar_data() + + prune_target['backbone.layer1.0.conv1_(0, 64)_64'] = 0.1 + prune_target['backbone.layer1.1.conv1_(0, 64)_64'] = 0.1 + + algorithm = DCFF( + MODEL_CFG, + target_pruning_ratio=prune_target, + mutator_cfg=mutator_cfg, + step_freq=epoch_step).to(DEVICE) + + algorithm.init_weights() + self._set_epoch_ite(1, 2, epoch) + algorithm.forward(data['inputs'], data['data_samples'], mode='loss') + self.assertEqual(algorithm.step_freq, epoch_step * iter_per_epoch) + subnet = export_fix_subnet(algorithm.architecture, dump_derived_mutable=True) + print("subnet:", subnet) + # print("model:", algorithm.architecture) + from mmengine import fileio + fileio.dump(subnet,'/mnt/lustre/zengyi/mmrazor/experiment/subnet.yaml') + self.assertEqual(1, 0) \ No newline at end of file From f99de082a5e8db2b3a1404e84efd25adaee27d6c Mon Sep 17 00:00:00 2001 From: zengyi <963525814@qq.com> Date: Tue, 13 Dec 2022 03:57:33 +0800 Subject: [PATCH 3/9] update fix_subnet --- .../iteprune_resnet_supernet.py | 23 + ...n_backbone_resnet50_resnet18_8xb32_in1k.py | 2 +- configs/pruning/mmcls/dcff/fix_subnet.yaml | 186 +++++++ configs/pruning/mmcls/dcff/resnet_cls.json | 509 ----------------- configs/pruning/mmdet/dcff/fix_subnet.yaml | 186 +++++++ configs/pruning/mmdet/dcff/resnet_det.json | 522 ------------------ configs/pruning/mmpose/dcff/fix_subnet.yaml | 186 +++++++ configs/pruning/mmpose/dcff/resnet_pose.json | 509 ----------------- ...ff_pointrend_resnet50_8xb2_cityscapes_1.py | 99 ---- configs/pruning/mmseg/dcff/fix_subnet.yaml | 186 +++++++ configs/pruning/mmseg/dcff/resnet_seg.json | 496 ----------------- mmrazor/engine/runner/__init__.py | 3 +- mmrazor/engine/runner/iteprune_val_loop.py | 7 +- .../architectures/backbones/prune_backbone.py | 34 -- .../backbones/searchable_shufflenet_v2.py | 2 +- .../mutable_channel_container.py | 8 + mmrazor/registry/__init__.py | 3 +- mmrazor/registry/sub_model.py | 73 +++ mmrazor/structures/subnet/fix_subnet.py | 60 +- .../test_algorithm/test_subnet.yaml | 186 +++++++ tests/data/test_registry/resnet_subnet.yaml | 186 +++++++ .../test_algorithms/test_dcff_network.py | 65 ++- tests/test_registry/test_registry.py | 17 + tests/test_runners/test_iteprune_val_loop.py | 142 ----- 24 files changed, 1329 insertions(+), 2361 deletions(-) create mode 100644 configs/_base_/prune_backbones/iteprune_resnet_supernet.py create mode 100644 configs/pruning/mmcls/dcff/fix_subnet.yaml delete mode 100644 configs/pruning/mmcls/dcff/resnet_cls.json create mode 100644 configs/pruning/mmdet/dcff/fix_subnet.yaml delete mode 100644 configs/pruning/mmdet/dcff/resnet_det.json create mode 100644 configs/pruning/mmpose/dcff/fix_subnet.yaml delete mode 100644 configs/pruning/mmpose/dcff/resnet_pose.json delete mode 100644 configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes_1.py create mode 100644 configs/pruning/mmseg/dcff/fix_subnet.yaml delete mode 100644 configs/pruning/mmseg/dcff/resnet_seg.json delete mode 100644 mmrazor/models/architectures/backbones/prune_backbone.py create mode 100644 mmrazor/registry/sub_model.py create mode 100644 tests/data/test_models/test_algorithm/test_subnet.yaml create mode 100644 tests/data/test_registry/resnet_subnet.yaml delete mode 100644 tests/test_runners/test_iteprune_val_loop.py diff --git a/configs/_base_/prune_backbones/iteprune_resnet_supernet.py b/configs/_base_/prune_backbones/iteprune_resnet_supernet.py new file mode 100644 index 000000000..6f57e8acf --- /dev/null +++ b/configs/_base_/prune_backbones/iteprune_resnet_supernet.py @@ -0,0 +1,23 @@ +_STAGE_MUTABLE = dict( + _scope_='mmrazor', + type='OneShotMutableOP', + candidates=dict( + shuffle_3x3=dict(type='ShuffleBlock', kernel_size=3), + shuffle_5x5=dict(type='ShuffleBlock', kernel_size=5), + shuffle_7x7=dict(type='ShuffleBlock', kernel_size=7), + shuffle_xception=dict(type='ShuffleXception'))) + +arch_setting = [ + # Parameters to build layers. 3 parameters are needed to construct a + # layer, from left to right: channel, num_blocks, mutable_cfg. + [64, 4, _STAGE_MUTABLE], + [160, 4, _STAGE_MUTABLE], + [320, 8, _STAGE_MUTABLE], + [640, 4, _STAGE_MUTABLE] +] + +nas_backbone = dict( + _scope_='mmrazor', + type='SearchableShuffleNetV2', + widen_factor=1.0, + arch_setting=arch_setting) diff --git a/configs/distill/mmcls/abloss/abloss_pretrain_backbone_resnet50_resnet18_8xb32_in1k.py b/configs/distill/mmcls/abloss/abloss_pretrain_backbone_resnet50_resnet18_8xb32_in1k.py index e803af471..fe7fdc82c 100644 --- a/configs/distill/mmcls/abloss/abloss_pretrain_backbone_resnet50_resnet18_8xb32_in1k.py +++ b/configs/distill/mmcls/abloss/abloss_pretrain_backbone_resnet50_resnet18_8xb32_in1k.py @@ -4,7 +4,7 @@ 'mmcls::_base_/default_runtime.py' ] -teacher_ = 'https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth' # noqa: E501 +teacher_ckpt = 'https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth' # noqa: E501 model = dict( _scope_='mmrazor', type='SingleTeacherDistill', diff --git a/configs/pruning/mmcls/dcff/fix_subnet.yaml b/configs/pruning/mmcls/dcff/fix_subnet.yaml new file mode 100644 index 000000000..4caffa65e --- /dev/null +++ b/configs/pruning/mmcls/dcff/fix_subnet.yaml @@ -0,0 +1,186 @@ +backbone.bn1.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.conv1.mutable_attrs.in_channels: +- 3 +- max_channels: 3 +backbone.conv1.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer1.0.bn1.mutable_attrs.num_features: +- 41 +- max_channels: 64 +backbone.layer1.0.bn2.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.out_channels: +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.in_channels: +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer1.1.bn1.mutable_attrs.num_features: +- 41 +- max_channels: 64 +backbone.layer1.1.bn2.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.out_channels: +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.in_channels: +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.bn1.mutable_attrs.num_features: +- 83 +- max_channels: 128 +backbone.layer2.0.bn2.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.0.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.conv1.mutable_attrs.out_channels: +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.in_channels: +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.0.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.downsample.0.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.1.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.1.bn1.mutable_attrs.num_features: +- 83 +- max_channels: 128 +backbone.layer2.1.bn2.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.out_channels: +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.in_channels: +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.bn1.mutable_attrs.num_features: +- 166 +- max_channels: 256 +backbone.layer3.0.bn2.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.0.conv1.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.conv1.mutable_attrs.out_channels: +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.in_channels: +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.0.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.downsample.0.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.1.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.1.bn1.mutable_attrs.num_features: +- 166 +- max_channels: 256 +backbone.layer3.1.bn2.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.out_channels: +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.in_channels: +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.bn1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.0.bn2.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.0.conv1.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.conv1.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.0.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.downsample.0.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.bn1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.bn2.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +head.fc.mutable_attrs.in_features: +- 358 +- max_channels: 512 +head.fc.mutable_attrs.out_features: +- 1000 +- max_channels: 1000 diff --git a/configs/pruning/mmcls/dcff/resnet_cls.json b/configs/pruning/mmcls/dcff/resnet_cls.json deleted file mode 100644 index 3fafa125d..000000000 --- a/configs/pruning/mmcls/dcff/resnet_cls.json +++ /dev/null @@ -1,509 +0,0 @@ -{ - "backbone.conv1_(0, 3)_3":{ - "init_args":{ - "num_channels":3, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 3 - ], - "choice_mode":"number" - }, - "choice":3 - }, - "backbone.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 64 - ], - "choice_mode":"number" - }, - "choice":64 - }, - "backbone.layer1.0.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 41 - ], - "choice_mode":"number" - }, - "choice":41 - }, - "backbone.layer1.0.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 38 - ], - "choice_mode":"number" - }, - "choice":38 - }, - "backbone.layer1.0.conv3_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 230 - ], - "choice_mode":"number" - }, - "choice":230 - }, - "backbone.layer1.1.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 41 - ], - "choice_mode":"number" - }, - "choice":41 - }, - "backbone.layer1.1.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 38 - ], - "choice_mode":"number" - }, - "choice":38 - }, - "backbone.layer1.2.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 41 - ], - "choice_mode":"number" - }, - "choice":41 - }, - "backbone.layer1.2.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 38 - ], - "choice_mode":"number" - }, - "choice":38 - }, - "backbone.layer2.0.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.0.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer2.0.conv3_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 460 - ], - "choice_mode":"number" - }, - "choice":460 - }, - "backbone.layer2.1.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.1.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer2.2.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.2.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer2.3.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.3.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer3.0.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 166 - ], - "choice_mode":"number" - }, - "choice":166 - }, - "backbone.layer3.0.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 153 - ], - "choice_mode":"number" - }, - "choice":153 - }, - "backbone.layer3.0.conv3_(0, 1024)_1024":{ - "init_args":{ - "num_channels":1024, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 921 - ], - "choice_mode":"number" - }, - "choice":921 - }, - "backbone.layer3.1.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 166 - ], - "choice_mode":"number" - }, - "choice":166 - }, - "backbone.layer3.1.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 153 - ], - "choice_mode":"number" - }, - "choice":153 - }, - "backbone.layer3.2.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 166 - ], - "choice_mode":"number" - }, - "choice":166 - }, - "backbone.layer3.2.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 153 - ], - "choice_mode":"number" - }, - "choice":153 - }, - "backbone.layer3.3.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.3.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.4.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.4.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.5.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.5.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer4.0.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.0.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.0.conv3_(0, 2048)_2048":{ - "init_args":{ - "num_channels":2048, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 1843 - ], - "choice_mode":"number" - }, - "choice":1843 - }, - "backbone.layer4.1.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.1.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.2.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.2.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "head.fc_(0, 1000)_1000":{ - "init_args":{ - "num_channels":1000, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 1000 - ], - "choice_mode":"number" - }, - "choice":1000 - } -} diff --git a/configs/pruning/mmdet/dcff/fix_subnet.yaml b/configs/pruning/mmdet/dcff/fix_subnet.yaml new file mode 100644 index 000000000..4caffa65e --- /dev/null +++ b/configs/pruning/mmdet/dcff/fix_subnet.yaml @@ -0,0 +1,186 @@ +backbone.bn1.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.conv1.mutable_attrs.in_channels: +- 3 +- max_channels: 3 +backbone.conv1.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer1.0.bn1.mutable_attrs.num_features: +- 41 +- max_channels: 64 +backbone.layer1.0.bn2.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.out_channels: +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.in_channels: +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer1.1.bn1.mutable_attrs.num_features: +- 41 +- max_channels: 64 +backbone.layer1.1.bn2.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.out_channels: +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.in_channels: +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.bn1.mutable_attrs.num_features: +- 83 +- max_channels: 128 +backbone.layer2.0.bn2.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.0.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.conv1.mutable_attrs.out_channels: +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.in_channels: +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.0.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.downsample.0.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.1.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.1.bn1.mutable_attrs.num_features: +- 83 +- max_channels: 128 +backbone.layer2.1.bn2.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.out_channels: +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.in_channels: +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.bn1.mutable_attrs.num_features: +- 166 +- max_channels: 256 +backbone.layer3.0.bn2.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.0.conv1.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.conv1.mutable_attrs.out_channels: +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.in_channels: +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.0.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.downsample.0.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.1.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.1.bn1.mutable_attrs.num_features: +- 166 +- max_channels: 256 +backbone.layer3.1.bn2.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.out_channels: +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.in_channels: +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.bn1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.0.bn2.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.0.conv1.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.conv1.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.0.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.downsample.0.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.bn1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.bn2.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +head.fc.mutable_attrs.in_features: +- 358 +- max_channels: 512 +head.fc.mutable_attrs.out_features: +- 1000 +- max_channels: 1000 diff --git a/configs/pruning/mmdet/dcff/resnet_det.json b/configs/pruning/mmdet/dcff/resnet_det.json deleted file mode 100644 index 7e3de46b3..000000000 --- a/configs/pruning/mmdet/dcff/resnet_det.json +++ /dev/null @@ -1,522 +0,0 @@ -{ - "backbone.conv1_(0, 3)_3":{ - "init_args":{ - "num_channels":3, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 3 - ], - "choice_mode":"number" - }, - "choice":3 - }, - "backbone.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 64 - ], - "choice_mode":"number" - }, - "choice":64 - }, - "backbone.layer1.0.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 41 - ], - "choice_mode":"number" - }, - "choice":41 - }, - "backbone.layer1.0.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 38 - ], - "choice_mode":"number" - }, - "choice":38 - }, - "backbone.layer1.0.conv3_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 230 - ], - "choice_mode":"number" - }, - "choice":230 - }, - "backbone.layer1.1.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 41 - ], - "choice_mode":"number" - }, - "choice":41 - }, - "backbone.layer1.1.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 38 - ], - "choice_mode":"number" - }, - "choice":38 - }, - "backbone.layer1.2.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 41 - ], - "choice_mode":"number" - }, - "choice":41 - }, - "backbone.layer1.2.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 38 - ], - "choice_mode":"number" - }, - "choice":38 - }, - "backbone.layer2.0.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.0.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer2.0.conv3_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 460 - ], - "choice_mode":"number" - }, - "choice":460 - }, - "backbone.layer2.1.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.1.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer2.2.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.2.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer2.3.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.3.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer3.0.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 166 - ], - "choice_mode":"number" - }, - "choice":166 - }, - "backbone.layer3.0.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 153 - ], - "choice_mode":"number" - }, - "choice":153 - }, - "backbone.layer3.0.conv3_(0, 1024)_1024":{ - "init_args":{ - "num_channels":1024, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 921 - ], - "choice_mode":"number" - }, - "choice":921 - }, - "backbone.layer3.1.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 166 - ], - "choice_mode":"number" - }, - "choice":166 - }, - "backbone.layer3.1.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 153 - ], - "choice_mode":"number" - }, - "choice":153 - }, - "backbone.layer3.2.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 166 - ], - "choice_mode":"number" - }, - "choice":166 - }, - "backbone.layer3.2.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 153 - ], - "choice_mode":"number" - }, - "choice":153 - }, - "backbone.layer3.3.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.3.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.4.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.4.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.5.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.5.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer4.0.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.0.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.0.conv3_(0, 2048)_2048":{ - "init_args":{ - "num_channels":2048, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 1843 - ], - "choice_mode":"number" - }, - "choice":1843 - }, - "backbone.layer4.1.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.1.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.2.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.2.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.2.conv3_(0, 2048)_2048":{ - "init_args":{ - "num_channels":2048, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 1843 - ], - "choice_mode":"number" - }, - "choice":1843 - }, - "head.fc_(0, 1000)_1000":{ - "init_args":{ - "num_channels":1000, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 1000 - ], - "choice_mode":"number" - }, - "choice":1000 - } -} diff --git a/configs/pruning/mmpose/dcff/fix_subnet.yaml b/configs/pruning/mmpose/dcff/fix_subnet.yaml new file mode 100644 index 000000000..4caffa65e --- /dev/null +++ b/configs/pruning/mmpose/dcff/fix_subnet.yaml @@ -0,0 +1,186 @@ +backbone.bn1.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.conv1.mutable_attrs.in_channels: +- 3 +- max_channels: 3 +backbone.conv1.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer1.0.bn1.mutable_attrs.num_features: +- 41 +- max_channels: 64 +backbone.layer1.0.bn2.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.out_channels: +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.in_channels: +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer1.1.bn1.mutable_attrs.num_features: +- 41 +- max_channels: 64 +backbone.layer1.1.bn2.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.out_channels: +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.in_channels: +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.bn1.mutable_attrs.num_features: +- 83 +- max_channels: 128 +backbone.layer2.0.bn2.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.0.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.conv1.mutable_attrs.out_channels: +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.in_channels: +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.0.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.downsample.0.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.1.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.1.bn1.mutable_attrs.num_features: +- 83 +- max_channels: 128 +backbone.layer2.1.bn2.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.out_channels: +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.in_channels: +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.bn1.mutable_attrs.num_features: +- 166 +- max_channels: 256 +backbone.layer3.0.bn2.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.0.conv1.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.conv1.mutable_attrs.out_channels: +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.in_channels: +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.0.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.downsample.0.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.1.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.1.bn1.mutable_attrs.num_features: +- 166 +- max_channels: 256 +backbone.layer3.1.bn2.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.out_channels: +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.in_channels: +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.bn1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.0.bn2.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.0.conv1.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.conv1.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.0.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.downsample.0.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.bn1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.bn2.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +head.fc.mutable_attrs.in_features: +- 358 +- max_channels: 512 +head.fc.mutable_attrs.out_features: +- 1000 +- max_channels: 1000 diff --git a/configs/pruning/mmpose/dcff/resnet_pose.json b/configs/pruning/mmpose/dcff/resnet_pose.json deleted file mode 100644 index a08b40503..000000000 --- a/configs/pruning/mmpose/dcff/resnet_pose.json +++ /dev/null @@ -1,509 +0,0 @@ -{ - "backbone.conv1_(0, 3)_3":{ - "init_args":{ - "num_channels":3, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 3 - ], - "choice_mode":"number" - }, - "choice":3 - }, - "backbone.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 64 - ], - "choice_mode":"number" - }, - "choice":64 - }, - "backbone.layer1.0.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 51 - ], - "choice_mode":"number" - }, - "choice":51 - }, - "backbone.layer1.0.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 51 - ], - "choice_mode":"number" - }, - "choice":51 - }, - "backbone.layer1.0.conv3_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 230 - ], - "choice_mode":"number" - }, - "choice":230 - }, - "backbone.layer1.1.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 51 - ], - "choice_mode":"number" - }, - "choice":51 - }, - "backbone.layer1.1.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 51 - ], - "choice_mode":"number" - }, - "choice":51 - }, - "backbone.layer1.2.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 51 - ], - "choice_mode":"number" - }, - "choice":51 - }, - "backbone.layer1.2.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 51 - ], - "choice_mode":"number" - }, - "choice":51 - }, - "backbone.layer2.0.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 102 - ], - "choice_mode":"number" - }, - "choice":102 - }, - "backbone.layer2.0.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 102 - ], - "choice_mode":"number" - }, - "choice":102 - }, - "backbone.layer2.0.conv3_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 460 - ], - "choice_mode":"number" - }, - "choice":460 - }, - "backbone.layer2.1.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 102 - ], - "choice_mode":"number" - }, - "choice":102 - }, - "backbone.layer2.1.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 102 - ], - "choice_mode":"number" - }, - "choice":102 - }, - "backbone.layer2.2.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 102 - ], - "choice_mode":"number" - }, - "choice":102 - }, - "backbone.layer2.2.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 102 - ], - "choice_mode":"number" - }, - "choice":102 - }, - "backbone.layer2.3.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 102 - ], - "choice_mode":"number" - }, - "choice":102 - }, - "backbone.layer2.3.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 102 - ], - "choice_mode":"number" - }, - "choice":102 - }, - "backbone.layer3.0.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 204 - ], - "choice_mode":"number" - }, - "choice":204 - }, - "backbone.layer3.0.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 204 - ], - "choice_mode":"number" - }, - "choice":204 - }, - "backbone.layer3.0.conv3_(0, 1024)_1024":{ - "init_args":{ - "num_channels":1024, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 921 - ], - "choice_mode":"number" - }, - "choice":921 - }, - "backbone.layer3.1.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 204 - ], - "choice_mode":"number" - }, - "choice":204 - }, - "backbone.layer3.1.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 204 - ], - "choice_mode":"number" - }, - "choice":204 - }, - "backbone.layer3.2.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 204 - ], - "choice_mode":"number" - }, - "choice":204 - }, - "backbone.layer3.2.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 204 - ], - "choice_mode":"number" - }, - "choice":204 - }, - "backbone.layer3.3.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 217 - ], - "choice_mode":"number" - }, - "choice":217 - }, - "backbone.layer3.3.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 217 - ], - "choice_mode":"number" - }, - "choice":217 - }, - "backbone.layer3.4.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 217 - ], - "choice_mode":"number" - }, - "choice":217 - }, - "backbone.layer3.4.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 217 - ], - "choice_mode":"number" - }, - "choice":217 - }, - "backbone.layer3.5.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 217 - ], - "choice_mode":"number" - }, - "choice":217 - }, - "backbone.layer3.5.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 217 - ], - "choice_mode":"number" - }, - "choice":217 - }, - "backbone.layer4.0.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 435 - ], - "choice_mode":"number" - }, - "choice":435 - }, - "backbone.layer4.0.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 435 - ], - "choice_mode":"number" - }, - "choice":435 - }, - "backbone.layer4.0.conv3_(0, 2048)_2048":{ - "init_args":{ - "num_channels":2048, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 1843 - ], - "choice_mode":"number" - }, - "choice":1843 - }, - "backbone.layer4.1.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 435 - ], - "choice_mode":"number" - }, - "choice":435 - }, - "backbone.layer4.1.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 435 - ], - "choice_mode":"number" - }, - "choice":435 - }, - "backbone.layer4.2.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 435 - ], - "choice_mode":"number" - }, - "choice":435 - }, - "backbone.layer4.2.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 435 - ], - "choice_mode":"number" - }, - "choice":435 - }, - "backbone.layer4.2.conv3_(0, 2048)_2048":{ - "init_args":{ - "num_channels":2048, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 1843 - ], - "choice_mode":"number" - }, - "choice":1843 - } -} diff --git a/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes_1.py b/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes_1.py deleted file mode 100644 index aeb62adf5..000000000 --- a/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes_1.py +++ /dev/null @@ -1,99 +0,0 @@ -_base_ = [ - # TODO: use autoaug pipeline. - 'mmseg::_base_/datasets/cityscapes.py', - 'mmseg::_base_/schedules/schedule_160k.py', - 'mmseg::_base_/default_runtime.py', - './pointrend_resnet50.py' -] - -optim_wrapper = dict( - type='OptimWrapper', - optimizer=dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005), - clip_grad=dict(max_norm=25, norm_type=2), - _delete_=True) -train_cfg = dict(type='IterBasedTrainLoop', max_iters=160000, val_interval=800) - -param_scheduler = [ - # warm up - dict(type='LinearLR', by_epoch=False, start_factor=0.1, begin=0, end=200), - dict( - type='PolyLR', - eta_min=1e-4, - power=0.9, - begin=200, - end=80000, - by_epoch=False, - ) -] - -stage_ratio_1 = 0.65 -stage_ratio_2 = 0.6 -stage_ratio_3 = 0.9 -stage_ratio_4 = 0.7 - -# the config template of target_pruning_ratio can be got by -# python ./tools/get_channel_units.py {config_file} --choice -target_pruning_ratio = { - 'backbone.layer1.0.conv1_(0, 64)_64': stage_ratio_1, - 'backbone.layer1.0.conv2_(0, 64)_64': stage_ratio_2, - 'backbone.layer1.0.conv3_(0, 256)_256': stage_ratio_3, - 'backbone.layer1.1.conv1_(0, 64)_64': stage_ratio_1, - 'backbone.layer1.1.conv2_(0, 64)_64': stage_ratio_2, - 'backbone.layer1.2.conv1_(0, 64)_64': stage_ratio_1, - 'backbone.layer1.2.conv2_(0, 64)_64': stage_ratio_2, - # block 1 [0.8, 0.8] downsample=[0.9] - 'backbone.layer2.0.conv1_(0, 128)_128': stage_ratio_1, - 'backbone.layer2.0.conv2_(0, 128)_128': stage_ratio_2, - 'backbone.layer2.0.conv3_(0, 512)_512': stage_ratio_3, - 'backbone.layer2.1.conv1_(0, 128)_128': stage_ratio_1, - 'backbone.layer2.1.conv2_(0, 128)_128': stage_ratio_2, - 'backbone.layer2.2.conv1_(0, 128)_128': stage_ratio_1, - 'backbone.layer2.2.conv2_(0, 128)_128': stage_ratio_2, - 'backbone.layer2.3.conv1_(0, 128)_128': stage_ratio_1, - 'backbone.layer2.3.conv2_(0, 128)_128': stage_ratio_2, - # block 2 [0.8, 0.8] downsample=[0.9] - 'backbone.layer3.0.conv1_(0, 256)_256': stage_ratio_1, - 'backbone.layer3.0.conv2_(0, 256)_256': stage_ratio_2, - 'backbone.layer3.0.conv3_(0, 1024)_1024': stage_ratio_3, - 'backbone.layer3.1.conv1_(0, 256)_256': stage_ratio_1, - 'backbone.layer3.1.conv2_(0, 256)_256': stage_ratio_2, - 'backbone.layer3.2.conv1_(0, 256)_256': stage_ratio_1, - 'backbone.layer3.2.conv2_(0, 256)_256': stage_ratio_2, - 'backbone.layer3.3.conv1_(0, 256)_256': stage_ratio_4, - 'backbone.layer3.3.conv2_(0, 256)_256': stage_ratio_4, - 'backbone.layer3.4.conv1_(0, 256)_256': stage_ratio_4, - 'backbone.layer3.4.conv2_(0, 256)_256': stage_ratio_4, - 'backbone.layer3.5.conv1_(0, 256)_256': stage_ratio_4, - 'backbone.layer3.5.conv2_(0, 256)_256': stage_ratio_4, - # block 3 [0.8, 0.8]*2+[0.8, 0.85]*2 downsample=[0.9] - 'backbone.layer4.0.conv1_(0, 512)_512': stage_ratio_4, - 'backbone.layer4.0.conv2_(0, 512)_512': stage_ratio_4, - 'backbone.layer4.0.conv3_(0, 2048)_2048': stage_ratio_3, - 'backbone.layer4.1.conv1_(0, 512)_512': stage_ratio_4, - 'backbone.layer4.1.conv2_(0, 512)_512': stage_ratio_4, - 'backbone.layer4.2.conv1_(0, 512)_512': stage_ratio_4, - 'backbone.layer4.2.conv2_(0, 512)_512': stage_ratio_4 - # block 4 [0.85, 0.85] downsample=[0.9] -} - -# model settings -model = dict( - _scope_='mmrazor', - type='DCFF', - architecture=_base_.architecture, - mutator_cfg=dict( - type='DCFFChannelMutator', - channel_unit_cfg=dict( - type='DCFFChannelUnit', default_args=dict(choice_mode='ratio')), - parse_cfg=dict( - type='BackwardTracer', - loss_calculator=dict(type='CascadeEncoderDecoderPseudoLoss'))), - target_pruning_ratio=target_pruning_ratio, - step_freq=1, - linear_schedule=False, - is_deployed=False) - -model_wrapper = dict( - type='mmcv.MMDistributedDataParallel', find_unused_parameters=True) - -val_cfg = dict(_delete_=True, type='mmrazor.ItePruneValLoop') diff --git a/configs/pruning/mmseg/dcff/fix_subnet.yaml b/configs/pruning/mmseg/dcff/fix_subnet.yaml new file mode 100644 index 000000000..4caffa65e --- /dev/null +++ b/configs/pruning/mmseg/dcff/fix_subnet.yaml @@ -0,0 +1,186 @@ +backbone.bn1.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.conv1.mutable_attrs.in_channels: +- 3 +- max_channels: 3 +backbone.conv1.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer1.0.bn1.mutable_attrs.num_features: +- 41 +- max_channels: 64 +backbone.layer1.0.bn2.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.out_channels: +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.in_channels: +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer1.1.bn1.mutable_attrs.num_features: +- 41 +- max_channels: 64 +backbone.layer1.1.bn2.mutable_attrs.num_features: +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.out_channels: +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.in_channels: +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.out_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.bn1.mutable_attrs.num_features: +- 83 +- max_channels: 128 +backbone.layer2.0.bn2.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.0.conv1.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.conv1.mutable_attrs.out_channels: +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.in_channels: +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.0.mutable_attrs.in_channels: +- 64 +- max_channels: 64 +backbone.layer2.0.downsample.0.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.1.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.1.bn1.mutable_attrs.num_features: +- 83 +- max_channels: 128 +backbone.layer2.1.bn2.mutable_attrs.num_features: +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.out_channels: +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.in_channels: +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.out_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.bn1.mutable_attrs.num_features: +- 166 +- max_channels: 256 +backbone.layer3.0.bn2.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.0.conv1.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.conv1.mutable_attrs.out_channels: +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.in_channels: +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.0.mutable_attrs.in_channels: +- 76 +- max_channels: 128 +backbone.layer3.0.downsample.0.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.1.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.1.bn1.mutable_attrs.num_features: +- 166 +- max_channels: 256 +backbone.layer3.1.bn2.mutable_attrs.num_features: +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.out_channels: +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.in_channels: +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.out_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.bn1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.0.bn2.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.0.conv1.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.conv1.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.0.mutable_attrs.in_channels: +- 153 +- max_channels: 256 +backbone.layer4.0.downsample.0.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.bn1.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.bn2.mutable_attrs.num_features: +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.in_channels: +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.out_channels: +- 358 +- max_channels: 512 +head.fc.mutable_attrs.in_features: +- 358 +- max_channels: 512 +head.fc.mutable_attrs.out_features: +- 1000 +- max_channels: 1000 diff --git a/configs/pruning/mmseg/dcff/resnet_seg.json b/configs/pruning/mmseg/dcff/resnet_seg.json deleted file mode 100644 index 317fba020..000000000 --- a/configs/pruning/mmseg/dcff/resnet_seg.json +++ /dev/null @@ -1,496 +0,0 @@ -{ - "backbone.conv1_(0, 3)_3":{ - "init_args":{ - "num_channels":3, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 3 - ], - "choice_mode":"number" - }, - "choice":3 - }, - "backbone.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 64 - ], - "choice_mode":"number" - }, - "choice":64 - }, - "backbone.layer1.0.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 41 - ], - "choice_mode":"number" - }, - "choice":41 - }, - "backbone.layer1.0.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 38 - ], - "choice_mode":"number" - }, - "choice":38 - }, - "backbone.layer1.0.conv3_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 230 - ], - "choice_mode":"number" - }, - "choice":230 - }, - "backbone.layer1.1.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 41 - ], - "choice_mode":"number" - }, - "choice":41 - }, - "backbone.layer1.1.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 38 - ], - "choice_mode":"number" - }, - "choice":38 - }, - "backbone.layer1.2.conv1_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 41 - ], - "choice_mode":"number" - }, - "choice":41 - }, - "backbone.layer1.2.conv2_(0, 64)_64":{ - "init_args":{ - "num_channels":64, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 38 - ], - "choice_mode":"number" - }, - "choice":38 - }, - "backbone.layer2.0.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.0.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer2.0.conv3_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 460 - ], - "choice_mode":"number" - }, - "choice":460 - }, - "backbone.layer2.1.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.1.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer2.2.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.2.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer2.3.conv1_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 83 - ], - "choice_mode":"number" - }, - "choice":83 - }, - "backbone.layer2.3.conv2_(0, 128)_128":{ - "init_args":{ - "num_channels":128, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 76 - ], - "choice_mode":"number" - }, - "choice":76 - }, - "backbone.layer3.0.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 166 - ], - "choice_mode":"number" - }, - "choice":166 - }, - "backbone.layer3.0.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 153 - ], - "choice_mode":"number" - }, - "choice":153 - }, - "backbone.layer3.0.conv3_(0, 1024)_1024":{ - "init_args":{ - "num_channels":1024, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 921 - ], - "choice_mode":"number" - }, - "choice":921 - }, - "backbone.layer3.1.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 166 - ], - "choice_mode":"number" - }, - "choice":166 - }, - "backbone.layer3.1.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 153 - ], - "choice_mode":"number" - }, - "choice":153 - }, - "backbone.layer3.2.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 166 - ], - "choice_mode":"number" - }, - "choice":166 - }, - "backbone.layer3.2.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 153 - ], - "choice_mode":"number" - }, - "choice":153 - }, - "backbone.layer3.3.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.3.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.4.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.4.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.5.conv1_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer3.5.conv2_(0, 256)_256":{ - "init_args":{ - "num_channels":256, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 179 - ], - "choice_mode":"number" - }, - "choice":179 - }, - "backbone.layer4.0.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.0.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.0.conv3_(0, 2048)_2048":{ - "init_args":{ - "num_channels":2048, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 1843 - ], - "choice_mode":"number" - }, - "choice":1843 - }, - "backbone.layer4.1.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.1.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.2.conv1_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - }, - "backbone.layer4.2.conv2_(0, 512)_512":{ - "init_args":{ - "num_channels":512, - "divisor":1, - "min_value":1, - "min_ratio":0.9, - "candidate_choices":[ - 358 - ], - "choice_mode":"number" - }, - "choice":358 - } -} diff --git a/mmrazor/engine/runner/__init__.py b/mmrazor/engine/runner/__init__.py index aaf521d6f..0f2b88d27 100644 --- a/mmrazor/engine/runner/__init__.py +++ b/mmrazor/engine/runner/__init__.py @@ -10,5 +10,6 @@ __all__ = [ 'SingleTeacherDistillValLoop', 'DartsEpochBasedTrainLoop', 'DartsIterBasedTrainLoop', 'SlimmableValLoop', 'EvolutionSearchLoop', - 'GreedySamplerTrainLoop', 'SubnetValLoop', 'SelfDistillValLoop' + 'GreedySamplerTrainLoop', 'SubnetValLoop', 'SelfDistillValLoop', + 'ItePruneValLoop' ] diff --git a/mmrazor/engine/runner/iteprune_val_loop.py b/mmrazor/engine/runner/iteprune_val_loop.py index 4bfd43522..b02d4cff7 100644 --- a/mmrazor/engine/runner/iteprune_val_loop.py +++ b/mmrazor/engine/runner/iteprune_val_loop.py @@ -38,7 +38,12 @@ def run(self): def _save_fix_subnet(self): """Save model subnet config.""" - fix_subnet = export_fix_subnet(self.model) + # TO DO: Modify export_fix_subnet's output. Might contain weight return + weight_path = osp.join(self.runner.work_dir, 'fix_subnet_weight.pth') + fix_subnet = export_fix_subnet( + self.model, + dump_mutable_container=True, + export_weight_path=weight_path) save_name = 'fix_subnet.yaml' fileio.dump(fix_subnet, osp.join(self.runner.work_dir, save_name)) self.runner.logger.info( diff --git a/mmrazor/models/architectures/backbones/prune_backbone.py b/mmrazor/models/architectures/backbones/prune_backbone.py deleted file mode 100644 index 0fec3c63a..000000000 --- a/mmrazor/models/architectures/backbones/prune_backbone.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) OpenMMLab. All rights reserved. -import copy -from typing import Dict, List, Optional, Tuple, Union - -import torch -import torch.nn as nn -from mmcv.cnn import build_activation_layer, build_norm_layer -from torch import Tensor - -from mmrazor.registry import MODELS - -@MODELS.register_module() -class PruneBackbone(nn.Module): - """Backbone of Prune Network. Reset Backbone param by subnet.yaml. - - Args: - """ - - def __init__(self, - source_model: Union[BaseModel, Dict], - fix_subnet: Optional[ValidFixMutable] = None, - init_cfg: Optional[Dict] = None) -> None: - super().__init__(init_cfg) - - self.source_model = MODELS.build(source_model) - self.fix_subnet = fix_subnet - self.init_cfg = init_cfg - self.update(self, fix_subnet) - - def update_subnet(self, fix_subnet): - - - def forward(self, x): - return self.forward(x) diff --git a/mmrazor/models/architectures/backbones/searchable_shufflenet_v2.py b/mmrazor/models/architectures/backbones/searchable_shufflenet_v2.py index 2d3e6b2e5..db9e300a4 100644 --- a/mmrazor/models/architectures/backbones/searchable_shufflenet_v2.py +++ b/mmrazor/models/architectures/backbones/searchable_shufflenet_v2.py @@ -50,7 +50,7 @@ class SearchableShuffleNetV2(BaseBackbone): 6 initializers, including ``Constant``, ``Xavier``, ``Normal``, ``Uniform``, ``Kaiming``, and ``Pretrained``. - Excamples: + Examples: >>> mutable_cfg = dict( ... type='OneShotMutableOP', ... candidates=dict( diff --git a/mmrazor/models/mutables/mutable_channel/mutable_channel_container.py b/mmrazor/models/mutables/mutable_channel/mutable_channel_container.py index 5706d0750..4b9f48eac 100644 --- a/mmrazor/models/mutables/mutable_channel/mutable_channel_container.py +++ b/mmrazor/models/mutables/mutable_channel/mutable_channel_container.py @@ -5,6 +5,7 @@ from mmrazor.registry import MODELS from mmrazor.utils import IndexDict +from mmrazor.utils.typing import DumpChosen from ...architectures.dynamic_ops.mixins import DynamicChannelMixin from .base_mutable_channel import BaseMutableChannel from .simple_mutable_channel import SimpleMutableChannel @@ -92,6 +93,13 @@ def register_mutable_channel_to_module(cls, # private methods + def dump_chosen(self) -> DumpChosen: + """Dump chosen.""" + meta = dict(max_channels=self.num_channels) + chosen = self.export_chosen() + + return DumpChosen(chosen=chosen, meta=meta) + def _assert_mutables_valid(self): """Assert the current stored BaseMutableChannels are valid to generate mask.""" diff --git a/mmrazor/registry/__init__.py b/mmrazor/registry/__init__.py index 63ce9b1ef..5a6d9c2da 100644 --- a/mmrazor/registry/__init__.py +++ b/mmrazor/registry/__init__.py @@ -5,11 +5,12 @@ RUNNER_CONSTRUCTORS, RUNNERS, TASK_UTILS, TRANSFORMS, VISBACKENDS, VISUALIZERS, WEIGHT_INITIALIZERS, sub_model) +from .sub_model import sub_model_prune __all__ = [ 'RUNNERS', 'RUNNER_CONSTRUCTORS', 'HOOKS', 'DATASETS', 'DATA_SAMPLERS', 'TRANSFORMS', 'MODELS', 'WEIGHT_INITIALIZERS', 'OPTIMIZERS', 'OPTIM_WRAPPERS', 'OPTIM_WRAPPER_CONSTRUCTORS', 'TASK_UTILS', 'PARAM_SCHEDULERS', 'METRICS', 'MODEL_WRAPPERS', 'LOOPS', 'VISBACKENDS', - 'VISUALIZERS', 'sub_model' + 'VISUALIZERS', 'sub_model', 'sub_model_prune' ] diff --git a/mmrazor/registry/sub_model.py b/mmrazor/registry/sub_model.py new file mode 100644 index 000000000..8da11f409 --- /dev/null +++ b/mmrazor/registry/sub_model.py @@ -0,0 +1,73 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import Dict, Type + +import torch.nn as nn +from mmcv.cnn.bricks import Conv2dAdaptivePadding +from mmengine.model.utils import _BatchNormXd +from mmengine.utils.dl_utils.parrots_wrapper import \ + SyncBatchNorm as EngineSyncBatchNorm + +from mmrazor.models.architectures import dynamic_ops +from mmrazor.models.architectures.dynamic_ops.mixins import DynamicChannelMixin +from mmrazor.models.mutables import MutableChannelContainer +from .registry import MODELS + + +def replace_with_dynamic_ops(model: nn.Module, + dynamicop_map: Dict[Type[nn.Module], + Type[DynamicChannelMixin]]): + """Replace torch modules with dynamic-ops.""" + + def traverse_children(model: nn.Module): + for name, module in model.named_children(): + if isinstance(module, nn.Module): + if type(module) in dynamicop_map: + new_module = dynamicop_map[type(module)].convert_from( + module) + setattr(model, name, new_module) + else: + traverse_children(module) + + traverse_children(model) + + +def register_channel_container(model: nn.Module, + container_class: Type[MutableChannelContainer]): + """register channel container for dynamic ops.""" + for module in model.modules(): + if isinstance(module, DynamicChannelMixin): + in_channels = getattr(module, module.attr_mappings['in_channels'], + 0) + if module.get_mutable_attr('in_channels') is None: + module.register_mutable_attr('in_channels', + container_class(in_channels)) + out_channels = getattr(module, + module.attr_mappings['out_channels'], 0) + if module.get_mutable_attr('out_channels') is None: + + module.register_mutable_attr('out_channels', + container_class(out_channels)) + + +# TO DO: Add more sub_model +# manage sub models for downstream repos +@MODELS.register_module() +def sub_model_prune(cfg, fix_subnet, prefix='', extra_prefix=''): + model = MODELS.build(cfg) + from mmrazor.structures import load_fix_subnet + + dynamicop_map = { + Conv2dAdaptivePadding: dynamic_ops.DynamicConv2dAdaptivePadding, + nn.Conv2d: dynamic_ops.DynamicConv2d, + nn.BatchNorm2d: dynamic_ops.DynamicBatchNorm2d, + nn.Linear: dynamic_ops.DynamicLinear, + nn.SyncBatchNorm: dynamic_ops.DynamicSyncBatchNorm, + EngineSyncBatchNorm: dynamic_ops.DynamicSyncBatchNorm, + _BatchNormXd: dynamic_ops.DynamicBatchNormXd, + } + replace_with_dynamic_ops(model, dynamicop_map) + register_channel_container(model, MutableChannelContainer) + + load_fix_subnet( + model, fix_subnet, prefix=prefix, extra_prefix=extra_prefix) + return model diff --git a/mmrazor/structures/subnet/fix_subnet.py b/mmrazor/structures/subnet/fix_subnet.py index 24ce2acc7..a1bb026c0 100644 --- a/mmrazor/structures/subnet/fix_subnet.py +++ b/mmrazor/structures/subnet/fix_subnet.py @@ -1,6 +1,8 @@ # Copyright (c) OpenMMLab. All rights reserved. +import copy import logging +import torch from mmengine import fileio from mmengine.logging import print_log from torch import nn @@ -87,16 +89,17 @@ def load_fix_subnet(model: nn.Module, def export_fix_subnet(model: nn.Module, + dump_mutable_container: bool = False, dump_derived_mutable: bool = False, - export_weight: bool = False) -> FixMutable: + export_weight_path: str = '') -> FixMutable: """Export subnet that can be loaded by :func:`load_fix_subnet`. Args: model (nn.Module): The target model to export. dump_derived_mutable (bool): Dump information for all derived mutables. Default to False. - export_weight (bool): Export entire subnet when set to True. - Export choice of mutables when set to False. Default to False. + export_weight_path (str): Export subnet weight path. + If empty stop export weight. Default to ''. """ if dump_derived_mutable: print_log( @@ -108,37 +111,24 @@ def export_fix_subnet(model: nn.Module, from mmrazor.models.mutables import DerivedMutable, MutableChannelContainer from mmrazor.models.mutables.base_mutable import BaseMutable - if export_weight: + if export_weight_path: # export subnet ckpt - fix_subnet = dict() - for name, module in model.named_modules(): - if isinstance(module, BaseMutable): - if isinstance(module, - (MutableChannelContainer, - DerivedMutable)) and not dump_derived_mutable: - continue - - if module.alias: - fix_subnet[module.alias] = module.dump_chosen() - else: - fix_subnet[name] = module.dump_chosen() - - return fix_subnet - else: - # export mutable's current_choice - fix_subnet = dict() - for name, module in model.named_modules(): - print("name, module:", name) - if isinstance(module, BaseMutable): - print("name, base:", name) - if isinstance(module, - (MutableChannelContainer, - DerivedMutable)) and not dump_derived_mutable: - continue - - if module.alias: - fix_subnet[module.alias] = module.dump_chosen() - else: - fix_subnet[name] = module.dump_chosen() + static_model = copy.deepcopy(model) + _dynamic_to_static(static_model) + torch.save(static_model.state_dict(), export_weight_path) + fix_subnet = dict() + for name, module in model.named_modules(): + if isinstance(module, BaseMutable): + if isinstance( + module, + MutableChannelContainer) and not dump_mutable_container: + continue + if isinstance(module, DerivedMutable) and not dump_derived_mutable: + continue + + if module.alias: + fix_subnet[module.alias] = module.dump_chosen() + else: + fix_subnet[name] = module.dump_chosen() - return fix_subnet + return fix_subnet diff --git a/tests/data/test_models/test_algorithm/test_subnet.yaml b/tests/data/test_models/test_algorithm/test_subnet.yaml new file mode 100644 index 000000000..bfbb2b3a5 --- /dev/null +++ b/tests/data/test_models/test_algorithm/test_subnet.yaml @@ -0,0 +1,186 @@ +backbone.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 3 +- max_channels: 3 +backbone.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer2.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer2.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer2.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer3.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer3.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer3.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer4.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer4.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer4.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +head.fc.mutable_attrs.in_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +head.fc.mutable_attrs.out_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 1000 +- max_channels: 1000 diff --git a/tests/data/test_registry/resnet_subnet.yaml b/tests/data/test_registry/resnet_subnet.yaml new file mode 100644 index 000000000..bfbb2b3a5 --- /dev/null +++ b/tests/data/test_registry/resnet_subnet.yaml @@ -0,0 +1,186 @@ +backbone.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 3 +- max_channels: 3 +backbone.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer1.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 41 +- max_channels: 64 +backbone.layer1.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer2.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer2.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 64 +- max_channels: 64 +backbone.layer2.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer2.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 83 +- max_channels: 128 +backbone.layer2.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer3.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer3.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 76 +- max_channels: 128 +backbone.layer3.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer3.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 166 +- max_channels: 256 +backbone.layer3.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer4.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer4.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 153 +- max_channels: 256 +backbone.layer4.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +backbone.layer4.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +head.fc.mutable_attrs.in_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 358 +- max_channels: 512 +head.fc.mutable_attrs.out_features: !!python/object/new:mmrazor.utils.typing.DumpChosen +- 1000 +- max_channels: 1000 diff --git a/tests/test_models/test_algorithms/test_dcff_network.py b/tests/test_models/test_algorithms/test_dcff_network.py index a57b5e798..12104839d 100644 --- a/tests/test_models/test_algorithms/test_dcff_network.py +++ b/tests/test_models/test_algorithms/test_dcff_network.py @@ -237,7 +237,6 @@ def test_export_subnet(self): mutator = MODELS.build(MUTATOR_CONFIG_FLOAT) mutator.prepare_from_supernet(model) mutator.set_choices(mutator.sample_choices()) - prune_target = mutator.choice_template custom_groups = [[ 'backbone.layer1.0.conv1_(0, 64)_64', @@ -251,22 +250,68 @@ def test_export_subnet(self): epoch = 6 data = self.fake_cifar_data() - prune_target['backbone.layer1.0.conv1_(0, 64)_64'] = 0.1 - prune_target['backbone.layer1.1.conv1_(0, 64)_64'] = 0.1 + stage_ratio_1 = 0.65 + stage_ratio_2 = 0.6 + stage_ratio_3 = 0.9 + stage_ratio_4 = 0.7 + + target_pruning_ratio = { + 'backbone.layer1.0.conv1_(0, 64)_64': stage_ratio_1, + 'backbone.layer1.0.conv2_(0, 64)_64': stage_ratio_2, + 'backbone.layer1.0.conv3_(0, 256)_256': stage_ratio_3, + 'backbone.layer1.1.conv1_(0, 64)_64': stage_ratio_1, + 'backbone.layer1.1.conv2_(0, 64)_64': stage_ratio_2, + 'backbone.layer1.2.conv1_(0, 64)_64': stage_ratio_1, + 'backbone.layer1.2.conv2_(0, 64)_64': stage_ratio_2, + # block 1 [0.65, 0.6] downsample=[0.9] + 'backbone.layer2.0.conv1_(0, 128)_128': stage_ratio_1, + 'backbone.layer2.0.conv2_(0, 128)_128': stage_ratio_2, + 'backbone.layer2.0.conv3_(0, 512)_512': stage_ratio_3, + 'backbone.layer2.1.conv1_(0, 128)_128': stage_ratio_1, + 'backbone.layer2.1.conv2_(0, 128)_128': stage_ratio_2, + 'backbone.layer2.2.conv1_(0, 128)_128': stage_ratio_1, + 'backbone.layer2.2.conv2_(0, 128)_128': stage_ratio_2, + 'backbone.layer2.3.conv1_(0, 128)_128': stage_ratio_1, + 'backbone.layer2.3.conv2_(0, 128)_128': stage_ratio_2, + # block 2 [0.65, 0.6] downsample=[0.9] + 'backbone.layer3.0.conv1_(0, 256)_256': stage_ratio_1, + 'backbone.layer3.0.conv2_(0, 256)_256': stage_ratio_2, + 'backbone.layer3.0.conv3_(0, 1024)_1024': stage_ratio_3, + 'backbone.layer3.1.conv1_(0, 256)_256': stage_ratio_1, + 'backbone.layer3.1.conv2_(0, 256)_256': stage_ratio_2, + 'backbone.layer3.2.conv1_(0, 256)_256': stage_ratio_1, + 'backbone.layer3.2.conv2_(0, 256)_256': stage_ratio_2, + 'backbone.layer3.3.conv1_(0, 256)_256': stage_ratio_4, + 'backbone.layer3.3.conv2_(0, 256)_256': stage_ratio_4, + 'backbone.layer3.4.conv1_(0, 256)_256': stage_ratio_4, + 'backbone.layer3.4.conv2_(0, 256)_256': stage_ratio_4, + 'backbone.layer3.5.conv1_(0, 256)_256': stage_ratio_4, + 'backbone.layer3.5.conv2_(0, 256)_256': stage_ratio_4, + # block 3 [0.65, 0.6]*2+[0.7, 0.7]*2 downsample=[0.9] + 'backbone.layer4.0.conv1_(0, 512)_512': stage_ratio_4, + 'backbone.layer4.0.conv2_(0, 512)_512': stage_ratio_4, + 'backbone.layer4.0.conv3_(0, 2048)_2048': stage_ratio_3, + 'backbone.layer4.1.conv1_(0, 512)_512': stage_ratio_4, + 'backbone.layer4.1.conv2_(0, 512)_512': stage_ratio_4, + 'backbone.layer4.2.conv1_(0, 512)_512': stage_ratio_4, + 'backbone.layer4.2.conv2_(0, 512)_512': stage_ratio_4 + # block 4 [0.7, 0.7] downsample=[0.9] + } algorithm = DCFF( MODEL_CFG, - target_pruning_ratio=prune_target, + target_pruning_ratio=target_pruning_ratio, mutator_cfg=mutator_cfg, step_freq=epoch_step).to(DEVICE) algorithm.init_weights() - self._set_epoch_ite(1, 2, epoch) + self._set_epoch_ite(0, 0, epoch) algorithm.forward(data['inputs'], data['data_samples'], mode='loss') self.assertEqual(algorithm.step_freq, epoch_step * iter_per_epoch) - subnet = export_fix_subnet(algorithm.architecture, dump_derived_mutable=True) - print("subnet:", subnet) - # print("model:", algorithm.architecture) + subnet = export_fix_subnet( + algorithm.architecture, + dump_mutable_container=True, + dump_derived_mutable=False) from mmengine import fileio - fileio.dump(subnet,'/mnt/lustre/zengyi/mmrazor/experiment/subnet.yaml') - self.assertEqual(1, 0) \ No newline at end of file + fileio.dump(subnet, + 'tests/data/test_models/test_algorithm/test_subnet.yaml') diff --git a/tests/test_registry/test_registry.py b/tests/test_registry/test_registry.py index 9972ae2c2..a14dfd3d6 100644 --- a/tests/test_registry/test_registry.py +++ b/tests/test_registry/test_registry.py @@ -82,6 +82,23 @@ def test_build_razor_from_cfg(self): model = MODELS.build(cfg.model) self.assertTrue(isinstance(model, BaseModel)) + def test_build_subnet_prune_from_cfg(self): + # test cfg_path + # model = MODELS.build(self.arch_cfg_path) + # self.assertIsNotNone(model) + + # test fix subnet + cfg = dict( + # use mmrazor's build_func + type='mmrazor.sub_model_prune', + cfg=dict( + cfg_path='mmcls::resnet/resnet50_8xb32_in1k.py', + pretrained=False), + fix_subnet='tests/data/test_registry/resnet_subnet.yaml', + extra_prefix='backbone.') + model = MODELS.build(cfg) + self.assertTrue(isinstance(model, BaseModel)) + if __name__ == '__main__': unittest.main() diff --git a/tests/test_runners/test_iteprune_val_loop.py b/tests/test_runners/test_iteprune_val_loop.py deleted file mode 100644 index ad241bde0..000000000 --- a/tests/test_runners/test_iteprune_val_loop.py +++ /dev/null @@ -1,142 +0,0 @@ -# Copyright (c) OpenMMLab. All rights reserved. -import copy -import shutil -import tempfile -from unittest import TestCase - -import torch -import torch.nn as nn -from mmengine.config import Config -from mmengine.evaluator import BaseMetric -from mmengine.model import BaseModel -from mmengine.runner import Runner -from torch.utils.data import Dataset - -from mmrazor.engine import ItePruneValLoop -from mmrazor.registry import DATASETS, METRICS, MODELS - - -def collate_fn(data_batch): - return data_batch - - -MODEL_CFG = dict( - _scope_='mmcls', - type='ImageClassifier', - backbone=dict( - type='ResNet', - depth=18, - num_stages=4, - out_indices=(3, ), - style='pytorch'), - neck=dict(type='GlobalAveragePooling'), - head=dict( - type='LinearClsHead', - num_classes=1000, - in_channels=512, - loss=dict(type='CrossEntropyLoss', loss_weight=1.0), - topk=(1, 5), - )) - - -@MODELS.register_module() -class ToyModel_ItePruneValLoop(BaseModel): - - def __init__(self): - super().__init__() - self.conv1 = nn.Conv2d(3, 16, 3, 1, 1) - self.conv2 = nn.Conv2d(16, 16, 3, 1, 1) - - def forward(self, inputs, data_samples, mode='tensor'): - inputs = torch.stack(inputs) - labels = torch.stack(data_samples) - outputs = self.conv1(inputs) - outputs = self.conv2(outputs) - outputs = torch.mean(outputs, (1, 2, 3)) - - if mode == 'tensor': - return outputs - elif mode == 'loss': - loss = (labels - outputs).sum() - outputs = dict(loss=loss) - return outputs - elif mode == 'predict': - outputs = dict(log_vars=dict(a=1, b=0.5)) - return outputs - - -@DATASETS.register_module() -class ToyDataset_ItePruneValLoop(Dataset): - METAINFO = dict() # type: ignore - data = torch.randn(12, 3, 32, 32) - label = torch.ones(12) - - @property - def metainfo(self): - return self.METAINFO - - def __len__(self): - return self.data.size(0) - - def __getitem__(self, index): - return dict(inputs=self.data[index], data_samples=self.label[index]) - - -@METRICS.register_module() -class ToyMetric_ItePruneValLoop(BaseMetric): - - def __init__(self, collect_device='cpu', dummy_metrics=None): - super().__init__(collect_device=collect_device) - self.dummy_metrics = dummy_metrics - - def process(self, data_samples, predictions): - result = {'acc': 1} - self.results.append(result) - - def compute_metrics(self, results): - return dict(acc=1) - - -class TestItePruneValLoop(TestCase): - - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - - val_dataloader = dict( - dataset=dict(type='ToyDataset_ItePruneValLoop'), - sampler=dict(type='DefaultSampler', shuffle=False), - batch_size=3, - num_workers=0) - val_evaluator = dict(type='ToyMetric_ItePruneValLoop') - - val_loop_cfg = dict( - default_scope='mmrazor', - model=dict(type='ToyModel_ItePruneValLoop'), - work_dir=self.temp_dir, - val_dataloader=val_dataloader, - val_evaluator=val_evaluator, - val_cfg=dict(type='ItePruneValLoop'), - custom_hooks=[], - default_hooks=dict( - runtime_info=dict(type='RuntimeInfoHook'), - timer=dict(type='IterTimerHook'), - logger=dict(type='LoggerHook'), - param_scheduler=dict(type='ParamSchedulerHook'), - checkpoint=dict( - type='CheckpointHook', interval=1, by_epoch=True), - sampler_seed=dict(type='DistSamplerSeedHook')), - launcher='none', - env_cfg=dict(dist_cfg=dict(backend='nccl')), - ) - self.val_loop_cfg = Config(val_loop_cfg) - - def tearDown(self): - shutil.rmtree(self.temp_dir) - - def test_init(self): - cfg = copy.deepcopy(self.val_loop_cfg) - cfg.experiment_name = 'test_init_self' - runner = Runner.from_cfg(cfg) - loop = runner.build_val_loop(cfg.val_cfg) - - self.assertIsInstance(loop, ItePruneValLoop) From 52068666bb90020106376ed532140ab18dc66b2c Mon Sep 17 00:00:00 2001 From: zengyi <963525814@qq.com> Date: Thu, 15 Dec 2022 00:53:42 +0800 Subject: [PATCH 4/9] update mutator load --- .../iteprune_resnet_supernet.py | 23 --- .../dcff/dcff_compact_resnet_8xb32_in1k.py | 11 +- configs/pruning/mmcls/dcff/fix_subnet.json | 141 +++++++++++++ ..._compact_faster_rcnn_resnet50_8xb4_coco.py | 11 +- .../dcff/fix_subnet.json} | 0 ...f_compact_topdown_heatmap_resnet50_coco.py | 11 +- .../dcff/fix_subnet.json} | 0 configs/pruning/mmpose/dcff/fix_subnet.yaml | 186 ------------------ ...pact_pointrend_resnet50_8xb2_cityscapes.py | 10 +- configs/pruning/mmseg/dcff/fix_subnet.json | 141 +++++++++++++ configs/pruning/mmseg/dcff/fix_subnet.yaml | 186 ------------------ mmrazor/engine/runner/iteprune_val_loop.py | 16 +- .../units/sequential_mutable_channel_unit.py | 10 + mmrazor/registry/sub_model.py | 76 ++----- mmrazor/structures/subnet/fix_subnet.py | 30 ++- tests/data/test_registry/subnet.json | 141 +++++++++++++ .../test_algorithms/test_dcff_network.py | 14 +- tests/test_registry/test_registry.py | 16 +- 18 files changed, 502 insertions(+), 521 deletions(-) delete mode 100644 configs/_base_/prune_backbones/iteprune_resnet_supernet.py create mode 100644 configs/pruning/mmcls/dcff/fix_subnet.json rename configs/pruning/{mmcls/dcff/fix_subnet.yaml => mmdet/dcff/fix_subnet.json} (100%) rename configs/pruning/{mmdet/dcff/fix_subnet.yaml => mmpose/dcff/fix_subnet.json} (100%) delete mode 100644 configs/pruning/mmpose/dcff/fix_subnet.yaml create mode 100644 configs/pruning/mmseg/dcff/fix_subnet.json delete mode 100644 configs/pruning/mmseg/dcff/fix_subnet.yaml create mode 100644 tests/data/test_registry/subnet.json diff --git a/configs/_base_/prune_backbones/iteprune_resnet_supernet.py b/configs/_base_/prune_backbones/iteprune_resnet_supernet.py deleted file mode 100644 index 6f57e8acf..000000000 --- a/configs/_base_/prune_backbones/iteprune_resnet_supernet.py +++ /dev/null @@ -1,23 +0,0 @@ -_STAGE_MUTABLE = dict( - _scope_='mmrazor', - type='OneShotMutableOP', - candidates=dict( - shuffle_3x3=dict(type='ShuffleBlock', kernel_size=3), - shuffle_5x5=dict(type='ShuffleBlock', kernel_size=5), - shuffle_7x7=dict(type='ShuffleBlock', kernel_size=7), - shuffle_xception=dict(type='ShuffleXception'))) - -arch_setting = [ - # Parameters to build layers. 3 parameters are needed to construct a - # layer, from left to right: channel, num_blocks, mutable_cfg. - [64, 4, _STAGE_MUTABLE], - [160, 4, _STAGE_MUTABLE], - [320, 8, _STAGE_MUTABLE], - [640, 4, _STAGE_MUTABLE] -] - -nas_backbone = dict( - _scope_='mmrazor', - type='SearchableShuffleNetV2', - widen_factor=1.0, - arch_setting=arch_setting) diff --git a/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py b/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py index 379e54abc..76214348a 100644 --- a/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py +++ b/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py @@ -1,8 +1,9 @@ _base_ = ['dcff_resnet_8xb32_in1k.py'] # model settings -model = _base_.model -# Avoid pruning_ratio check in mutator -model['fix_subnet'] = 'configs/pruning/mmcls/dcff/fix_subnet.yaml' -model['target_pruning_ratio'] = None -model['is_deployed'] = True +model_cfg = dict( + _scope_='mmrazor', + type='sub_model_prune', + architecture=dict( + cfg_path='mmcls::resnet/resnet50_8xb32_in1k.py', pretrained=False), + mutator_cfg='configs/pruning/mmcls/dcff/fix_subnet.json') diff --git a/configs/pruning/mmcls/dcff/fix_subnet.json b/configs/pruning/mmcls/dcff/fix_subnet.json new file mode 100644 index 000000000..dfdcea758 --- /dev/null +++ b/configs/pruning/mmcls/dcff/fix_subnet.json @@ -0,0 +1,141 @@ +{ + "type":"DCFFChannelMutator", + "channel_unit_cfg":{ + "type":"DCFFChannelUnit", + "default_args":{ + "choice_mode":"ratio" + }, + "units":{ + "backbone.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":1.0 + }, + "backbone.layer1.0.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.640625 + }, + "backbone.layer1.1.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.640625 + }, + "backbone.layer2.0.conv1_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer2.0.conv2_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.59375 + }, + "backbone.layer2.1.conv1_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer3.0.conv1_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer3.0.conv2_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.59765625 + }, + "backbone.layer3.1.conv1_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer4.0.conv1_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + }, + "backbone.layer4.0.conv2_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + }, + "backbone.layer4.1.conv1_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + } + } + }, + "parse_cfg":{ + "type":"ChannelAnalyzer", + "demo_input":[ + 1, + 3, + 224, + 224 + ], + "tracer_type":"BackwardTracer" + } +} diff --git a/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py b/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py index c16a15080..56cca493d 100644 --- a/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py +++ b/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py @@ -1,9 +1,8 @@ _base_ = ['dcff_faster_rcnn_resnet50_8xb4_coco.py'] # model settings -model = _base_.model -model = _base_.model -# Avoid pruning_ratio check in mutator -model['fix_subnet'] = 'configs/pruning/mmdet/dcff/fix_subnet.yaml' -model['target_pruning_ratio'] = None -model['is_deployed'] = True +model_cfg = dict( + _scope_='mmrazor', + type='sub_model_prune', + architecture=_base_.architecture, + mutator_cfg='configs/pruning/mmdet/dcff/fix_subnet.json') diff --git a/configs/pruning/mmcls/dcff/fix_subnet.yaml b/configs/pruning/mmdet/dcff/fix_subnet.json similarity index 100% rename from configs/pruning/mmcls/dcff/fix_subnet.yaml rename to configs/pruning/mmdet/dcff/fix_subnet.json diff --git a/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py b/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py index 90d4d45b7..8f0043043 100644 --- a/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py +++ b/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py @@ -1,9 +1,8 @@ _base_ = ['dcff_topdown_heatmap_resnet50_coco.py'] # model settings -model = _base_.model -model = _base_.model -# Avoid pruning_ratio check in mutator -model['fix_subnet'] = 'configs/pruning/mmpose/dcff/fix_subnet.yaml' -model['target_pruning_ratio'] = None -model['is_deployed'] = True +model_cfg = dict( + _scope_='mmrazor', + type='sub_model_prune', + architecture=_base_.architecture, + mutator_cfg='configs/pruning/mmpose/dcff/fix_subnet.json') diff --git a/configs/pruning/mmdet/dcff/fix_subnet.yaml b/configs/pruning/mmpose/dcff/fix_subnet.json similarity index 100% rename from configs/pruning/mmdet/dcff/fix_subnet.yaml rename to configs/pruning/mmpose/dcff/fix_subnet.json diff --git a/configs/pruning/mmpose/dcff/fix_subnet.yaml b/configs/pruning/mmpose/dcff/fix_subnet.yaml deleted file mode 100644 index 4caffa65e..000000000 --- a/configs/pruning/mmpose/dcff/fix_subnet.yaml +++ /dev/null @@ -1,186 +0,0 @@ -backbone.bn1.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.conv1.mutable_attrs.in_channels: -- 3 -- max_channels: 3 -backbone.conv1.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer1.0.bn1.mutable_attrs.num_features: -- 41 -- max_channels: 64 -backbone.layer1.0.bn2.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.out_channels: -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.in_channels: -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer1.1.bn1.mutable_attrs.num_features: -- 41 -- max_channels: 64 -backbone.layer1.1.bn2.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.out_channels: -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.in_channels: -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.bn1.mutable_attrs.num_features: -- 83 -- max_channels: 128 -backbone.layer2.0.bn2.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.0.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.conv1.mutable_attrs.out_channels: -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.in_channels: -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.0.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.downsample.0.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.1.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.1.bn1.mutable_attrs.num_features: -- 83 -- max_channels: 128 -backbone.layer2.1.bn2.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.out_channels: -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.in_channels: -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.bn1.mutable_attrs.num_features: -- 166 -- max_channels: 256 -backbone.layer3.0.bn2.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.0.conv1.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.conv1.mutable_attrs.out_channels: -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.in_channels: -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.0.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.downsample.0.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.1.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.1.bn1.mutable_attrs.num_features: -- 166 -- max_channels: 256 -backbone.layer3.1.bn2.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.out_channels: -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.in_channels: -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.bn1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.0.bn2.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.0.conv1.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.conv1.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.0.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.downsample.0.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.bn1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.bn2.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -head.fc.mutable_attrs.in_features: -- 358 -- max_channels: 512 -head.fc.mutable_attrs.out_features: -- 1000 -- max_channels: 1000 diff --git a/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py b/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py index df46d3430..33b8bc919 100644 --- a/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py +++ b/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py @@ -1,8 +1,8 @@ _base_ = ['dcff_pointrend_resnet50_8xb2_cityscapes.py'] # model settings -model = _base_.model -# Avoid pruning_ratio check in mutator -model['fix_subnet'] = 'configs/pruning/mmseg/dcff/fix_subnet.yaml' -model['target_pruning_ratio'] = None -model['is_deployed'] = True +model_cfg = dict( + _scope_='mmrazor', + type='sub_model_prune', + architecture=_base_.architecture, + mutator_cfg='configs/pruning/mmseg/dcff/fix_subnet.json') diff --git a/configs/pruning/mmseg/dcff/fix_subnet.json b/configs/pruning/mmseg/dcff/fix_subnet.json new file mode 100644 index 000000000..dfdcea758 --- /dev/null +++ b/configs/pruning/mmseg/dcff/fix_subnet.json @@ -0,0 +1,141 @@ +{ + "type":"DCFFChannelMutator", + "channel_unit_cfg":{ + "type":"DCFFChannelUnit", + "default_args":{ + "choice_mode":"ratio" + }, + "units":{ + "backbone.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":1.0 + }, + "backbone.layer1.0.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.640625 + }, + "backbone.layer1.1.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.640625 + }, + "backbone.layer2.0.conv1_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer2.0.conv2_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.59375 + }, + "backbone.layer2.1.conv1_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer3.0.conv1_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer3.0.conv2_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.59765625 + }, + "backbone.layer3.1.conv1_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer4.0.conv1_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + }, + "backbone.layer4.0.conv2_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + }, + "backbone.layer4.1.conv1_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + } + } + }, + "parse_cfg":{ + "type":"ChannelAnalyzer", + "demo_input":[ + 1, + 3, + 224, + 224 + ], + "tracer_type":"BackwardTracer" + } +} diff --git a/configs/pruning/mmseg/dcff/fix_subnet.yaml b/configs/pruning/mmseg/dcff/fix_subnet.yaml deleted file mode 100644 index 4caffa65e..000000000 --- a/configs/pruning/mmseg/dcff/fix_subnet.yaml +++ /dev/null @@ -1,186 +0,0 @@ -backbone.bn1.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.conv1.mutable_attrs.in_channels: -- 3 -- max_channels: 3 -backbone.conv1.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer1.0.bn1.mutable_attrs.num_features: -- 41 -- max_channels: 64 -backbone.layer1.0.bn2.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.out_channels: -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.in_channels: -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer1.1.bn1.mutable_attrs.num_features: -- 41 -- max_channels: 64 -backbone.layer1.1.bn2.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.out_channels: -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.in_channels: -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.bn1.mutable_attrs.num_features: -- 83 -- max_channels: 128 -backbone.layer2.0.bn2.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.0.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.conv1.mutable_attrs.out_channels: -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.in_channels: -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.0.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.downsample.0.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.1.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.1.bn1.mutable_attrs.num_features: -- 83 -- max_channels: 128 -backbone.layer2.1.bn2.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.out_channels: -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.in_channels: -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.bn1.mutable_attrs.num_features: -- 166 -- max_channels: 256 -backbone.layer3.0.bn2.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.0.conv1.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.conv1.mutable_attrs.out_channels: -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.in_channels: -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.0.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.downsample.0.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.1.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.1.bn1.mutable_attrs.num_features: -- 166 -- max_channels: 256 -backbone.layer3.1.bn2.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.out_channels: -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.in_channels: -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.bn1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.0.bn2.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.0.conv1.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.conv1.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.0.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.downsample.0.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.bn1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.bn2.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -head.fc.mutable_attrs.in_features: -- 358 -- max_channels: 512 -head.fc.mutable_attrs.out_features: -- 1000 -- max_channels: 1000 diff --git a/mmrazor/engine/runner/iteprune_val_loop.py b/mmrazor/engine/runner/iteprune_val_loop.py index b02d4cff7..dd81b553d 100644 --- a/mmrazor/engine/runner/iteprune_val_loop.py +++ b/mmrazor/engine/runner/iteprune_val_loop.py @@ -39,13 +39,13 @@ def run(self): def _save_fix_subnet(self): """Save model subnet config.""" # TO DO: Modify export_fix_subnet's output. Might contain weight return - weight_path = osp.join(self.runner.work_dir, 'fix_subnet_weight.pth') - fix_subnet = export_fix_subnet( - self.model, - dump_mutable_container=True, - export_weight_path=weight_path) - save_name = 'fix_subnet.yaml' - fileio.dump(fix_subnet, osp.join(self.runner.work_dir, save_name)) + fix_subnet, fix_weight = export_fix_subnet( + self.model, dump_mutable_container=True, export_weight=True) + subnet_name = 'fix_subnet.yaml' + weight_name = 'fix_subnet_weight.pth' + fileio.dump(fix_subnet, osp.join(self.runner.work_dir, subnet_name)) + fileio.dump(fix_weight, osp.join(self.runner.work_dir, weight_name)) self.runner.logger.info( 'export finished and ' - f'{save_name} saved in {self.runner.work_dir}.') + f'{subnet_name}, ' + f'{weight_name} saved in {self.runner.work_dir}.') diff --git a/mmrazor/models/mutables/mutable_channel/units/sequential_mutable_channel_unit.py b/mmrazor/models/mutables/mutable_channel/units/sequential_mutable_channel_unit.py index 89dc785ed..5f15e53ab 100644 --- a/mmrazor/models/mutables/mutable_channel/units/sequential_mutable_channel_unit.py +++ b/mmrazor/models/mutables/mutable_channel/units/sequential_mutable_channel_unit.py @@ -59,6 +59,16 @@ def init_from_mutable_channel(cls, unit.mutable_channel = mutable_channel return unit + @classmethod + def init_from_cfg(cls, model: nn.Module, config: Dict): + """init a Channel using a config which can be generated by + self.config_template(), include init choice.""" + unit = super().init_from_cfg(model, config) + # TO DO: add illegal judgement here? + if 'choice' in config: + unit.current_choice = config['choice'] + return unit + def prepare_for_pruning(self, model: nn.Module): """Prepare for pruning, including register mutable channels.""" # register MutableMask diff --git a/mmrazor/registry/sub_model.py b/mmrazor/registry/sub_model.py index 8da11f409..963a48455 100644 --- a/mmrazor/registry/sub_model.py +++ b/mmrazor/registry/sub_model.py @@ -1,73 +1,25 @@ # Copyright (c) OpenMMLab. All rights reserved. -from typing import Dict, Type +from typing import Dict, Optional import torch.nn as nn -from mmcv.cnn.bricks import Conv2dAdaptivePadding -from mmengine.model.utils import _BatchNormXd -from mmengine.utils.dl_utils.parrots_wrapper import \ - SyncBatchNorm as EngineSyncBatchNorm +from mmengine import fileio -from mmrazor.models.architectures import dynamic_ops -from mmrazor.models.architectures.dynamic_ops.mixins import DynamicChannelMixin -from mmrazor.models.mutables import MutableChannelContainer +from mmrazor.structures.subnet.fix_subnet import _dynamic_to_static from .registry import MODELS -def replace_with_dynamic_ops(model: nn.Module, - dynamicop_map: Dict[Type[nn.Module], - Type[DynamicChannelMixin]]): - """Replace torch modules with dynamic-ops.""" - - def traverse_children(model: nn.Module): - for name, module in model.named_children(): - if isinstance(module, nn.Module): - if type(module) in dynamicop_map: - new_module = dynamicop_map[type(module)].convert_from( - module) - setattr(model, name, new_module) - else: - traverse_children(module) - - traverse_children(model) - - -def register_channel_container(model: nn.Module, - container_class: Type[MutableChannelContainer]): - """register channel container for dynamic ops.""" - for module in model.modules(): - if isinstance(module, DynamicChannelMixin): - in_channels = getattr(module, module.attr_mappings['in_channels'], - 0) - if module.get_mutable_attr('in_channels') is None: - module.register_mutable_attr('in_channels', - container_class(in_channels)) - out_channels = getattr(module, - module.attr_mappings['out_channels'], 0) - if module.get_mutable_attr('out_channels') is None: - - module.register_mutable_attr('out_channels', - container_class(out_channels)) - - # TO DO: Add more sub_model # manage sub models for downstream repos @MODELS.register_module() -def sub_model_prune(cfg, fix_subnet, prefix='', extra_prefix=''): - model = MODELS.build(cfg) - from mmrazor.structures import load_fix_subnet - - dynamicop_map = { - Conv2dAdaptivePadding: dynamic_ops.DynamicConv2dAdaptivePadding, - nn.Conv2d: dynamic_ops.DynamicConv2d, - nn.BatchNorm2d: dynamic_ops.DynamicBatchNorm2d, - nn.Linear: dynamic_ops.DynamicLinear, - nn.SyncBatchNorm: dynamic_ops.DynamicSyncBatchNorm, - EngineSyncBatchNorm: dynamic_ops.DynamicSyncBatchNorm, - _BatchNormXd: dynamic_ops.DynamicBatchNormXd, - } - replace_with_dynamic_ops(model, dynamicop_map) - register_channel_container(model, MutableChannelContainer) - - load_fix_subnet( - model, fix_subnet, prefix=prefix, extra_prefix=extra_prefix) +def sub_model_prune(architecture, + mutator_cfg, + init_cfg: Optional[Dict] = None) -> nn.Module: + if isinstance(mutator_cfg, str): + mutator_cfg = fileio.load(mutator_cfg) + mutator_cfg['parse_cfg'] = {'type': 'Config'} + model = MODELS.build(architecture) + mutator = MODELS.build(mutator_cfg) + mutator.prepare_from_supernet(model) + mutator.set_choices(mutator.current_choices) + _dynamic_to_static(model) return model diff --git a/mmrazor/structures/subnet/fix_subnet.py b/mmrazor/structures/subnet/fix_subnet.py index a1bb026c0..afd44a959 100644 --- a/mmrazor/structures/subnet/fix_subnet.py +++ b/mmrazor/structures/subnet/fix_subnet.py @@ -2,12 +2,11 @@ import copy import logging -import torch from mmengine import fileio from mmengine.logging import print_log from torch import nn -from mmrazor.utils import FixMutable, ValidFixMutable +from mmrazor.utils import ValidFixMutable from mmrazor.utils.typing import DumpChosen @@ -89,17 +88,15 @@ def load_fix_subnet(model: nn.Module, def export_fix_subnet(model: nn.Module, - dump_mutable_container: bool = False, dump_derived_mutable: bool = False, - export_weight_path: str = '') -> FixMutable: + export_weight: bool = False): """Export subnet that can be loaded by :func:`load_fix_subnet`. Args: model (nn.Module): The target model to export. dump_derived_mutable (bool): Dump information for all derived mutables. Default to False. - export_weight_path (str): Export subnet weight path. - If empty stop export weight. Default to ''. + export_weight (bool): Export subnet weight. Default to False. """ if dump_derived_mutable: print_log( @@ -111,19 +108,12 @@ def export_fix_subnet(model: nn.Module, from mmrazor.models.mutables import DerivedMutable, MutableChannelContainer from mmrazor.models.mutables.base_mutable import BaseMutable - if export_weight_path: - # export subnet ckpt - static_model = copy.deepcopy(model) - _dynamic_to_static(static_model) - torch.save(static_model.state_dict(), export_weight_path) fix_subnet = dict() for name, module in model.named_modules(): if isinstance(module, BaseMutable): - if isinstance( - module, - MutableChannelContainer) and not dump_mutable_container: - continue - if isinstance(module, DerivedMutable) and not dump_derived_mutable: + if isinstance(module, + (MutableChannelContainer, + DerivedMutable)) and not dump_derived_mutable: continue if module.alias: @@ -131,4 +121,10 @@ def export_fix_subnet(model: nn.Module, else: fix_subnet[name] = module.dump_chosen() - return fix_subnet + if export_weight: + # export subnet ckpt + static_model = copy.deepcopy(model) + _dynamic_to_static(static_model) + return fix_subnet, static_model + else: + return fix_subnet diff --git a/tests/data/test_registry/subnet.json b/tests/data/test_registry/subnet.json new file mode 100644 index 000000000..4fe63bda2 --- /dev/null +++ b/tests/data/test_registry/subnet.json @@ -0,0 +1,141 @@ +{ + "type":"DCFFChannelMutator", + "channel_unit_cfg":{ + "type":"DCFFChannelUnit", + "default_args":{ + "choice_mode":"ratio" + }, + "units":{ + "backbone.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":1.0 + }, + "backbone.layer1.0.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.640625 + }, + "backbone.layer1.1.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.640625 + }, + "backbone.layer2.0.conv1_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer2.0.conv2_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.59375 + }, + "backbone.layer2.1.conv1_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer3.0.conv1_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer3.0.conv2_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.59765625 + }, + "backbone.layer3.1.conv1_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer4.0.conv1_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + }, + "backbone.layer4.0.conv2_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + }, + "backbone.layer4.1.conv1_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + } + } + }, + "parse_cfg":{ + "type":"ChannelAnalyzer", + "demo_input":[ + 1, + 3, + 224, + 224 + ], + "tracer_type":"BackwardTracer" + } +} \ No newline at end of file diff --git a/tests/test_models/test_algorithms/test_dcff_network.py b/tests/test_models/test_algorithms/test_dcff_network.py index 12104839d..52f696d42 100644 --- a/tests/test_models/test_algorithms/test_dcff_network.py +++ b/tests/test_models/test_algorithms/test_dcff_network.py @@ -1,5 +1,6 @@ # Copyright (c) OpenMMLab. All rights reserved. import copy +import json import os import unittest @@ -12,7 +13,6 @@ from mmrazor.models.algorithms.pruning.ite_prune_algorithm import \ ItePruneConfigManager from mmrazor.registry import MODELS -from mmrazor.structures import export_fix_subnet # @TASK_UTILS.register_module() @@ -308,10 +308,8 @@ def test_export_subnet(self): self._set_epoch_ite(0, 0, epoch) algorithm.forward(data['inputs'], data['data_samples'], mode='loss') self.assertEqual(algorithm.step_freq, epoch_step * iter_per_epoch) - subnet = export_fix_subnet( - algorithm.architecture, - dump_mutable_container=True, - dump_derived_mutable=False) - from mmengine import fileio - fileio.dump(subnet, - 'tests/data/test_models/test_algorithm/test_subnet.yaml') + config = algorithm.mutator.config_template( + with_channels=False, with_unit_init_args=True) + json_config = json.dumps(config, indent=4, separators=(',', ':')) + with open('tests/data/test_registry/subnet.json', 'w') as file: + file.write(json_config) diff --git a/tests/test_registry/test_registry.py b/tests/test_registry/test_registry.py index a14dfd3d6..713e52db2 100644 --- a/tests/test_registry/test_registry.py +++ b/tests/test_registry/test_registry.py @@ -4,6 +4,7 @@ from unittest import TestCase import torch.nn as nn +from mmengine import fileio from mmengine.config import Config from mmengine.model import BaseModel @@ -83,20 +84,17 @@ def test_build_razor_from_cfg(self): self.assertTrue(isinstance(model, BaseModel)) def test_build_subnet_prune_from_cfg(self): - # test cfg_path - # model = MODELS.build(self.arch_cfg_path) - # self.assertIsNotNone(model) - + mutator_cfg = fileio.load('tests/data/test_registry/subnet.json') + # mutator_cfg['parse_cfg'] = {'type': 'Config'} # test fix subnet - cfg = dict( + model_cfg = dict( # use mmrazor's build_func type='mmrazor.sub_model_prune', - cfg=dict( + architecture=dict( cfg_path='mmcls::resnet/resnet50_8xb32_in1k.py', pretrained=False), - fix_subnet='tests/data/test_registry/resnet_subnet.yaml', - extra_prefix='backbone.') - model = MODELS.build(cfg) + mutator_cfg=mutator_cfg) + model = MODELS.build(model_cfg) self.assertTrue(isinstance(model, BaseModel)) From 8213b33cfc6ca17f0f36fd992a1c74dfbadb7b17 Mon Sep 17 00:00:00 2001 From: zengyi <963525814@qq.com> Date: Thu, 15 Dec 2022 20:06:53 +0800 Subject: [PATCH 5/9] export/load_fix_subnet revision for mutator --- .../dcff/dcff_compact_resnet_8xb32_in1k.py | 8 +- ..._compact_faster_rcnn_resnet50_8xb4_coco.py | 8 +- configs/pruning/mmdet/dcff/fix_subnet.json | 327 ++++++++---------- ...f_compact_topdown_heatmap_resnet50_coco.py | 8 +- configs/pruning/mmpose/dcff/fix_subnet.json | 327 ++++++++---------- ...pact_pointrend_resnet50_8xb2_cityscapes.py | 8 +- configs/pruning/mmseg/dcff/fix_subnet.json | 2 +- mmrazor/engine/runner/iteprune_val_loop.py | 14 +- mmrazor/registry/__init__.py | 3 +- mmrazor/registry/registry.py | 21 +- mmrazor/registry/sub_model.py | 25 -- mmrazor/structures/subnet/fix_subnet.py | 86 ++++- .../test_algorithm/test_subnet.yaml | 186 ---------- tests/data/test_registry/resnet_subnet.yaml | 186 ---------- tests/test_registry/test_registry.py | 8 +- 15 files changed, 412 insertions(+), 805 deletions(-) delete mode 100644 mmrazor/registry/sub_model.py delete mode 100644 tests/data/test_models/test_algorithm/test_subnet.yaml delete mode 100644 tests/data/test_registry/resnet_subnet.yaml diff --git a/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py b/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py index 76214348a..d73cf6fd9 100644 --- a/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py +++ b/configs/pruning/mmcls/dcff/dcff_compact_resnet_8xb32_in1k.py @@ -3,7 +3,9 @@ # model settings model_cfg = dict( _scope_='mmrazor', - type='sub_model_prune', - architecture=dict( + type='sub_model', + cfg=dict( cfg_path='mmcls::resnet/resnet50_8xb32_in1k.py', pretrained=False), - mutator_cfg='configs/pruning/mmcls/dcff/fix_subnet.json') + fix_subnet='configs/pruning/mmcls/dcff/fix_subnet.json', + mode='mutator', + subnet_weight='configs/pruning/mmcls/dcff/fix_subnet_weight.pth') diff --git a/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py b/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py index 56cca493d..8ba24fc9a 100644 --- a/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py +++ b/configs/pruning/mmdet/dcff/dcff_compact_faster_rcnn_resnet50_8xb4_coco.py @@ -3,6 +3,8 @@ # model settings model_cfg = dict( _scope_='mmrazor', - type='sub_model_prune', - architecture=_base_.architecture, - mutator_cfg='configs/pruning/mmdet/dcff/fix_subnet.json') + type='sub_model', + cfg=_base_.architecture, + fix_subnet='configs/pruning/mmdet/dcff/fix_subnet.json', + mode='mutator', + subnet_weight='configs/pruning/mmdet/dcff/fix_subnet_weight.pth') diff --git a/configs/pruning/mmdet/dcff/fix_subnet.json b/configs/pruning/mmdet/dcff/fix_subnet.json index 4caffa65e..9722b07e5 100644 --- a/configs/pruning/mmdet/dcff/fix_subnet.json +++ b/configs/pruning/mmdet/dcff/fix_subnet.json @@ -1,186 +1,141 @@ -backbone.bn1.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.conv1.mutable_attrs.in_channels: -- 3 -- max_channels: 3 -backbone.conv1.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer1.0.bn1.mutable_attrs.num_features: -- 41 -- max_channels: 64 -backbone.layer1.0.bn2.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.out_channels: -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.in_channels: -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer1.1.bn1.mutable_attrs.num_features: -- 41 -- max_channels: 64 -backbone.layer1.1.bn2.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.out_channels: -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.in_channels: -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.bn1.mutable_attrs.num_features: -- 83 -- max_channels: 128 -backbone.layer2.0.bn2.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.0.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.conv1.mutable_attrs.out_channels: -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.in_channels: -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.0.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.downsample.0.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.1.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.1.bn1.mutable_attrs.num_features: -- 83 -- max_channels: 128 -backbone.layer2.1.bn2.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.out_channels: -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.in_channels: -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.bn1.mutable_attrs.num_features: -- 166 -- max_channels: 256 -backbone.layer3.0.bn2.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.0.conv1.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.conv1.mutable_attrs.out_channels: -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.in_channels: -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.0.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.downsample.0.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.1.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.1.bn1.mutable_attrs.num_features: -- 166 -- max_channels: 256 -backbone.layer3.1.bn2.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.out_channels: -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.in_channels: -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.bn1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.0.bn2.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.0.conv1.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.conv1.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.0.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.downsample.0.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.bn1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.bn2.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -head.fc.mutable_attrs.in_features: -- 358 -- max_channels: 512 -head.fc.mutable_attrs.out_features: -- 1000 -- max_channels: 1000 +{ + "type":"DCFFChannelMutator", + "channel_unit_cfg":{ + "type":"DCFFChannelUnit", + "default_args":{ + "choice_mode":"ratio" + }, + "units":{ + "backbone.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":1.0 + }, + "backbone.layer1.0.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.640625 + }, + "backbone.layer1.1.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.640625 + }, + "backbone.layer2.0.conv1_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer2.0.conv2_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.59375 + }, + "backbone.layer2.1.conv1_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer3.0.conv1_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer3.0.conv2_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.59765625 + }, + "backbone.layer3.1.conv1_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484374 + }, + "backbone.layer4.0.conv1_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + }, + "backbone.layer4.0.conv2_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + }, + "backbone.layer4.1.conv1_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + } + } + }, + "parse_cfg":{ + "type":"ChannelAnalyzer", + "demo_input":[ + 1, + 3, + 224, + 224 + ], + "tracer_type":"BackwardTracer" + } +} diff --git a/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py b/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py index 8f0043043..9e0ca2f4a 100644 --- a/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py +++ b/configs/pruning/mmpose/dcff/dcff_compact_topdown_heatmap_resnet50_coco.py @@ -3,6 +3,8 @@ # model settings model_cfg = dict( _scope_='mmrazor', - type='sub_model_prune', - architecture=_base_.architecture, - mutator_cfg='configs/pruning/mmpose/dcff/fix_subnet.json') + type='sub_model', + cfg=_base_.architecture, + fix_subnet='configs/pruning/mmpose/dcff/fix_subnet.json', + mode='mutator', + subnet_weight='configs/pruning/mmpose/dcff/fix_subnet_weight.pth') diff --git a/configs/pruning/mmpose/dcff/fix_subnet.json b/configs/pruning/mmpose/dcff/fix_subnet.json index 4caffa65e..6c5243e0a 100644 --- a/configs/pruning/mmpose/dcff/fix_subnet.json +++ b/configs/pruning/mmpose/dcff/fix_subnet.json @@ -1,186 +1,141 @@ -backbone.bn1.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.conv1.mutable_attrs.in_channels: -- 3 -- max_channels: 3 -backbone.conv1.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer1.0.bn1.mutable_attrs.num_features: -- 41 -- max_channels: 64 -backbone.layer1.0.bn2.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.out_channels: -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.in_channels: -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer1.1.bn1.mutable_attrs.num_features: -- 41 -- max_channels: 64 -backbone.layer1.1.bn2.mutable_attrs.num_features: -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.out_channels: -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.in_channels: -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.out_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.bn1.mutable_attrs.num_features: -- 83 -- max_channels: 128 -backbone.layer2.0.bn2.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.0.conv1.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.conv1.mutable_attrs.out_channels: -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.in_channels: -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.0.mutable_attrs.in_channels: -- 64 -- max_channels: 64 -backbone.layer2.0.downsample.0.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.1.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.1.bn1.mutable_attrs.num_features: -- 83 -- max_channels: 128 -backbone.layer2.1.bn2.mutable_attrs.num_features: -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.out_channels: -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.in_channels: -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.out_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.bn1.mutable_attrs.num_features: -- 166 -- max_channels: 256 -backbone.layer3.0.bn2.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.0.conv1.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.conv1.mutable_attrs.out_channels: -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.in_channels: -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.0.mutable_attrs.in_channels: -- 76 -- max_channels: 128 -backbone.layer3.0.downsample.0.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.1.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.1.bn1.mutable_attrs.num_features: -- 166 -- max_channels: 256 -backbone.layer3.1.bn2.mutable_attrs.num_features: -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.out_channels: -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.in_channels: -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.out_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.bn1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.0.bn2.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.0.conv1.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.conv1.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.0.mutable_attrs.in_channels: -- 153 -- max_channels: 256 -backbone.layer4.0.downsample.0.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.bn1.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.bn2.mutable_attrs.num_features: -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.in_channels: -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.out_channels: -- 358 -- max_channels: 512 -head.fc.mutable_attrs.in_features: -- 358 -- max_channels: 512 -head.fc.mutable_attrs.out_features: -- 1000 -- max_channels: 1000 +{ + "type":"DCFFChannelMutator", + "channel_unit_cfg":{ + "type":"DCFFChannelUnit", + "default_args":{ + "choice_mode":"ratio" + }, + "units":{ + "backbone.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":1.0 + }, + "backbone.layer1.0.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.640625 + }, + "backbone.layer1.1.conv1_(0, 64)_64":{ + "init_args":{ + "num_channels":64, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.640625 + }, + "backbone.layer2.0.conv1_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer2.0.conv2_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.59374 + }, + "backbone.layer2.1.conv1_(0, 128)_128":{ + "init_args":{ + "num_channels":128, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer3.0.conv1_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer3.0.conv2_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.59765625 + }, + "backbone.layer3.1.conv1_(0, 256)_256":{ + "init_args":{ + "num_channels":256, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.6484375 + }, + "backbone.layer4.0.conv1_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + }, + "backbone.layer4.0.conv2_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + }, + "backbone.layer4.1.conv1_(0, 512)_512":{ + "init_args":{ + "num_channels":512, + "choice_mode":"ratio", + "divisor":1, + "min_value":1, + "min_ratio":0.9 + }, + "choice":0.69921875 + } + } + }, + "parse_cfg":{ + "type":"ChannelAnalyzer", + "demo_input":[ + 1, + 3, + 224, + 224 + ], + "tracer_type":"BackwardTracer" + } +} diff --git a/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py b/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py index 33b8bc919..614878d4f 100644 --- a/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py +++ b/configs/pruning/mmseg/dcff/dcff_compact_pointrend_resnet50_8xb2_cityscapes.py @@ -3,6 +3,8 @@ # model settings model_cfg = dict( _scope_='mmrazor', - type='sub_model_prune', - architecture=_base_.architecture, - mutator_cfg='configs/pruning/mmseg/dcff/fix_subnet.json') + type='sub_model', + cfg=_base_.architecture, + fix_subnet='configs/pruning/mmseg/dcff/fix_subnet.json', + mode='mutator', + subnet_weight='configs/pruning/mmseg/dcff/fix_subnet_weight.pth') diff --git a/configs/pruning/mmseg/dcff/fix_subnet.json b/configs/pruning/mmseg/dcff/fix_subnet.json index dfdcea758..bd9fcb189 100644 --- a/configs/pruning/mmseg/dcff/fix_subnet.json +++ b/configs/pruning/mmseg/dcff/fix_subnet.json @@ -124,7 +124,7 @@ "min_value":1, "min_ratio":0.9 }, - "choice":0.69921875 + "choice":0.69921874 } } }, diff --git a/mmrazor/engine/runner/iteprune_val_loop.py b/mmrazor/engine/runner/iteprune_val_loop.py index dd81b553d..305423320 100644 --- a/mmrazor/engine/runner/iteprune_val_loop.py +++ b/mmrazor/engine/runner/iteprune_val_loop.py @@ -1,6 +1,8 @@ # Copyright (c) OpenMMLab. All rights reserved. +import json import os.path as osp +import torch from mmengine import fileio from mmengine.runner import ValLoop @@ -39,12 +41,16 @@ def run(self): def _save_fix_subnet(self): """Save model subnet config.""" # TO DO: Modify export_fix_subnet's output. Might contain weight return - fix_subnet, fix_weight = export_fix_subnet( - self.model, dump_mutable_container=True, export_weight=True) - subnet_name = 'fix_subnet.yaml' + fix_subnet, static_model = export_fix_subnet( + self.model, subnet_export_mode='mutator', export_weight=True) + fix_subnet = json.dumps(fix_subnet, indent=4, separators=(',', ':')) + subnet_name = 'fix_subnet.json' weight_name = 'fix_subnet_weight.pth' fileio.dump(fix_subnet, osp.join(self.runner.work_dir, subnet_name)) - fileio.dump(fix_weight, osp.join(self.runner.work_dir, weight_name)) + torch.save({ + 'state_dict': static_model.state_dict(), + 'meta': {} + }, osp.join(self.runner.work_dir, weight_name)) self.runner.logger.info( 'export finished and ' f'{subnet_name}, ' diff --git a/mmrazor/registry/__init__.py b/mmrazor/registry/__init__.py index 5a6d9c2da..63ce9b1ef 100644 --- a/mmrazor/registry/__init__.py +++ b/mmrazor/registry/__init__.py @@ -5,12 +5,11 @@ RUNNER_CONSTRUCTORS, RUNNERS, TASK_UTILS, TRANSFORMS, VISBACKENDS, VISUALIZERS, WEIGHT_INITIALIZERS, sub_model) -from .sub_model import sub_model_prune __all__ = [ 'RUNNERS', 'RUNNER_CONSTRUCTORS', 'HOOKS', 'DATASETS', 'DATA_SAMPLERS', 'TRANSFORMS', 'MODELS', 'WEIGHT_INITIALIZERS', 'OPTIMIZERS', 'OPTIM_WRAPPERS', 'OPTIM_WRAPPER_CONSTRUCTORS', 'TASK_UTILS', 'PARAM_SCHEDULERS', 'METRICS', 'MODEL_WRAPPERS', 'LOOPS', 'VISBACKENDS', - 'VISUALIZERS', 'sub_model', 'sub_model_prune' + 'VISUALIZERS', 'sub_model' ] diff --git a/mmrazor/registry/registry.py b/mmrazor/registry/registry.py index 684aa8116..8031eaf83 100644 --- a/mmrazor/registry/registry.py +++ b/mmrazor/registry/registry.py @@ -7,6 +7,7 @@ """ from typing import Any, Optional, Union +import torch from mmengine.config import Config, ConfigDict from mmengine.registry import DATA_SAMPLERS as MMENGINE_DATA_SAMPLERS from mmengine.registry import DATASETS as MMENGINE_DATASETS @@ -107,10 +108,26 @@ def build_razor_model_from_cfg( # manage sub models for downstream repos @MODELS.register_module() -def sub_model(cfg, fix_subnet, prefix='', extra_prefix=''): +def sub_model(cfg, + fix_subnet, + mode='mutable', + prefix='', + extra_prefix='', + subnet_weight=None): model = MODELS.build(cfg) from mmrazor.structures import load_fix_subnet load_fix_subnet( - model, fix_subnet, prefix=prefix, extra_prefix=extra_prefix) + model, + fix_subnet, + load_subnet_mode=mode, + prefix=prefix, + extra_prefix=extra_prefix) + if subnet_weight: + if isinstance(subnet_weight, str): + subnet_weight = torch.load(subnet_weight) + if not isinstance(subnet_weight, dict): + raise TypeError('subnet_weight should be a `str` or `dict`' + f'but got {type(subnet_weight)}') + model.load_state_dict(subnet_weight) return model diff --git a/mmrazor/registry/sub_model.py b/mmrazor/registry/sub_model.py deleted file mode 100644 index 963a48455..000000000 --- a/mmrazor/registry/sub_model.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) OpenMMLab. All rights reserved. -from typing import Dict, Optional - -import torch.nn as nn -from mmengine import fileio - -from mmrazor.structures.subnet.fix_subnet import _dynamic_to_static -from .registry import MODELS - - -# TO DO: Add more sub_model -# manage sub models for downstream repos -@MODELS.register_module() -def sub_model_prune(architecture, - mutator_cfg, - init_cfg: Optional[Dict] = None) -> nn.Module: - if isinstance(mutator_cfg, str): - mutator_cfg = fileio.load(mutator_cfg) - mutator_cfg['parse_cfg'] = {'type': 'Config'} - model = MODELS.build(architecture) - mutator = MODELS.build(mutator_cfg) - mutator.prepare_from_supernet(model) - mutator.set_choices(mutator.current_choices) - _dynamic_to_static(model) - return model diff --git a/mmrazor/structures/subnet/fix_subnet.py b/mmrazor/structures/subnet/fix_subnet.py index afd44a959..feafc0d98 100644 --- a/mmrazor/structures/subnet/fix_subnet.py +++ b/mmrazor/structures/subnet/fix_subnet.py @@ -1,11 +1,13 @@ # Copyright (c) OpenMMLab. All rights reserved. import copy import logging +from typing import Dict from mmengine import fileio from mmengine.logging import print_log from torch import nn +from mmrazor.registry import MODELS from mmrazor.utils import ValidFixMutable from mmrazor.utils.typing import DumpChosen @@ -29,6 +31,7 @@ def traverse_children(module: nn.Module) -> None: def load_fix_subnet(model: nn.Module, fix_mutable: ValidFixMutable, + load_subnet_mode: str = 'mutable', prefix: str = '', extra_prefix: str = '') -> None: """Load fix subnet.""" @@ -45,6 +48,22 @@ def load_fix_subnet(model: nn.Module, if isinstance(model, DynamicMixin): raise RuntimeError('Root model can not be dynamic op.') + if load_subnet_mode == 'mutable': + _load_fix_subnet_by_mutable(model, fix_mutable, prefix, extra_prefix) + elif load_subnet_mode == 'mutator': + _load_fix_subnet_by_mutator(model, fix_mutable) + else: + raise ValueError(f'Invalid load_subnet_mode {load_subnet_mode}, ' + 'only mutable or mutator is supported.') + + # convert dynamic op to static op + _dynamic_to_static(model) + + +def _load_fix_subnet_by_mutable(model: nn.Module, + fix_mutable: Dict, + prefix: str = '', + extra_prefix: str = '') -> None: # Avoid circular import from mmrazor.models.mutables import DerivedMutable, MutableChannelContainer from mmrazor.models.mutables.base_mutable import BaseMutable @@ -83,21 +102,63 @@ def load_fix_subnet(model: nn.Module, chosen = DumpChosen(**chosen) module.fix_chosen(chosen.chosen) - # convert dynamic op to static op - _dynamic_to_static(model) + +def _load_fix_subnet_by_mutator(model: nn.Module, mutator_cfg: Dict) -> None: + if 'channel_unit_cfg' not in mutator_cfg: + raise ValueError('mutator_cfg must contain key channel_unit_cfg, ' + f'but got mutator_cfg:' + f'{mutator_cfg}') + mutator_cfg['parse_cfg'] = {'type': 'Config'} + mutator = MODELS.build(mutator_cfg) + mutator.prepare_from_supernet(model) + mutator.set_choices(mutator.current_choices) def export_fix_subnet(model: nn.Module, + export_subnet_mode: str = 'mutable', dump_derived_mutable: bool = False, export_weight: bool = False): - """Export subnet that can be loaded by :func:`load_fix_subnet`. + """Export subnet that can be loaded by :func:`load_fix_subnet`. Include + subnet structure and subnet weight. Args: model (nn.Module): The target model to export. + export_subnet_mode (bool): Subnet export method choice. + Export by `mutable.dump_chosen()` when set to 'mutable' (NAS) + Export by `mutator.config_template()` when set to 'mutator' (Prune) dump_derived_mutable (bool): Dump information for all derived mutables. - Default to False. + Valid when `export_subnet_mode`='mutable'. Default to False. export_weight (bool): Export subnet weight. Default to False. + + Return: + fix_subnet (ValidFixMutable): Exported subnet choice config. + static_model (nn.Module): Exported static model. + Valid when `export_weight`=True. """ + + static_model = copy.deepcopy(model) + + fix_subnet = dict() + if export_subnet_mode == 'mutable': + fix_subnet = _export_subnet_by_mutable(static_model, + dump_derived_mutable) + elif export_subnet_mode == 'mutator': + fix_subnet = _export_subnet_by_mutator(static_model) + else: + raise ValueError(f'Invalid export_subnet_mode {export_subnet_mode}, ' + 'only mutable or mutator is supported.') + + if export_weight: + # export subnet ckpt + print_log('Exporting fixed subnet weight') + _dynamic_to_static(static_model) + return fix_subnet, static_model + else: + return fix_subnet + + +def _export_subnet_by_mutable(model: nn.Module, + dump_derived_mutable: bool) -> Dict: if dump_derived_mutable: print_log( 'Trying to dump information of all derived mutables, ' @@ -120,11 +181,14 @@ def export_fix_subnet(model: nn.Module, fix_subnet[module.alias] = module.dump_chosen() else: fix_subnet[name] = module.dump_chosen() + return fix_subnet - if export_weight: - # export subnet ckpt - static_model = copy.deepcopy(model) - _dynamic_to_static(static_model) - return fix_subnet, static_model - else: - return fix_subnet + +def _export_subnet_by_mutator(model: nn.Module) -> Dict: + if not hasattr(model, 'mutator'): + raise ValueError('model should contain `mutator` instance, but got ' + f'{type(model)} model') + fix_subnet = model.mutator.config_template( + with_channels=False, with_unit_init_args=True) + + return fix_subnet diff --git a/tests/data/test_models/test_algorithm/test_subnet.yaml b/tests/data/test_models/test_algorithm/test_subnet.yaml deleted file mode 100644 index bfbb2b3a5..000000000 --- a/tests/data/test_models/test_algorithm/test_subnet.yaml +++ /dev/null @@ -1,186 +0,0 @@ -backbone.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 3 -- max_channels: 3 -backbone.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer2.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer2.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer2.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer3.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer3.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer3.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer4.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer4.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer4.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -head.fc.mutable_attrs.in_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -head.fc.mutable_attrs.out_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 1000 -- max_channels: 1000 diff --git a/tests/data/test_registry/resnet_subnet.yaml b/tests/data/test_registry/resnet_subnet.yaml deleted file mode 100644 index bfbb2b3a5..000000000 --- a/tests/data/test_registry/resnet_subnet.yaml +++ /dev/null @@ -1,186 +0,0 @@ -backbone.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 3 -- max_channels: 3 -backbone.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer1.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 41 -- max_channels: 64 -backbone.layer1.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer2.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer2.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 64 -- max_channels: 64 -backbone.layer2.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer2.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 83 -- max_channels: 128 -backbone.layer2.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer3.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer3.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 76 -- max_channels: 128 -backbone.layer3.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer3.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 166 -- max_channels: 256 -backbone.layer3.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer4.0.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer4.0.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.0.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 153 -- max_channels: 256 -backbone.layer4.0.downsample.0.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.0.downsample.1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.bn1.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.bn2.mutable_attrs.num_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.conv1.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.in_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -backbone.layer4.1.conv2.mutable_attrs.out_channels: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -head.fc.mutable_attrs.in_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 358 -- max_channels: 512 -head.fc.mutable_attrs.out_features: !!python/object/new:mmrazor.utils.typing.DumpChosen -- 1000 -- max_channels: 1000 diff --git a/tests/test_registry/test_registry.py b/tests/test_registry/test_registry.py index 713e52db2..0d5a2666d 100644 --- a/tests/test_registry/test_registry.py +++ b/tests/test_registry/test_registry.py @@ -85,15 +85,15 @@ def test_build_razor_from_cfg(self): def test_build_subnet_prune_from_cfg(self): mutator_cfg = fileio.load('tests/data/test_registry/subnet.json') - # mutator_cfg['parse_cfg'] = {'type': 'Config'} # test fix subnet model_cfg = dict( # use mmrazor's build_func - type='mmrazor.sub_model_prune', - architecture=dict( + type='mmrazor.sub_model', + cfg=dict( cfg_path='mmcls::resnet/resnet50_8xb32_in1k.py', pretrained=False), - mutator_cfg=mutator_cfg) + fix_subnet=mutator_cfg, + mode='mutator') model = MODELS.build(model_cfg) self.assertTrue(isinstance(model, BaseModel)) From a957099a8a4db72b0d2eeb2ae6d34d2c31c5bca8 Mon Sep 17 00:00:00 2001 From: zengyi <963525814@qq.com> Date: Fri, 16 Dec 2022 12:11:49 +0800 Subject: [PATCH 6/9] update fix_subnet with dev-1.x --- mmrazor/engine/runner/iteprune_val_loop.py | 2 +- mmrazor/registry/registry.py | 3 +++ mmrazor/structures/subnet/fix_subnet.py | 19 ++++------------- tests/data/test_registry/subnet.json | 2 +- .../test_algorithms/test_dcff_network.py | 21 +++++++++++++------ tests/test_registry/test_registry.py | 6 +++++- 6 files changed, 29 insertions(+), 24 deletions(-) diff --git a/mmrazor/engine/runner/iteprune_val_loop.py b/mmrazor/engine/runner/iteprune_val_loop.py index dd056b577..8880b6719 100644 --- a/mmrazor/engine/runner/iteprune_val_loop.py +++ b/mmrazor/engine/runner/iteprune_val_loop.py @@ -42,7 +42,7 @@ def _save_fix_subnet(self): """Save model subnet config.""" # TO DO: Modify export_fix_subnet's output. Might contain weight return fix_subnet, static_model = export_fix_subnet( - self.model, subnet_export_mode='mutator', slice_weight=True) + self.model, export_subnet_mode='mutator', slice_weight=True) fix_subnet = json.dumps(fix_subnet, indent=4, separators=(',', ':')) subnet_name = 'fix_subnet.json' weight_name = 'fix_subnet_weight.pth' diff --git a/mmrazor/registry/registry.py b/mmrazor/registry/registry.py index 39dccb151..c6cfc75f9 100644 --- a/mmrazor/registry/registry.py +++ b/mmrazor/registry/registry.py @@ -113,7 +113,10 @@ def sub_model(cfg, prefix='', extra_prefix='', init_cfg=None): + # override model = MODELS.build(cfg) + # save path type cfg process, set init_cfg directly + model.init_cfg = init_cfg from mmrazor.structures import load_fix_subnet load_fix_subnet( diff --git a/mmrazor/structures/subnet/fix_subnet.py b/mmrazor/structures/subnet/fix_subnet.py index 128204e1f..bec757b72 100644 --- a/mmrazor/structures/subnet/fix_subnet.py +++ b/mmrazor/structures/subnet/fix_subnet.py @@ -1,6 +1,5 @@ # Copyright (c) OpenMMLab. All rights reserved. import copy -import logging from typing import Dict, Optional, Tuple from mmengine import fileio @@ -127,7 +126,6 @@ def _load_fix_subnet_by_mutator(model: nn.Module, mutator_cfg: Dict) -> None: def export_fix_subnet( model: nn.Module, export_subnet_mode: str = 'mutable', - dump_derived_mutable: bool = False, slice_weight: bool = False) -> Tuple[FixMutable, Optional[Dict]]: """Export subnet that can be loaded by :func:`load_fix_subnet`. Include subnet structure and subnet weight. @@ -137,8 +135,6 @@ def export_fix_subnet( export_subnet_mode (bool): Subnet export method choice. Export by `mutable.dump_chosen()` when set to 'mutable' (NAS) Export by `mutator.config_template()` when set to 'mutator' (Prune) - dump_derived_mutable (bool): Dump information for all derived mutables. - Valid when `export_subnet_mode`='mutable'. Default to False. slice_weight (bool): Export subnet weight. Default to False. Return: @@ -151,8 +147,7 @@ def export_fix_subnet( fix_subnet = dict() if export_subnet_mode == 'mutable': - fix_subnet = _export_subnet_by_mutable(static_model, - dump_derived_mutable) + fix_subnet = _export_subnet_by_mutable(static_model) elif export_subnet_mode == 'mutator': fix_subnet = _export_subnet_by_mutator(static_model) else: @@ -170,13 +165,7 @@ def export_fix_subnet( return fix_subnet, None -def _export_subnet_by_mutable(model: nn.Module, - dump_derived_mutable: bool) -> Dict: - if dump_derived_mutable: - print_log( - 'Trying to dump information of all derived mutables, ' - 'this might harm readability of the exported configurations.', - level=logging.WARNING) +def _export_subnet_by_mutable(model: nn.Module) -> Dict: # Avoid circular import from mmrazor.models.mutables import DerivedMutable, MutableChannelContainer @@ -197,13 +186,13 @@ def module_dump_chosen(module, fix_subnet): for source_mutable in module.source_mutables: module_dump_chosen(source_mutable, fix_subnet) else: - fix_subnet[name] = module.dump_chosen() + module_dump_chosen(module, fix_subnet) return fix_subnet def _export_subnet_by_mutator(model: nn.Module) -> Dict: if not hasattr(model, 'mutator'): - raise ValueError('model should contain `mutator` instance, but got ' + raise ValueError('model should contain `mutator` attribute, but got ' f'{type(model)} model') fix_subnet = model.mutator.config_template( with_channels=False, with_unit_init_args=True) diff --git a/tests/data/test_registry/subnet.json b/tests/data/test_registry/subnet.json index 4fe63bda2..dfdcea758 100644 --- a/tests/data/test_registry/subnet.json +++ b/tests/data/test_registry/subnet.json @@ -138,4 +138,4 @@ ], "tracer_type":"BackwardTracer" } -} \ No newline at end of file +} diff --git a/tests/test_models/test_algorithms/test_dcff_network.py b/tests/test_models/test_algorithms/test_dcff_network.py index 52f696d42..f3c92852e 100644 --- a/tests/test_models/test_algorithms/test_dcff_network.py +++ b/tests/test_models/test_algorithms/test_dcff_network.py @@ -2,17 +2,19 @@ import copy import json import os +import os.path as osp import unittest import torch from mmcls.structures import ClsDataSample -from mmengine import MessageHub +from mmengine import MessageHub, fileio from mmengine.model import BaseModel from mmrazor.models.algorithms.pruning.dcff import DCFF from mmrazor.models.algorithms.pruning.ite_prune_algorithm import \ ItePruneConfigManager from mmrazor.registry import MODELS +from mmrazor.structures import export_fix_subnet # @TASK_UTILS.register_module() @@ -308,8 +310,15 @@ def test_export_subnet(self): self._set_epoch_ite(0, 0, epoch) algorithm.forward(data['inputs'], data['data_samples'], mode='loss') self.assertEqual(algorithm.step_freq, epoch_step * iter_per_epoch) - config = algorithm.mutator.config_template( - with_channels=False, with_unit_init_args=True) - json_config = json.dumps(config, indent=4, separators=(',', ':')) - with open('tests/data/test_registry/subnet.json', 'w') as file: - file.write(json_config) + + fix_subnet, static_model = export_fix_subnet( + algorithm, export_subnet_mode='mutator', slice_weight=True) + fix_subnet = json.dumps(fix_subnet, indent=4, separators=(',', ':')) + subnet_name = 'subnet.json' + weight_name = 'subnet_weight.pth' + fileio.dump(fix_subnet, + osp.join('tests/data/test_registry/', subnet_name)) + torch.save({ + 'state_dict': static_model.state_dict(), + 'meta': {} + }, osp.join('tests/data/test_registry/', weight_name)) diff --git a/tests/test_registry/test_registry.py b/tests/test_registry/test_registry.py index 0d5a2666d..64de464f2 100644 --- a/tests/test_registry/test_registry.py +++ b/tests/test_registry/test_registry.py @@ -85,6 +85,9 @@ def test_build_razor_from_cfg(self): def test_build_subnet_prune_from_cfg(self): mutator_cfg = fileio.load('tests/data/test_registry/subnet.json') + init_cfg = dict( + type='Pretrained', + checkpoint='tests/data/test_registry/subnet_weight.pth') # test fix subnet model_cfg = dict( # use mmrazor's build_func @@ -93,7 +96,8 @@ def test_build_subnet_prune_from_cfg(self): cfg_path='mmcls::resnet/resnet50_8xb32_in1k.py', pretrained=False), fix_subnet=mutator_cfg, - mode='mutator') + mode='mutator', + init_cfg=init_cfg) model = MODELS.build(model_cfg) self.assertTrue(isinstance(model, BaseModel)) From 98216687d043351af948ad003eb159762f7a467d Mon Sep 17 00:00:00 2001 From: zengyi <963525814@qq.com> Date: Fri, 16 Dec 2022 16:34:53 +0800 Subject: [PATCH 7/9] update comments --- .../mmcls/dcff/dcff_resnet_8xb32_in1k.py | 3 +- .../dcff_faster_rcnn_resnet50_8xb4_coco.py | 3 +- .../dcff_topdown_heatmap_resnet50_coco.py | 3 +- ...dcff_pointrend_resnet50_8xb2_cityscapes.py | 3 +- mmrazor/engine/runner/iteprune_val_loop.py | 10 +++--- mmrazor/models/algorithms/pruning/dcff.py | 7 ++--- .../algorithms/pruning/ite_prune_algorithm.py | 17 ++-------- .../mutable_channel_container.py | 8 ----- .../units/mutable_channel_unit.py | 10 ++++++ .../units/sequential_mutable_channel_unit.py | 10 ------ mmrazor/registry/registry.py | 31 ++++++++++++++----- mmrazor/structures/subnet/fix_subnet.py | 2 +- tests/data/test_registry/subnet.json | 2 +- .../test_algorithms/test_dcff_network.py | 7 +++-- 14 files changed, 53 insertions(+), 63 deletions(-) diff --git a/configs/pruning/mmcls/dcff/dcff_resnet_8xb32_in1k.py b/configs/pruning/mmcls/dcff/dcff_resnet_8xb32_in1k.py index 05a1a5fca..360645a6a 100644 --- a/configs/pruning/mmcls/dcff/dcff_resnet_8xb32_in1k.py +++ b/configs/pruning/mmcls/dcff/dcff_resnet_8xb32_in1k.py @@ -80,7 +80,6 @@ data_preprocessor=None, target_pruning_ratio=target_pruning_ratio, step_freq=1, - linear_schedule=False, - is_deployed=False) + linear_schedule=False) val_cfg = dict(_delete_=True, type='mmrazor.ItePruneValLoop') diff --git a/configs/pruning/mmdet/dcff/dcff_faster_rcnn_resnet50_8xb4_coco.py b/configs/pruning/mmdet/dcff/dcff_faster_rcnn_resnet50_8xb4_coco.py index 11bc33200..b6051c649 100644 --- a/configs/pruning/mmdet/dcff/dcff_faster_rcnn_resnet50_8xb4_coco.py +++ b/configs/pruning/mmdet/dcff/dcff_faster_rcnn_resnet50_8xb4_coco.py @@ -79,8 +79,7 @@ tracer_type='BackwardTracer')), target_pruning_ratio=target_pruning_ratio, step_freq=1, - linear_schedule=False, - is_deployed=False) + linear_schedule=False) model_wrapper = dict( type='mmcv.MMDistributedDataParallel', find_unused_parameters=True) diff --git a/configs/pruning/mmpose/dcff/dcff_topdown_heatmap_resnet50_coco.py b/configs/pruning/mmpose/dcff/dcff_topdown_heatmap_resnet50_coco.py index 2198139a8..d18bccc02 100644 --- a/configs/pruning/mmpose/dcff/dcff_topdown_heatmap_resnet50_coco.py +++ b/configs/pruning/mmpose/dcff/dcff_topdown_heatmap_resnet50_coco.py @@ -119,8 +119,7 @@ tracer_type='BackwardTracer')), target_pruning_ratio=target_pruning_ratio, step_freq=1, - linear_schedule=False, - is_deployed=False) + linear_schedule=False) dataset_type = 'CocoDataset' data_mode = 'topdown' diff --git a/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes.py b/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes.py index 79c5d8b2a..d552e23e9 100644 --- a/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes.py +++ b/configs/pruning/mmseg/dcff/dcff_pointrend_resnet50_8xb2_cityscapes.py @@ -91,8 +91,7 @@ tracer_type='BackwardTracer')), target_pruning_ratio=target_pruning_ratio, step_freq=200, - linear_schedule=False, - is_deployed=False) + linear_schedule=False) model_wrapper = dict( type='mmcv.MMDistributedDataParallel', find_unused_parameters=True) diff --git a/mmrazor/engine/runner/iteprune_val_loop.py b/mmrazor/engine/runner/iteprune_val_loop.py index 8880b6719..07d40c884 100644 --- a/mmrazor/engine/runner/iteprune_val_loop.py +++ b/mmrazor/engine/runner/iteprune_val_loop.py @@ -3,7 +3,6 @@ import os.path as osp import torch -from mmengine import fileio from mmengine.runner import ValLoop from mmrazor.registry import LOOPS @@ -46,11 +45,10 @@ def _save_fix_subnet(self): fix_subnet = json.dumps(fix_subnet, indent=4, separators=(',', ':')) subnet_name = 'fix_subnet.json' weight_name = 'fix_subnet_weight.pth' - fileio.dump(fix_subnet, osp.join(self.runner.work_dir, subnet_name)) - torch.save({ - 'state_dict': static_model.state_dict(), - 'meta': {} - }, osp.join(self.runner.work_dir, weight_name)) + with open(osp.join(self.runner.work_dir, subnet_name), 'w') as file: + file.write(fix_subnet) + torch.save({'state_dict': static_model.state_dict()}, + osp.join(self.runner.work_dir, weight_name)) self.runner.logger.info( 'export finished and ' f'{subnet_name}, ' diff --git a/mmrazor/models/algorithms/pruning/dcff.py b/mmrazor/models/algorithms/pruning/dcff.py index e09199903..71b669c09 100644 --- a/mmrazor/models/algorithms/pruning/dcff.py +++ b/mmrazor/models/algorithms/pruning/dcff.py @@ -46,8 +46,6 @@ class DCFF(ItePruneAlgorithm): Defaults to None. linear_schedule (bool, optional): flag to set linear ratio schedule. Defaults to False due to dcff fixed pruning rate. - is_deployed (bool, optional): flag to set deployed algorithm. - Defaults to False. """ def __init__(self, @@ -61,12 +59,11 @@ def __init__(self, step_freq=1, prune_times=0, init_cfg: Optional[Dict] = None, - linear_schedule=False, - is_deployed=False) -> None: + linear_schedule=False) -> None: # invalid param prune_times, reset after message_hub get [max_epoch] super().__init__(architecture, mutator_cfg, fix_subnet, data_preprocessor, target_pruning_ratio, step_freq, - prune_times, init_cfg, linear_schedule, is_deployed) + prune_times, init_cfg, linear_schedule) def _calc_temperature(self, cur_num: int, max_num: int): """Calculate temperature param.""" diff --git a/mmrazor/models/algorithms/pruning/ite_prune_algorithm.py b/mmrazor/models/algorithms/pruning/ite_prune_algorithm.py index 2c0362e64..88d2e6067 100644 --- a/mmrazor/models/algorithms/pruning/ite_prune_algorithm.py +++ b/mmrazor/models/algorithms/pruning/ite_prune_algorithm.py @@ -113,8 +113,6 @@ class ItePruneAlgorithm(BaseAlgorithm): Defaults to None. linear_schedule (bool, optional): flag to set linear ratio schedule. Defaults to True. - is_deployed (bool, optional): flag to set deployed algorithm. - Defaults to False. """ def __init__(self, @@ -129,8 +127,7 @@ def __init__(self, step_freq=1, prune_times=1, init_cfg: Optional[Dict] = None, - linear_schedule=True, - is_deployed=False) -> None: + linear_schedule=True) -> None: super().__init__(architecture, data_preprocessor, init_cfg) @@ -139,17 +136,9 @@ def __init__(self, self.step_freq = step_freq self.prune_times = prune_times self.linear_schedule = linear_schedule - self.is_deployed = is_deployed - if self.is_deployed: - assert fix_subnet is not None - # Avoid circular import - from mmrazor.structures import load_fix_subnet - load_fix_subnet(self.architecture, fix_subnet) - else: - # init mutator - self.mutator: ChannelMutator = MODELS.build(mutator_cfg) - self.mutator.prepare_from_supernet(self.architecture) + self.mutator: ChannelMutator = MODELS.build(mutator_cfg) + self.mutator.prepare_from_supernet(self.architecture) def group_target_pruning_ratio( self, target: Dict[str, float], diff --git a/mmrazor/models/mutables/mutable_channel/mutable_channel_container.py b/mmrazor/models/mutables/mutable_channel/mutable_channel_container.py index 4b9f48eac..5706d0750 100644 --- a/mmrazor/models/mutables/mutable_channel/mutable_channel_container.py +++ b/mmrazor/models/mutables/mutable_channel/mutable_channel_container.py @@ -5,7 +5,6 @@ from mmrazor.registry import MODELS from mmrazor.utils import IndexDict -from mmrazor.utils.typing import DumpChosen from ...architectures.dynamic_ops.mixins import DynamicChannelMixin from .base_mutable_channel import BaseMutableChannel from .simple_mutable_channel import SimpleMutableChannel @@ -93,13 +92,6 @@ def register_mutable_channel_to_module(cls, # private methods - def dump_chosen(self) -> DumpChosen: - """Dump chosen.""" - meta = dict(max_channels=self.num_channels) - chosen = self.export_chosen() - - return DumpChosen(chosen=chosen, meta=meta) - def _assert_mutables_valid(self): """Assert the current stored BaseMutableChannels are valid to generate mask.""" diff --git a/mmrazor/models/mutables/mutable_channel/units/mutable_channel_unit.py b/mmrazor/models/mutables/mutable_channel/units/mutable_channel_unit.py index 9963f671b..dabe41fab 100644 --- a/mmrazor/models/mutables/mutable_channel/units/mutable_channel_unit.py +++ b/mmrazor/models/mutables/mutable_channel/units/mutable_channel_unit.py @@ -41,6 +41,16 @@ def __init__(self, num_channels: int, **kwargs) -> None: super().__init__(num_channels) + @classmethod + def init_from_cfg(cls, model: nn.Module, config: Dict): + """init a Channel using a config which can be generated by + self.config_template(), include init choice.""" + unit = super().init_from_cfg(model, config) + # TO DO: add illegal judgement here? + if 'choice' in config: + unit.current_choice = config['choice'] + return unit + @classmethod def init_from_mutable_channel(cls, mutable_channel: BaseMutableChannel): unit = cls(mutable_channel.num_channels) diff --git a/mmrazor/models/mutables/mutable_channel/units/sequential_mutable_channel_unit.py b/mmrazor/models/mutables/mutable_channel/units/sequential_mutable_channel_unit.py index 5f15e53ab..89dc785ed 100644 --- a/mmrazor/models/mutables/mutable_channel/units/sequential_mutable_channel_unit.py +++ b/mmrazor/models/mutables/mutable_channel/units/sequential_mutable_channel_unit.py @@ -59,16 +59,6 @@ def init_from_mutable_channel(cls, unit.mutable_channel = mutable_channel return unit - @classmethod - def init_from_cfg(cls, model: nn.Module, config: Dict): - """init a Channel using a config which can be generated by - self.config_template(), include init choice.""" - unit = super().init_from_cfg(model, config) - # TO DO: add illegal judgement here? - if 'choice' in config: - unit.current_choice = config['choice'] - return unit - def prepare_for_pruning(self, model: nn.Module): """Prepare for pruning, including register mutable channels.""" # register MutableMask diff --git a/mmrazor/registry/registry.py b/mmrazor/registry/registry.py index c6cfc75f9..0a066b0a0 100644 --- a/mmrazor/registry/registry.py +++ b/mmrazor/registry/registry.py @@ -5,8 +5,9 @@ More details can be found at https://mmengine.readthedocs.io/en/latest/tutorials/registry.html. """ -from typing import Any, Optional, Union +from typing import Any, Dict, Optional, Union +import torch from mmengine.config import Config, ConfigDict from mmengine.registry import DATA_SAMPLERS as MMENGINE_DATA_SAMPLERS from mmengine.registry import DATASETS as MMENGINE_DATASETS @@ -109,14 +110,16 @@ def build_razor_model_from_cfg( @MODELS.register_module() def sub_model(cfg, fix_subnet, - mode='mutable', - prefix='', - extra_prefix='', - init_cfg=None): - # override + mode: str = 'mutable', + prefix: str = '', + extra_prefix: str = '', + init_weight_supernet: bool = False, + init_cfg: Optional[Dict] = None): model = MODELS.build(cfg) # save path type cfg process, set init_cfg directly - model.init_cfg = init_cfg + if init_cfg and (not init_weight_supernet): + # load subnet weight when init_cfg is valid + model.init_cfg = init_cfg from mmrazor.structures import load_fix_subnet load_fix_subnet( @@ -125,4 +128,18 @@ def sub_model(cfg, load_subnet_mode=mode, prefix=prefix, extra_prefix=extra_prefix) + + if init_weight_supernet: + # load supernet weight via sliced state_dict + if init_cfg is None: + raise TypeError(f'`init_cfg` should be a `dict`' + 'when `init_weight_supernet` is True' + f'but got {init_cfg}') + if 'checkpoint' in init_cfg: + init_cfg = torch.load(init_cfg['checkpoint']) + if not isinstance(init_cfg, dict): + raise TypeError('init_cfg should be a `str` or `dict`' + f'but got {type(init_cfg)}') + model.load_state_dict(init_cfg) + return model diff --git a/mmrazor/structures/subnet/fix_subnet.py b/mmrazor/structures/subnet/fix_subnet.py index bec757b72..311dc8936 100644 --- a/mmrazor/structures/subnet/fix_subnet.py +++ b/mmrazor/structures/subnet/fix_subnet.py @@ -139,7 +139,7 @@ def export_fix_subnet( Return: fix_subnet (ValidFixMutable): Exported subnet choice config. - static_model (nn.Module): Exported static model. + static_model (Optional[Dict]): Exported static model state_dict. Valid when `slice_weight`=True. """ diff --git a/tests/data/test_registry/subnet.json b/tests/data/test_registry/subnet.json index dfdcea758..4fe63bda2 100644 --- a/tests/data/test_registry/subnet.json +++ b/tests/data/test_registry/subnet.json @@ -138,4 +138,4 @@ ], "tracer_type":"BackwardTracer" } -} +} \ No newline at end of file diff --git a/tests/test_models/test_algorithms/test_dcff_network.py b/tests/test_models/test_algorithms/test_dcff_network.py index f3c92852e..9d369f3f2 100644 --- a/tests/test_models/test_algorithms/test_dcff_network.py +++ b/tests/test_models/test_algorithms/test_dcff_network.py @@ -7,7 +7,7 @@ import torch from mmcls.structures import ClsDataSample -from mmengine import MessageHub, fileio +from mmengine import MessageHub from mmengine.model import BaseModel from mmrazor.models.algorithms.pruning.dcff import DCFF @@ -316,8 +316,9 @@ def test_export_subnet(self): fix_subnet = json.dumps(fix_subnet, indent=4, separators=(',', ':')) subnet_name = 'subnet.json' weight_name = 'subnet_weight.pth' - fileio.dump(fix_subnet, - osp.join('tests/data/test_registry/', subnet_name)) + with open(osp.join('tests/data/test_registry/', subnet_name), + 'w') as file: + file.write(fix_subnet) torch.save({ 'state_dict': static_model.state_dict(), 'meta': {} From e4c683b6772369dab54457270a06820d0cef313b Mon Sep 17 00:00:00 2001 From: zengyi <963525814@qq.com> Date: Fri, 16 Dec 2022 16:40:22 +0800 Subject: [PATCH 8/9] update docs --- mmrazor/registry/registry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mmrazor/registry/registry.py b/mmrazor/registry/registry.py index 0a066b0a0..4cb378d47 100644 --- a/mmrazor/registry/registry.py +++ b/mmrazor/registry/registry.py @@ -132,13 +132,13 @@ def sub_model(cfg, if init_weight_supernet: # load supernet weight via sliced state_dict if init_cfg is None: - raise TypeError(f'`init_cfg` should be a `dict`' + raise TypeError(f'`init_cfg` should be valid' 'when `init_weight_supernet` is True' f'but got {init_cfg}') if 'checkpoint' in init_cfg: init_cfg = torch.load(init_cfg['checkpoint']) if not isinstance(init_cfg, dict): - raise TypeError('init_cfg should be a `str` or `dict`' + raise TypeError('init_cfg should be a `dict`' f'but got {type(init_cfg)}') model.load_state_dict(init_cfg) From afb68a0ec9720bfab5725982aded3f7dc8ff86fd Mon Sep 17 00:00:00 2001 From: zengyi <963525814@qq.com> Date: Fri, 16 Dec 2022 17:12:49 +0800 Subject: [PATCH 9/9] update registry --- mmrazor/registry/registry.py | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/mmrazor/registry/registry.py b/mmrazor/registry/registry.py index 4cb378d47..d3a5c5423 100644 --- a/mmrazor/registry/registry.py +++ b/mmrazor/registry/registry.py @@ -7,7 +7,6 @@ """ from typing import Any, Dict, Optional, Union -import torch from mmengine.config import Config, ConfigDict from mmengine.registry import DATA_SAMPLERS as MMENGINE_DATA_SAMPLERS from mmengine.registry import DATASETS as MMENGINE_DATASETS @@ -113,13 +112,16 @@ def sub_model(cfg, mode: str = 'mutable', prefix: str = '', extra_prefix: str = '', - init_weight_supernet: bool = False, + init_weight_from_supernet: bool = False, init_cfg: Optional[Dict] = None): model = MODELS.build(cfg) - # save path type cfg process, set init_cfg directly - if init_cfg and (not init_weight_supernet): - # load subnet weight when init_cfg is valid + # Save path type cfg process, set init_cfg directly. + if init_cfg: + # update init_cfg when init_cfg is valid. model.init_cfg = init_cfg + if init_weight_from_supernet: + # Supernet is modified after load_fix_subnet(), init weight here. + model.init_weights() from mmrazor.structures import load_fix_subnet load_fix_subnet( @@ -129,17 +131,8 @@ def sub_model(cfg, prefix=prefix, extra_prefix=extra_prefix) - if init_weight_supernet: - # load supernet weight via sliced state_dict - if init_cfg is None: - raise TypeError(f'`init_cfg` should be valid' - 'when `init_weight_supernet` is True' - f'but got {init_cfg}') - if 'checkpoint' in init_cfg: - init_cfg = torch.load(init_cfg['checkpoint']) - if not isinstance(init_cfg, dict): - raise TypeError('init_cfg should be a `dict`' - f'but got {type(init_cfg)}') - model.load_state_dict(init_cfg) + if init_weight_from_supernet: + # Supernet is modified after load_fix_subnet(). + model.init_cfg = None return model