打算在挖某个模型的代码的时候讲模型配置。首先说一下运行时一些优化器的配置:
mmdetection支持pytorch已经实现的一些优化器 adam和sgd等,我们可以在配置文件中这么定义:
optimizer = dict(type=‘Adam’, lr=0.0003, weight_decay=0.0001)
也可以自己去定义新的优化器,这个操作在mmdet3d/core/optimizer目录中,新建一个mmdet3d/core/optimizer/my_optimizer.py:
from mmcv.runner.optimizer import OPTIMIZERS
from torch.optim import Optimizer
@OPTIMIZERS.register_module()
class MyOptimizer(Optimizer):
def __init__(self, a, b, c)
然后将新建的优化器添加到register中:
新建 mmdet3d/core/optimizer/init.py 文件用于引入。
新定义的模块应该在 mmdet3d/core/optimizer/init.py 中被引入,使得注册器可以找到新模块并注册之:
from .my_optimizer import MyOptimizer
__all__ = ['MyOptimizer']
您也需要通过添加如下语句在 mmdet3d/core/init.py 中引入 optimizer:
from .optimizer import *
然后我们可以在配置文件中指定优化器:
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
or
optimizer = dict(type='MyOptimizer', a=a_value, b=b_value, c=c_value)
部分模型可能会拥有一些参数专属的优化器设置,比如 BatchNorm 层的权重衰减 (weight decay)。 用户可以通过自定义优化器的构造器来对那些细粒度的参数进行调优。
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
配置文件中的一些额外设置:
没有在优化器部分实现的技巧应该通过优化器构造器或者钩子来实现 (比如逐参数的学习率设置)。我们列举了一些常用的可以稳定训练过程或者加速训练的设置。我们欢迎提供更多类似设置的 PR 和 issue。
使用梯度裁剪 (gradient clip) 来稳定训练过程:
optimizer_config = dict(
_delete_=True, grad_clip=dict(max_norm=35, norm_type=2))**
使用动量规划器 (momentum scheduler) 来加速模型收敛:
lr_config = dict(
policy='cyclic',
target_ratio=(10, 1e-4),
cyclic_times=1,
step_ratio_up=0.4,
)
momentum_config = dict(
policy='cyclic',
target_ratio=(0.85 / 0.95, 1),
cyclic_times=1,
step_ratio_up=0.4,
)
学习率退火程序:
多项式衰减过程:
lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False)
余弦退火程序:
lr_config = dict(
policy='CosineAnnealing',
warmup='linear',
warmup_iters=1000,
warmup_ratio=1.0 / 10,
min_lr_ratio=1e-5)
Workflow:
工作流是一个(阶段,epoch 数)的列表,用于指定不同阶段运行顺序和运行的 epoch 数。 默认情况它被设置为:
workflow = [('train', 1)]
这意味着,工作流包括训练 1 个 epoch。 有时候用户可能想要检查一些模型在验证集上的评估指标(比如损失、准确率)。 在这种情况中,我们可以将工作流设置如下:
[('train', 1), ('val', 1)]
这样,就是交替地运行 1 个 epoch 进行训练,1 个 epoch 进行验证。
模型参数在验证期间不会更新。
配置文件中,runner 里的 max_epochs 字段只控制训练 epoch 的数量,而不会影响验证工作流。
[(‘train’, 1), (‘val’, 1)] 和 [(‘train’, 1)] 工作流不会改变 EvalHook 的行为,这是因为 EvalHook 被 after_train_epoch 调用,且验证工作流只会影响通过 after_val_epoch 调用的钩子。因此,[(‘train’, 1), (‘val’, 1)] 和 [(‘train’, 1)] 的唯一区别就是执行器 (runner) 会在每个训练 epoch 之后在验证集上计算损失。
文章出处登录后可见!