MMdetection-教程5:自定义运行设置

  • Post author:
  • Post category:其他



目录


自定义优化设置


自定义pytorch支持的优化器


自定义自主实现的优化器


1.定义一个新的优化器


2.添加优化器到注册表


3.在配置文件中指定优化器


自定义优化器构造函数(optimizer constructor)


其他设置


自定义训练策略(training schedules)


自定义工作流(workflow)


自定义钩子(hooks)


定义自主实现的钩子


使用MMCV实现的钩子


修改默认的runtime钩子


自定义优化设置(optimization settings)

自定义pytorch支持的优化器

我们已经支持所有由pytorch实现的优化器,只需改变配置文件中的

optimizer

域即可。例如,如果你想使用

ADAM

(注意,性能可能会降低),做如下修改:

optimizer = dict(type='Adam', lr=0.0003, weight_decay=0.0001)

用户仅需修改优化器配置中的

lr

即可调整模型的学习率。用户可根据Python提供的

API doc

设置参数。

自定义自主实现的优化器

1.定义一个新的优化器

自定义优化器应按照如下步骤定义:

假设你想添加一个拥有参数

a



b



c

,名为

MyOptimizer

的优化器。你需要创建一个新的目录

mmdet/core/optimizer

。然后在文件中实现新的优化器,例如,在

mmdet/core/optimizer/my_optimizer.py

from .registry import OPTIMIZERS
from torch.optim import Optimizer


@OPTIMIZERS.register_module()
class MyOptimizer(Optimizer):

    def __init__(self, a, b, c)

2.添加优化器到注册表

为了能够找到上述模块,该模块应首先被导入主命名空间(main namespace)。有两种可选方式。

(1)修改

mmdet/core/optimizer/__init__.py

导入。

新定义的模块应该在

mmdet/core/optimizer/__init__.py

中被导入,以便注册表可以查询到并添加它:

from .my_optimizer import MyOptimizer

(2)在配置文件中使用

custom_imports

手动导入:

custom_imports = dict(imports=['mmdet.core.optimizer.my_optimizer'], allow_failed_imports=False)

模块

mmdet.core.optimizer.my_optimizer

将会在程序开始时被导入,并且

MyOptimizer

类会被自动注册。注意,仅有包含

MyOptimizer

类的包会被导入,

mmdet.core.optimizer.my_optimizer.MyOptimizer

不会被直接导入。

实际上用户通过这种导入方法可以使用完全不同的目录结构,只要模块的根目录能包含在

PYTHONPATH

中。

3.在配置文件中指定优化器

然后你就可以在配置文件中的

optimizer

域使用

MyOptimizer

。在这个配置文件中,优化器被

optimizer

域作如下定义:

optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)

为了使用自己的优化器,对域作如下改变:

optimizer = dict(type='MyOptimizer', a=a_value, b=b_value, c=c_value)

自定义优化器构造函数(optimizer constructor)

一些模块可能对优化器有特定的参数设置,例如BN层的权重衰减。用户可通过自定义优化器构造函数来实现参数的精细调整。

from mmcv.utils import build_from_cfg

from mmcv.runner.optimizer import OPTIMIZER_BUILDERS, OPTIMIZERS
from mmdet.utils import get_root_logger
from .my_optimizer import MyOptimizer


@OPTIMIZER_BUILDERS.register_module()
class MyOptimizerConstructor(object):

    def __init__(self, optimizer_cfg, paramwise_cfg=None):

    def __call__(self, model):

        return my_optimizer

默认的构造函数实现方法在

这里

,可以作为新的构造函数的模板。

其他设置

待更新……

自定义训练策略(training schedules)

默认情况下,我们使用逐步学习率和1x策略,这调用了MMCV中的

StepLRHook

。我们支持很多其他的学习率策略(

这里

),例如

CosineAnnealing



Poly

策略。这里给出一些例子。

Poly策略:

lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False)

ConsineAnnealing策略:

lr_config = dict(
    policy='CosineAnnealing',
    warmup='linear',
    warmup_iters=1000,
    warmup_ratio=1.0 / 10,
    min_lr_ratio=1e-5)

自定义工作流(workflow)

官网给的方法不再适用,可直接在配置文件中的evaluation域指定验证上一轮训练模型的间隔和评价指标,对于COCO格式数据集而言,默认配置如下:

evaluation = dict(interval=1, metric='bbox')

自定义钩子(hooks)

定义自主实现的钩子

1.实现一个新钩子

有时用户可能需要实现一个新的钩子。MMD从v2.3.0开始支持在训练过程中使用自定义钩子。因此用户可以直接在mmdet或者他们基于mmdet的源码中实现一个钩子,并通过修改训练的配置文件来使用它。在v2.3.0之前,用户需要在训练之前修改源码使得钩子完成注册。这里我们给出一个在mmdet中创建新钩子并在训练中使用它的例子。

from mmcv.runner import HOOKS, Hook


@HOOKS.register_module()
class MyHook(Hook):

    def __init__(self, a, b):
        pass

    def before_run(self, runner):
        pass

    def after_run(self, runner):
        pass

    def before_epoch(self, runner):
        pass

    def after_epoch(self, runner):
        pass

    def before_iter(self, runner):
        pass

    def after_iter(self, runner):
        pass

用户需要根据钩子的功能,指定其在训练过程中的每个阶段

before_run



after_run



after_epoch



before_epoch



before_iter



after_iter

的行为。

2.注册新钩子

然后我们需要导入

MyHook

。假设该文件在

mmdet/core/utils/my_hook.py

路径下,有两种实现方法:

(1)修改

mmdet/core/utils/__init__.py

来导入。

新定义的模块应该在

mmdet/core/utils/__init__.py

被导入,以便Registry可以发现并添加它:

from .my_hook import MyHook

(2)使用

custom_imports

在配置文件中手动导入:

custom_imports = dict(imports=['mmdet.core.utils.my_hook'], allow_failed_imports=False)

3.修改配置文件

custom_hooks = [
    dict(type='MyHook', a=a_value, b=b_value)
]

你也可以通过如下方法添加键

priority

等于

‘NORMAL’



‘HIGHEST’

设置钩子的优先级:

custom_hooks = [
    dict(type='MyHook', a=a_value, b=b_value, priority='NORMAL')
]

注册过程中钩子默认优先级为

NORMAL

使用MMCV实现的钩子

如果钩子在MMCV中已经实现,你可以直接修改配置文件使用钩子:

4.例子:NumClassCheckHook

我们实现了一个名为

NumClassCheckHook

的钩子来检查在头部的

num_classes

是否匹配

dataset



CLASSES

的长度。

我们将它设置在

default_runtime.py

文件中。

custom_hooks = [dict(type='NumClassCheckHook')]

修改默认的runtime钩子

以下是一些常见的钩子,它们并没有通过

custom_hooks

注册。

  • log_config

  • checkpoint_config

  • evaluation

  • lr_config

  • optimizer_config

  • momentum_config

在这些钩子中,只有logger钩子拥有

VERY_LOW

优先级,其他优先级均为

NORMAL

。上述提到的教程已经覆盖了如何修改

optimizer_config



momentum_config



lr_config

,这里我们展示

log_config



checkpoint_config



evaluation

的使用。


Checkpoint config

MMCV runner使用

checkpoint_config

初始化

CheckpointHook

checkpoint_config = dict(interval=1)

用户可以设置

max_keep_ckpts

来保存少数checkpoints文件,或者通过

save_optimizer

决定是否存储优化器的状态字典。更多参数细节参考

这里


Log config


log_config

封装了多个

logger

钩子,并且能设置间隔。现在MMCV支持

WandbLoggerHook



MlflowLoggerHook



TensorboardLoggerHook

,详细使用方法请参考

文档

log_config = dict(
    interval=50,
    hooks=[
        dict(type='TextLoggerHook'),
        dict(type='TensorboardLoggerHook')
    ])


Evaluation config


evaluation

的配置将被用于

EvalHook

的初始化。除了键

interval

,其他参数例如

metric

将会被传入

dataset.evaluate()

evaluation = dict(interval=1, metric='bbox')