权重初始化¶
在训练过程中,合适的初始化策略有助于加快训练速度或获得更高的性能。 MMCV 提供了一些常用的方法来初始化模块,例如 nn.Conv2d
。 MMdetection 中的模型初始化主要使用 init_cfg
。 用户可以通过以下两个步骤来初始化模型
在
model_cfg
中为模型或其组件定义init_cfg
,但子组件的init_cfg
优先级更高,会覆盖父模块的init_cfg
。像往常一样构建模型,但显式调用
model.init_weights()
方法,模型参数将根据配置进行初始化。
MMdetection 中初始化的高级流程是
model_cfg(init_cfg) -> build_from_cfg -> model -> init_weight() -> initialize(self, self.init_cfg) -> 子模型的 init_weight()
描述¶
它是一个字典或字典列表,包含以下键和值
type
(str),包含INTIALIZERS
中的初始化器名称,后面跟着初始化器的参数。layer
(str 或 str 列表),包含 Pytorch 或 MMCV 中具有可学习参数的基本层的名称,例如'Conv2d'
,'DeformConv2d'
。override
(dict 或 dict 列表),包含未继承自 BaseModule 的子模块,以及其初始化配置不同于'layer'
键中其他层的配置。type
中定义的初始化器将适用于layer
中定义的所有层,因此,如果子模块不是BaseModule
的派生类,但可以像layer
中的层一样进行初始化,则不需要使用override
。override
包含type
后面跟着初始化器的参数;name
用于指示将要初始化的子模块。
初始化参数¶
从 mmcv.runner.BaseModule
或 mmdet.models
继承一个新的模型。 这里我们展示一个 FooModel 的示例。
import torch.nn as nn
from mmcv.runner import BaseModule
class FooModel(BaseModule)
def __init__(self,
arg1,
arg2,
init_cfg=None):
super(FooModel, self).__init__(init_cfg)
...
使用
init_cfg
在代码中直接初始化模型import torch.nn as nn from mmcv.runner import BaseModule # or directly inherit mmdet models class FooModel(BaseModule) def __init__(self, arg1, arg2, init_cfg=XXX): super(FooModel, self).__init__(init_cfg) ...
使用
init_cfg
在mmcv.Sequential
或mmcv.ModuleList
代码中直接初始化模型from mmcv.runner import BaseModule, ModuleList class FooModel(BaseModule) def __init__(self, arg1, arg2, init_cfg=None): super(FooModel, self).__init__(init_cfg) ... self.conv1 = ModuleList(init_cfg=XXX)
在配置文件中使用
init_cfg
初始化模型model = dict( ... model = dict( type='FooModel', arg1=XXX, arg2=XXX, init_cfg=XXX), ...
init_cfg 的用法¶
使用
layer
键初始化模型如果我们只定义了
layer
,它只会初始化layer
键中的层。注意:
layer
键的值是 Pytorch 中具有属性 weight 和 bias 的类名(因此不支持MultiheadAttention layer
等)。
定义
layer
键来初始化具有相同配置的模块。init_cfg = dict(type='Constant', layer=['Conv1d', 'Conv2d', 'Linear'], val=1) # initialize whole module with same configuration
定义
layer
键来初始化具有不同配置的层。
init_cfg = [dict(type='Constant', layer='Conv1d', val=1),
dict(type='Constant', layer='Conv2d', val=2),
dict(type='Constant', layer='Linear', val=3)]
# nn.Conv1d will be initialized with dict(type='Constant', val=1)
# nn.Conv2d will be initialized with dict(type='Constant', val=2)
# nn.Linear will be initialized with dict(type='Constant', val=3)
使用
override
键初始化模型
当使用其属性名初始化某些特定部分时,可以使用
override
键,override
中的值将忽略 init_cfg 中的值。# layers: # self.feat = nn.Conv1d(3, 1, 3) # self.reg = nn.Conv2d(3, 3, 3) # self.cls = nn.Linear(1,2) init_cfg = dict(type='Constant', layer=['Conv1d','Conv2d'], val=1, bias=2, override=dict(type='Constant', name='reg', val=3, bias=4)) # self.feat and self.cls will be initialized with dict(type='Constant', val=1, bias=2) # The module called 'reg' will be initialized with dict(type='Constant', val=3, bias=4)
如果 init_cfg 中的
layer
为 None,则只会初始化具有 override 中名称的子模块,并且可以省略 override 中的 type 和其他参数。# layers: # self.feat = nn.Conv1d(3, 1, 3) # self.reg = nn.Conv2d(3, 3, 3) # self.cls = nn.Linear(1,2) init_cfg = dict(type='Constant', val=1, bias=2, override=dict(name='reg')) # self.feat and self.cls will be initialized by Pytorch # The module called 'reg' will be initialized with dict(type='Constant', val=1, bias=2)
如果我们没有定义
layer
键或override
键,则不会初始化任何内容。无效用法
# It is invalid that override don't have name key init_cfg = dict(type='Constant', layer=['Conv1d','Conv2d'], val=1, bias=2, override=dict(type='Constant', val=3, bias=4)) # It is also invalid that override has name and other args except type init_cfg = dict(type='Constant', layer=['Conv1d','Conv2d'], val=1, bias=2, override=dict(name='reg', val=3, bias=4))
使用预训练模型初始化模型
init_cfg = dict(type='Pretrained', checkpoint='torchvision://resnet50')
更多详情请参考 MMEngine 的文档