目录
自定义优化器构造函数(optimizer constructor)
自定义优化设置(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')