From e98c6ee7d25ba5bee312cc8fafe6705d9a8219c2 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Wed, 2 Sep 2020 08:58:32 +0200 Subject: [PATCH 01/17] Add runner_type option --- mmseg/apis/train.py | 12 +++++++++--- tools/train.py | 8 +++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/mmseg/apis/train.py b/mmseg/apis/train.py index b703143587..113033ac8b 100644 --- a/mmseg/apis/train.py +++ b/mmseg/apis/train.py @@ -3,7 +3,7 @@ import numpy as np import torch from mmcv.parallel import MMDataParallel, MMDistributedDataParallel -from mmcv.runner import IterBasedRunner, build_optimizer +from mmcv.runner import EpochBasedRunner, IterBasedRunner, build_optimizer from mmseg.core import DistEvalHook, EvalHook from mmseg.datasets import build_dataloader, build_dataset @@ -35,7 +35,8 @@ def train_segmentor(model, distributed=False, validate=False, timestamp=None, - meta=None): + meta=None, + runner_type="iter"): """Launch segmentor training.""" logger = get_root_logger(cfg.log_level) @@ -70,7 +71,12 @@ def train_segmentor(model, # build runner optimizer = build_optimizer(model, cfg.optimizer) - runner = IterBasedRunner( + if runner_type == "iter": + runner_class = IterBasedRunner + else: + runner_class = EpochBasedRunner + + runner = runner_class( model=model, batch_processor=None, optimizer=optimizer, diff --git a/tools/train.py b/tools/train.py index 8e3835ae00..11d0a6c952 100644 --- a/tools/train.py +++ b/tools/train.py @@ -53,6 +53,11 @@ def parse_args(): default='none', help='job launcher') parser.add_argument('--local_rank', type=int, default=0) + parser.add_argument( + '--runner-type', + choices=['epoch', 'iter'], + default='iter', + help='Type of mmcv runner to use. EpochBased or IterBased.') args = parser.parse_args() if 'LOCAL_RANK' not in os.environ: os.environ['LOCAL_RANK'] = str(args.local_rank) @@ -154,7 +159,8 @@ def main(): distributed=distributed, validate=(not args.no_validate), timestamp=timestamp, - meta=meta) + meta=meta, + runner_type=args.runner_type) if __name__ == '__main__': From af2053a42ab3d0db58c6d1b168b930d7e9e71e3b Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Wed, 2 Sep 2020 09:15:54 +0200 Subject: [PATCH 02/17] pre-commit --- mmseg/apis/train.py | 6 +++--- tools/train.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mmseg/apis/train.py b/mmseg/apis/train.py index 113033ac8b..0d9f006aac 100644 --- a/mmseg/apis/train.py +++ b/mmseg/apis/train.py @@ -36,7 +36,7 @@ def train_segmentor(model, validate=False, timestamp=None, meta=None, - runner_type="iter"): + runner_type='iter'): """Launch segmentor training.""" logger = get_root_logger(cfg.log_level) @@ -71,8 +71,8 @@ def train_segmentor(model, # build runner optimizer = build_optimizer(model, cfg.optimizer) - if runner_type == "iter": - runner_class = IterBasedRunner + if runner_type == 'iter': + runner_class = IterBasedRunner else: runner_class = EpochBasedRunner diff --git a/tools/train.py b/tools/train.py index 11d0a6c952..e650cc4c23 100644 --- a/tools/train.py +++ b/tools/train.py @@ -57,7 +57,7 @@ def parse_args(): '--runner-type', choices=['epoch', 'iter'], default='iter', - help='Type of mmcv runner to use. EpochBased or IterBased.') + help='Type of mmcv runner to use. EpochBased or IterBased.') args = parser.parse_args() if 'LOCAL_RANK' not in os.environ: os.environ['LOCAL_RANK'] = str(args.local_rank) From 47958a62b3569f48fd413674af10b1bf05bccc81 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Wed, 2 Sep 2020 09:45:56 +0200 Subject: [PATCH 03/17] Fix max_iters --- mmseg/apis/train.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mmseg/apis/train.py b/mmseg/apis/train.py index 0d9f006aac..19f9d747f4 100644 --- a/mmseg/apis/train.py +++ b/mmseg/apis/train.py @@ -73,8 +73,10 @@ def train_segmentor(model, if runner_type == 'iter': runner_class = IterBasedRunner + max_iters = cfg.total_iters else: runner_class = EpochBasedRunner + max_iters = cfg.total_epochs runner = runner_class( model=model, @@ -109,4 +111,4 @@ def train_segmentor(model, runner.resume(cfg.resume_from) elif cfg.load_from: runner.load_checkpoint(cfg.load_from) - runner.run(data_loaders, cfg.workflow, cfg.total_iters) + runner.run(data_loaders, cfg.workflow, max_iters) From e51c601d733329c75cc554ad371754d8d7ca2acb Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Wed, 2 Sep 2020 12:41:01 +0200 Subject: [PATCH 04/17] Add by_epoch to EvalHook --- mmseg/apis/train.py | 1 + mmseg/core/evaluation/eval_hooks.py | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/mmseg/apis/train.py b/mmseg/apis/train.py index 19f9d747f4..093b355970 100644 --- a/mmseg/apis/train.py +++ b/mmseg/apis/train.py @@ -104,6 +104,7 @@ def train_segmentor(model, dist=distributed, shuffle=False) eval_cfg = cfg.get('evaluation', {}) + eval_cfg['by_epoch'] = runner_type != 'iter' eval_hook = DistEvalHook if distributed else EvalHook runner.register_hook(eval_hook(val_dataloader, **eval_cfg)) diff --git a/mmseg/core/evaluation/eval_hooks.py b/mmseg/core/evaluation/eval_hooks.py index cbd0b23fe9..c6c9eefb3f 100644 --- a/mmseg/core/evaluation/eval_hooks.py +++ b/mmseg/core/evaluation/eval_hooks.py @@ -12,17 +12,27 @@ class EvalHook(Hook): interval (int): Evaluation interval (by epochs). Default: 1. """ - def __init__(self, dataloader, interval=1, **eval_kwargs): + def __init__(self, dataloader, interval=1, by_epoch=False, **eval_kwargs): if not isinstance(dataloader, DataLoader): raise TypeError('dataloader must be a pytorch DataLoader, but got ' f'{type(dataloader)}') self.dataloader = dataloader self.interval = interval + self.by_epoch = by_epoch self.eval_kwargs = eval_kwargs def after_train_iter(self, runner): """After train epoch hook.""" - if not self.every_n_iters(runner, self.interval): + if self.by_epoch or not self.every_n_iters(runner, self.interval): + return + from mmseg.apis import single_gpu_test + runner.log_buffer.clear() + results = single_gpu_test(runner.model, self.dataloader, show=False) + self.evaluate(runner, results) + + def after_train_epoch(self, runner): + """After train epoch hook.""" + if not self.by_epoch: return from mmseg.apis import single_gpu_test runner.log_buffer.clear() From 160c5b7833e46f44826eef6fb4e5fd2a2521112f Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Wed, 9 Sep 2020 20:05:48 +0200 Subject: [PATCH 05/17] Add test_eval_hook for epoch runner --- tests/test_eval_hook.py | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/tests/test_eval_hook.py b/tests/test_eval_hook.py index 84542ecfe3..eb44e996ed 100644 --- a/tests/test_eval_hook.py +++ b/tests/test_eval_hook.py @@ -38,7 +38,7 @@ def train_step(self, data_batch, optimizer): return dict(loss=loss) -def test_eval_hook(): +def test_iter_eval_hook(): with pytest.raises(TypeError): test_dataset = ExampleModel() data_loader = [ @@ -75,6 +75,43 @@ def test_eval_hook(): logger=runner.logger) +def test_epoch_eval_hook(): + with pytest.raises(TypeError): + test_dataset = ExampleModel() + data_loader = [ + DataLoader( + test_dataset, + batch_size=1, + sampler=None, + num_worker=0, + shuffle=False) + ] + EvalHook(data_loader, by_epoch=True) + + test_dataset = ExampleDataset() + test_dataset.evaluate = MagicMock(return_value=dict(test='success')) + loader = DataLoader(test_dataset, batch_size=1) + model = ExampleModel() + data_loader = DataLoader( + test_dataset, batch_size=1, sampler=None, num_workers=0, shuffle=False) + optim_cfg = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005) + optimizer = obj_from_dict(optim_cfg, torch.optim, + dict(params=model.parameters())) + + # test EvalHook + with tempfile.TemporaryDirectory() as tmpdir: + eval_hook = EvalHook(data_loader) + runner = mmcv.runner.EpochBasedRunner( + model=model, + optimizer=optimizer, + work_dir=tmpdir, + logger=logging.getLogger()) + runner.register_hook(eval_hook) + runner.run([loader], [('train', 1)], 1) + test_dataset.evaluate.assert_called_with([torch.tensor([1])], + logger=runner.logger) + + def multi_gpu_test(model, data_loader, tmpdir=None, gpu_collect=False): results = single_gpu_test(model, data_loader) return results From a2509aa9b777768dbec9eae9cbb184c8bd6b36d4 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Mon, 28 Sep 2020 18:53:05 +0200 Subject: [PATCH 06/17] Remove runner-type arg from tools/train --- tools/train.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tools/train.py b/tools/train.py index e650cc4c23..8e3835ae00 100644 --- a/tools/train.py +++ b/tools/train.py @@ -53,11 +53,6 @@ def parse_args(): default='none', help='job launcher') parser.add_argument('--local_rank', type=int, default=0) - parser.add_argument( - '--runner-type', - choices=['epoch', 'iter'], - default='iter', - help='Type of mmcv runner to use. EpochBased or IterBased.') args = parser.parse_args() if 'LOCAL_RANK' not in os.environ: os.environ['LOCAL_RANK'] = str(args.local_rank) @@ -159,8 +154,7 @@ def main(): distributed=distributed, validate=(not args.no_validate), timestamp=timestamp, - meta=meta, - runner_type=args.runner_type) + meta=meta) if __name__ == '__main__': From cee1946b1fb846962520564a4e3e2f821ea1c111 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Mon, 28 Sep 2020 18:54:36 +0200 Subject: [PATCH 07/17] Add missing every_n_iters check for epoch mode --- mmseg/core/evaluation/eval_hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmseg/core/evaluation/eval_hooks.py b/mmseg/core/evaluation/eval_hooks.py index c6c9eefb3f..0a2111fb2b 100644 --- a/mmseg/core/evaluation/eval_hooks.py +++ b/mmseg/core/evaluation/eval_hooks.py @@ -32,7 +32,7 @@ def after_train_iter(self, runner): def after_train_epoch(self, runner): """After train epoch hook.""" - if not self.by_epoch: + if not self.by_epoch or not self.every_n_iters(runner, self.interval): return from mmseg.apis import single_gpu_test runner.log_buffer.clear() From 42467f391de59581fcdc2bff40ea68637ee67c3a Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Mon, 28 Sep 2020 18:58:39 +0200 Subject: [PATCH 08/17] Bump mmcv min version --- mmseg/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmseg/__init__.py b/mmseg/__init__.py index 20bce069a1..ffc848a934 100644 --- a/mmseg/__init__.py +++ b/mmseg/__init__.py @@ -2,7 +2,7 @@ from .version import __version__, version_info -MMCV_MIN = '1.1.2' +MMCV_MIN = '1.1.4' MMCV_MAX = '1.2.0' From cbdf4050983d8dd92436a726b0d4772767e37592 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Mon, 28 Sep 2020 19:11:40 +0200 Subject: [PATCH 09/17] Use build_runner --- configs/_base_/schedules/schedule_160k.py | 2 +- configs/_base_/schedules/schedule_20k.py | 2 +- configs/_base_/schedules/schedule_40k.py | 2 +- configs/_base_/schedules/schedule_80k.py | 2 +- mmseg/apis/train.py | 32 +++++++++-------------- 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/configs/_base_/schedules/schedule_160k.py b/configs/_base_/schedules/schedule_160k.py index 8fe4b04d22..52603890b1 100644 --- a/configs/_base_/schedules/schedule_160k.py +++ b/configs/_base_/schedules/schedule_160k.py @@ -4,6 +4,6 @@ # learning policy lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False) # runtime settings -total_iters = 160000 +runner = dict(type='IterBasedRunner', max_iters=160000) checkpoint_config = dict(by_epoch=False, interval=16000) evaluation = dict(interval=16000, metric='mIoU') diff --git a/configs/_base_/schedules/schedule_20k.py b/configs/_base_/schedules/schedule_20k.py index d3903d6452..bf780a1b6f 100644 --- a/configs/_base_/schedules/schedule_20k.py +++ b/configs/_base_/schedules/schedule_20k.py @@ -4,6 +4,6 @@ # learning policy lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False) # runtime settings -total_iters = 20000 +runner = dict(type='IterBasedRunner', max_iters=20000) checkpoint_config = dict(by_epoch=False, interval=2000) evaluation = dict(interval=2000, metric='mIoU') diff --git a/configs/_base_/schedules/schedule_40k.py b/configs/_base_/schedules/schedule_40k.py index b1449219cb..cdbf841abc 100644 --- a/configs/_base_/schedules/schedule_40k.py +++ b/configs/_base_/schedules/schedule_40k.py @@ -4,6 +4,6 @@ # learning policy lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False) # runtime settings -total_iters = 40000 +runner = dict(type='IterBasedRunner', max_iters=40000) checkpoint_config = dict(by_epoch=False, interval=4000) evaluation = dict(interval=4000, metric='mIoU') diff --git a/configs/_base_/schedules/schedule_80k.py b/configs/_base_/schedules/schedule_80k.py index 3a77b41d45..c190cee6bd 100644 --- a/configs/_base_/schedules/schedule_80k.py +++ b/configs/_base_/schedules/schedule_80k.py @@ -4,6 +4,6 @@ # learning policy lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False) # runtime settings -total_iters = 80000 +runner = dict(type='IterBasedRunner', max_iters=80000) checkpoint_config = dict(by_epoch=False, interval=8000) evaluation = dict(interval=8000, metric='mIoU') diff --git a/mmseg/apis/train.py b/mmseg/apis/train.py index 093b355970..194653d13e 100644 --- a/mmseg/apis/train.py +++ b/mmseg/apis/train.py @@ -3,7 +3,7 @@ import numpy as np import torch from mmcv.parallel import MMDataParallel, MMDistributedDataParallel -from mmcv.runner import EpochBasedRunner, IterBasedRunner, build_optimizer +from mmcv.runner import build_optimizer, build_runner from mmseg.core import DistEvalHook, EvalHook from mmseg.datasets import build_dataloader, build_dataset @@ -35,8 +35,7 @@ def train_segmentor(model, distributed=False, validate=False, timestamp=None, - meta=None, - runner_type='iter'): + meta=None): """Launch segmentor training.""" logger = get_root_logger(cfg.log_level) @@ -71,20 +70,15 @@ def train_segmentor(model, # build runner optimizer = build_optimizer(model, cfg.optimizer) - if runner_type == 'iter': - runner_class = IterBasedRunner - max_iters = cfg.total_iters - else: - runner_class = EpochBasedRunner - max_iters = cfg.total_epochs - - runner = runner_class( - model=model, - batch_processor=None, - optimizer=optimizer, - work_dir=cfg.work_dir, - logger=logger, - meta=meta) + runner = build_runner( + cfg.runner, + default_args=dict( + model=model, + batch_processor=None, + optimizer=optimizer, + work_dir=cfg.work_dir, + logger=logger, + meta=meta)) # register hooks runner.register_training_hooks(cfg.lr_config, cfg.optimizer_config, @@ -104,7 +98,7 @@ def train_segmentor(model, dist=distributed, shuffle=False) eval_cfg = cfg.get('evaluation', {}) - eval_cfg['by_epoch'] = runner_type != 'iter' + eval_cfg['by_epoch'] = cfg.runner['type'] != 'IterBasedRunner' eval_hook = DistEvalHook if distributed else EvalHook runner.register_hook(eval_hook(val_dataloader, **eval_cfg)) @@ -112,4 +106,4 @@ def train_segmentor(model, runner.resume(cfg.resume_from) elif cfg.load_from: runner.load_checkpoint(cfg.load_from) - runner.run(data_loaders, cfg.workflow, max_iters) + runner.run(data_loaders, cfg.workflow) From e8fbd0d4e4df0158abc328c2afa45bd48b3df617 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Mon, 28 Sep 2020 19:44:56 +0200 Subject: [PATCH 10/17] Use interval in tests --- tests/test_eval_hook.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_eval_hook.py b/tests/test_eval_hook.py index eb44e996ed..7a6e186cd3 100644 --- a/tests/test_eval_hook.py +++ b/tests/test_eval_hook.py @@ -100,16 +100,16 @@ def test_epoch_eval_hook(): # test EvalHook with tempfile.TemporaryDirectory() as tmpdir: - eval_hook = EvalHook(data_loader) + eval_hook = EvalHook(data_loader, by_epoch=True, interval=2) runner = mmcv.runner.EpochBasedRunner( model=model, optimizer=optimizer, work_dir=tmpdir, logger=logging.getLogger()) runner.register_hook(eval_hook) - runner.run([loader], [('train', 1)], 1) - test_dataset.evaluate.assert_called_with([torch.tensor([1])], - logger=runner.logger) + runner.run([loader], [('train', 1)], 2) + test_dataset.evaluate.assert_called_once_with([torch.tensor([1])], + logger=runner.logger) def multi_gpu_test(model, data_loader, tmpdir=None, gpu_collect=False): From 6af278f424168b982d9745a434179d800729ae57 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Tue, 29 Sep 2020 07:59:46 +0200 Subject: [PATCH 11/17] Update test_eval_hook.py --- tests/test_eval_hook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_eval_hook.py b/tests/test_eval_hook.py index 7a6e186cd3..af1fdc4e47 100644 --- a/tests/test_eval_hook.py +++ b/tests/test_eval_hook.py @@ -98,7 +98,7 @@ def test_epoch_eval_hook(): optimizer = obj_from_dict(optim_cfg, torch.optim, dict(params=model.parameters())) - # test EvalHook + # test EvalHook with interval with tempfile.TemporaryDirectory() as tmpdir: eval_hook = EvalHook(data_loader, by_epoch=True, interval=2) runner = mmcv.runner.EpochBasedRunner( From f9ca157a23b73038de7531f8a926bd2a7118a9f1 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Tue, 29 Sep 2020 08:31:24 +0200 Subject: [PATCH 12/17] Use every_n_epochs instead of every_n_iters. Update DistEvalHook --- mmseg/core/evaluation/eval_hooks.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/mmseg/core/evaluation/eval_hooks.py b/mmseg/core/evaluation/eval_hooks.py index 0a2111fb2b..0e8a76acae 100644 --- a/mmseg/core/evaluation/eval_hooks.py +++ b/mmseg/core/evaluation/eval_hooks.py @@ -32,7 +32,7 @@ def after_train_iter(self, runner): def after_train_epoch(self, runner): """After train epoch hook.""" - if not self.by_epoch or not self.every_n_iters(runner, self.interval): + if not self.by_epoch or not self.every_n_epochs(runner, self.interval): return from mmseg.apis import single_gpu_test runner.log_buffer.clear() @@ -76,7 +76,22 @@ def __init__(self, def after_train_iter(self, runner): """After train epoch hook.""" - if not self.every_n_iters(runner, self.interval): + if self.by_epoch or not self.every_n_iters(runner, self.interval): + return + from mmseg.apis import multi_gpu_test + runner.log_buffer.clear() + results = multi_gpu_test( + runner.model, + self.dataloader, + tmpdir=osp.join(runner.work_dir, '.eval_hook'), + gpu_collect=self.gpu_collect) + if runner.rank == 0: + print('\n') + self.evaluate(runner, results) + + def after_train_epoch(self, runner): + """After train epoch hook.""" + if not self.by_epoch or not self.every_n_epochs(runner, self.interval): return from mmseg.apis import multi_gpu_test runner.log_buffer.clear() From a050edb8c99dbba8c07c0c4239cabd8eb5c374b2 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Tue, 29 Sep 2020 08:33:31 +0200 Subject: [PATCH 13/17] Add test_dist_eval_hook_epoch --- tests/test_eval_hook.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/test_eval_hook.py b/tests/test_eval_hook.py index af1fdc4e47..a6a1352ea5 100644 --- a/tests/test_eval_hook.py +++ b/tests/test_eval_hook.py @@ -153,3 +153,41 @@ def test_dist_eval_hook(): runner.run([loader], [('train', 1)], 1) test_dataset.evaluate.assert_called_with([torch.tensor([1])], logger=runner.logger) + + +@patch('mmseg.apis.multi_gpu_test', multi_gpu_test) +def test_dist_eval_hook_epoch(): + with pytest.raises(TypeError): + test_dataset = ExampleModel() + data_loader = [ + DataLoader( + test_dataset, + batch_size=1, + sampler=None, + num_worker=0, + shuffle=False) + ] + DistEvalHook(data_loader) + + test_dataset = ExampleDataset() + test_dataset.evaluate = MagicMock(return_value=dict(test='success')) + loader = DataLoader(test_dataset, batch_size=1) + model = ExampleModel() + data_loader = DataLoader( + test_dataset, batch_size=1, sampler=None, num_workers=0, shuffle=False) + optim_cfg = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005) + optimizer = obj_from_dict(optim_cfg, torch.optim, + dict(params=model.parameters())) + + # test DistEvalHook + with tempfile.TemporaryDirectory() as tmpdir: + eval_hook = DistEvalHook(data_loader, by_epoch=True, interval=2) + runner = mmcv.runner.EpochBasedRunner( + model=model, + optimizer=optimizer, + work_dir=tmpdir, + logger=logging.getLogger()) + runner.register_hook(eval_hook) + runner.run([loader], [('train', 1)], 2) + test_dataset.evaluate.assert_called_with([torch.tensor([1])], + logger=runner.logger) From c18bbf6207a30701f4b20e9489f9bd20e27a3f4f Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Tue, 29 Sep 2020 08:35:16 +0200 Subject: [PATCH 14/17] Fix tests --- mmseg/core/evaluation/eval_hooks.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mmseg/core/evaluation/eval_hooks.py b/mmseg/core/evaluation/eval_hooks.py index 0e8a76acae..09c6265ece 100644 --- a/mmseg/core/evaluation/eval_hooks.py +++ b/mmseg/core/evaluation/eval_hooks.py @@ -64,6 +64,7 @@ def __init__(self, dataloader, interval=1, gpu_collect=False, + by_epoch=False, **eval_kwargs): if not isinstance(dataloader, DataLoader): raise TypeError( @@ -72,6 +73,7 @@ def __init__(self, self.dataloader = dataloader self.interval = interval self.gpu_collect = gpu_collect + self.by_epoch = by_epoch self.eval_kwargs = eval_kwargs def after_train_iter(self, runner): From 73cd9ced41eaf6fa09881066a1478cb84c9e78d7 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Tue, 29 Sep 2020 15:59:28 +0200 Subject: [PATCH 15/17] Add DeprecationWarning --- mmseg/apis/train.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mmseg/apis/train.py b/mmseg/apis/train.py index 194653d13e..37b0e5a839 100644 --- a/mmseg/apis/train.py +++ b/mmseg/apis/train.py @@ -1,4 +1,5 @@ import random +import warnings import numpy as np import torch @@ -70,6 +71,12 @@ def train_segmentor(model, # build runner optimizer = build_optimizer(model, cfg.optimizer) + if cfg.get('runner') is None: + cfg.runner = {'type': 'IterBasedRunner', 'max_iters': cfg.total_iters} + warnings.warn( + 'config is now expected to have a `runner` section, ' + 'please set `runner` in your config.', DeprecationWarning) + runner = build_runner( cfg.runner, default_args=dict( From 8076f4a675dc86522c30fb67d4096705f66e7b56 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Tue, 29 Sep 2020 16:05:55 +0200 Subject: [PATCH 16/17] Update docs --- docs/config.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/config.md b/docs/config.md index be9226a60d..82dada1963 100644 --- a/docs/config.md +++ b/docs/config.md @@ -225,7 +225,7 @@ dist_params = dict(backend='nccl') # Parameters to setup distributed training, log_level = 'INFO' # The level of logging. load_from = None # load models as a pre-trained model from a given path. This will not resume training. resume_from = None # Resume checkpoints from a given path, the training will be resumed from the iteration when the checkpoint's is saved. -workflow = [('train', 1)] # Workflow for runner. [('train', 1)] means there is only one workflow and the workflow named 'train' is executed once. The workflow trains the model by 40000 iterations according to the total_iters. +workflow = [('train', 1)] # Workflow for runner. [('train', 1)] means there is only one workflow and the workflow named 'train' is executed once. The workflow trains the model by 40000 iterations according to the `runner.max_iters`. cudnn_benchmark = True # Whether use cudnn_benchmark to speed up, which is fast for fixed input size. optimizer = dict( # Config used to build optimizer, support all the optimizers in PyTorch whose arguments are also the same as those in PyTorch type='SGD', # Type of optimizers, refer to https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/optimizer/default_constructor.py#L13 for more details @@ -238,7 +238,9 @@ lr_config = dict( power=0.9, # The power of polynomial decay. min_lr=0.0001, # The minimum learning rate to stable the training. by_epoch=False) # Whethe count by epoch or not. -total_iters = 40000 # Total number of iterations. +runner = dict( + type='IterBasedRunner', # Type of runner to use (i.e. IterBasedRunner or EpochBasedRunner) + max_iters=40000) # Total number of iterations. For EpochBasedRunner use `max_epochs` checkpoint_config = dict( # Config to set the checkpoint hook, Refer to https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/checkpoint.py for implementation. by_epoch=False, # Whethe count by epoch or not. interval=4000) # The save interval. From 65a53e4e79f38b129906ad35846f581bb1ca9563 Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Tue, 13 Oct 2020 13:21:04 +0200 Subject: [PATCH 17/17] Replace DeprecationWarning with UserWarning --- mmseg/apis/train.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmseg/apis/train.py b/mmseg/apis/train.py index 37b0e5a839..5f526df2b0 100644 --- a/mmseg/apis/train.py +++ b/mmseg/apis/train.py @@ -75,7 +75,7 @@ def train_segmentor(model, cfg.runner = {'type': 'IterBasedRunner', 'max_iters': cfg.total_iters} warnings.warn( 'config is now expected to have a `runner` section, ' - 'please set `runner` in your config.', DeprecationWarning) + 'please set `runner` in your config.', UserWarning) runner = build_runner( cfg.runner,