目录
1、训练技巧
1.1、Backbone和Heads不同学习率
1.2、在线难样本挖掘(OHEM)
1.3、类平衡损失
2、自定义优化设置
2.1、Pytorch支持的自定义优化器
2.2、定制优化器
2.3、在配置文件中指定优化器
2.4、自定义优化器构造函数
2.5、其他设置
3、定制训练计划
4、自定义钩子过程
4.1、使用MMCV中实现的挂钩
4.2、修改默认的运行时挂钩
4.3、检查点配置
4.4、日志配置
4.5、评估配置
在语义分割中,一些方法使头部Heads的LR大于主干的LR,以实现更好的性能或更快的收敛。
在MMSegmentation中,在配置中添加以下行,可以使头部的LR达到主干的10倍。
optimizer=dict(
paramwise_cfg = dict(
custom_keys={
'head': dict(lr_mult=10.)}))
通过此修改,'head'里面的任何参数组的LR都将乘以10。有关更多详细信息,请参考MMCV doc。
我们在这里实现像素采样器用于训练采样。这是在启用OHEM的情况下训练PSPNet的示例配置。
_base_ = './pspnet_r50-d8_512x1024_40k_cityscapes.py'
model=dict(
decode_head=dict(
sampler=dict(type='OHEMPixelSampler', thresh=0.7, min_kept=100000)) )
这样,仅使用置信度得分低于0.7的像素进行训练。而且我们在训练期间至少保留100000像素。如果thresh未指定,min_kept则将选择最大损失像素。
对于类别分布不平衡的数据集,可以更改每个类别的损失权重。这是城市景观数据集的示例。
_base_ = './pspnet_r50-d8_512x1024_40k_cityscapes.py'
model=dict(
decode_head=dict(
loss_decode=dict(
type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0,
# DeepLab used this class weight for cityscapes
class_weight=[0.8373, 0.9180, 0.8660, 1.0345, 1.0166, 0.9969, 0.9754,
1.0489, 0.8786, 1.0023, 0.9539, 0.9843, 1.1116, 0.9037,
1.0865, 1.0955, 1.0865, 1.1529, 1.0507])))
class_weight将CrossEntropyLoss作为weight参数传递。有关详细信息,请参阅PyTorch Doc。
已经支持使用由PyTorch实现的所有优化器,唯一的修改就是更改optimizer配置文件的字段。例如,如果要使用ADAM(请注意性能可能会下降很多),则修改可以如下。
optimizer = dict(type='Adam', lr=0.0003, weight_decay=0.0001)
要修改模型的学习率,用户只需lr在优化器的配置中进行修改即可。用户可以按照PyTorch的API文档直接设置参数。
1)定义一个新的优化器
假设想添加一个名为优化MyOptimizer,其中有参数a,b和c。需要创建一个名为的新目录mmseg/core/optimizer。然后在文件中实现新的优化器,例如,在mmseg/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):
pass
2)将优化器添加到注册表
要找到上面定义的上述模块,首先应将此模块导入主命名空间。有两种选择可以实现它。
应该将新定义的模块导入其中,mmseg/core/optimizer/__init__.py以便注册表可以找到新模块并将其添加:
from .my_optimizer import MyOptimizer
custom_imports = dict(
imports=['mmseg.core.optimizer.my_optimizer'],
allow_failed_imports=False
)
该模块mmseg.core.optimizer.my_optimizer将在程序开始时导入,MyOptimizer然后自动注册该类。请注意,仅MyOptimizer应导入包含该类的包。 mmseg.core.optimizer.my_optimizer.MyOptimizer 无法直接导入。
实际上,只要模块根目录可以位于中,用户就可以使用这种导入方法使用完全不同的文件目录结构PYTHONPATH。
然后,您可以MyOptimizer在optimizer配置文件的字段中使用。在配置中,优化器由字段定义,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)
某些模型可能具有一些特定于参数的设置以进行优化,例如BatchNorm层的重量衰减。用户可以通过自定义优化器构造函数来进行那些细粒度的参数调整。
from mmcv.utils import build_from_cfg
from mmcv.runner.optimizer import OPTIMIZER_BUILDERS, OPTIMIZERS
from mmseg.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):
pass
def __call__(self, model):
return my_optimizer
默认的优化器构造函数在此处实现,它也可以用作新的优化器构造函数的模板。
未通过优化器实现的技巧应通过优化器构造函数(例如,设置按参数的学习率)或钩子过程来实现。我们列出了一些可以稳定训练或加速训练的常用设置。随意创建PR,发布更多设置。
1)使用梯度剪裁来稳定训练:某些模型需要梯度剪裁来剪辑梯度以稳定训练过程。一个例子如下:
optimizer_config = dict(
_delete_=True,
grad_clip=dict(max_norm=35, norm_type=2)
)
如果您的配置继承了已经设置的基本配置optimizer_config,则可能需要_delete_=True覆盖不必要的设置。有关更多详细信息,请参见配置文档。
2)使用动量计划表来加速模型收敛:我们支持动量计划表根据学习率修改模型的动量,从而可以更快地收敛模型。动量调度程序通常与LR调度程序一起使用,例如,在3D检测中使用以下配置来加速收敛。有关更多详细信息,请参考CyclicLrUpdater和CyclicMomentumUpdater的实现。
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,
)
默认情况下,我们在40k / 80k计划中使用计划表控制学习率,这在MMCV中称为PolyLrUpdaterHook。我们在这里支持其他许多学习率计划,例如CosineAnnealing和Poly计划。这里有些例子:
1)Step schedule:
lr_config = dict(policy='step', step=[9, 10])
2)ConsineAnnealing schedule:
lr_config = dict(
policy='CosineAnnealing',
warmup='linear',
warmup_iters=1000,
warmup_ratio=1.0 / 10,
min_lr_ratio=1e-5)
如果该挂钩已在MMCV中实现,则可以直接修改配置以使用该挂钩,如下所示
custom_hooks = [
dict(type='MyHook', a=a_value, b=b_value, priority='NORMAL')
]
有一些未通过注册的常见钩子custom_hooks,它们是:
在这些挂钩中,只有记录器挂钩具有VERY_LOW优先级,其他挂钩具有NORMAL。上述教程已经涵盖了如何修改optimizer_config,momentum_config和lr_config。在这里,我们揭示了如何我们可以做的log_config,checkpoint_config和evaluation。
MMCV运行程序将用于checkpoint_config初始化CheckpointHook。
checkpoint_config = dict(interval=1)
用户可以设置max_keep_ckpts为仅保存少量检查点,或者通过决定是否存储优化器的状态字典save_optimizer。参数的更多详细信息在这里
该log_config包装的多个记录器的钩和能够设定的时间间隔。现在MMCV支持WandbLoggerHook,MlflowLoggerHook和TensorboardLoggerHook。详细用法可以在doc中找到。
log_config = dict(
interval=50,
hooks=[
dict(type='TextLoggerHook'),
dict(type='TensorboardLoggerHook')
])
配置evaluation将用于初始化EvalHook。除键外interval,其他参数(例如)metric将传递给dataset.evaluate()
evaluation = dict(interval=1, metric='mIoU')