mmsegment训练技巧(九)

目录

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、评估配置


1、训练技巧

1.1、Backbone和Heads不同学习率

在语义分割中,一些方法使头部Heads的LR大于主干的LR,以实现更好的性能或更快的收敛。

在MMSegmentation中,在配置中添加以下行,可以使头部的LR达到主干的10倍。

optimizer=dict(
    paramwise_cfg = dict(
        custom_keys={
            'head': dict(lr_mult=10.)}))

通过此修改,'head'里面的任何参数组的LR都将乘以10。有关更多详细信息,请参考MMCV doc。

1.2、在线难样本挖掘(OHEM)

我们在这里实现像素采样器用于训练采样。这是在启用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则将选择最大损失像素。

1.3、类平衡损失

对于类别分布不平衡的数据集,可以更改每个类别的损失权重。这是城市景观数据集的示例。

_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。

2、自定义优化设置

2.1、Pytorch支持的自定义优化器

已经支持使用由PyTorch实现的所有优化器,唯一的修改就是更改optimizer配置文件的字段。例如,如果要使用ADAM(请注意性能可能会下降很多),则修改可以如下。

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

要修改模型的学习率,用户只需lr在优化器的配置中进行修改即可。用户可以按照PyTorch的API文档直接设置参数。

2.2、定制优化器

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以导入它。

应该将新定义的模块导入其中,mmseg/core/optimizer/__init__.py以便注册表可以找到新模块并将其添加:

from .my_optimizer import MyOptimizer
  • custom_imports在配置中使用以手动导入它
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。

2.3、在配置文件中指定优化器

然后,您可以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)

2.4、自定义优化器构造函数

某些模型可能具有一些特定于参数的设置以进行优化,例如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

默认的优化器构造函数在此处实现,它也可以用作新的优化器构造函数的模板。

2.5、其他设置

未通过优化器实现的技巧应通过优化器构造函数(例如,设置按参数的学习率)或钩子过程来实现。我们列出了一些可以稳定训练或加速训练的常用设置。随意创建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,
)

3、定制训练计划

默认情况下,我们在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)

4、自定义钩子过程

4.1、使用MMCV中实现的挂钩

如果该挂钩已在MMCV中实现,则可以直接修改配置以使用该挂钩,如下所示

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

4.2、修改默认的运行时挂钩

有一些未通过注册的常见钩子custom_hooks,它们是:

  • log_config
  • checkpoint_config
  • evaluation
  • lr_config
  • optimizer_config
  • momentum_config

在这些挂钩中,只有记录器挂钩具有VERY_LOW优先级,其他挂钩具有NORMAL。上述教程已经涵盖了如何修改optimizer_config,momentum_config和lr_config。在这里,我们揭示了如何我们可以做的log_config,checkpoint_config和evaluation。

4.3、检查点配置

MMCV运行程序将用于checkpoint_config初始化CheckpointHook。

checkpoint_config = dict(interval=1)

用户可以设置max_keep_ckpts为仅保存少量检查点,或者通过决定是否存储优化器的状态字典save_optimizer。参数的更多详细信息在这里

4.4、日志配置

该log_config包装的多个记录器的钩和能够设定的时间间隔。现在MMCV支持WandbLoggerHook,MlflowLoggerHook和TensorboardLoggerHook。详细用法可以在doc中找到。

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

4.5、评估配置

配置evaluation将用于初始化EvalHook。除键外interval,其他参数(例如)metric将传递给dataset.evaluate()

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

 

你可能感兴趣的:(mmsegment,深度学习,pytorch)