MMLab中自定义模块初始化方法

这方面好像介绍的少,看了下基本原理,下面介绍下如何在搭载权重的模型中加入自定义模块时方便的进行初始化。

MMLab的逻辑时对每个部分进行初始化,若此部分定义了初始化方法为Pretrained则加载权重,然后对内部其他模块不再进行其他的初始化操作。

但其存在着一个问题。例如,需要对backbone改进,加入自定义模块后同时需要原模型的预训练权重,此时无法方便的对新加入模块进行初始化操作(因为代码决定其会跳过了此部分初始化,直接进行下一部分的初始化操作)。源代码如下(在BaseModule)中:

复制代码
        if not self._is_init:
            if self.init_cfg:
                print_log(
                    f'initialize {module_name} with init_cfg {self.init_cfg}',
                    logger=logger_name)
                initialize(self, self.init_cfg)
                if isinstance(self.init_cfg, dict):
                    # prevent the parameters of
                    # the pre-trained model
                    # from being overwritten by
                    # the `init_weights`
                    if self.init_cfg['type'] == 'Pretrained':
                        return

            for m in self.children():
                if hasattr(m, 'init_weights'):
                    m.init_weights()
                    # users may overload the `init_weights`
                    update_init_info(
                        m,
                        init_info=f'Initialized by '
                        f'user-defined `init_weights`'
                        f' in {m.__class__.__name__} ')

            self._is_init = True

那么如何对自定义模块方便地进行初始化呢,下面介绍三种方法:

(1)定义一个my_weight_init()对自定义模块中的所有module进行初始化操作,其优点是可操作性强,但设置复杂。代码如下:

复制代码
def my_module_weights_init(target_module):
    for m in target_module.modules():
        if type(m) == nn.Conv2d:
            nn.init.xavier_normal_(m.weight.data)
            nn.init.constant_(m.bias.data, 0.0)

对自定义的模块的初始化直接调用apply即可。

(2)对于MMLab中定义好的模块,若其存在init_cfg则可直接输入相关设置参数进行初始化操作。

(3)最为方便的方法,在mmcv.cnn.utils.weight_init中存在initialize函数,可通过相关参数对函数内部所有相关层进行初始化操作,主要原理是建立初始化器的实例化对象,对模块参数进行处理。mmcv中目前可调用一下八种方法进行初始化,位于mmcv.cnn.utilsz中。

复制代码
'ConstantInit', 'XavierInit', 'NormalInit', 'TruncNormalInit', 'UniformInit', 'KaimingInit', 'PretrainedInit', 'Caffe2XavierInit'

上述initialize方法的相关代码如下:

复制代码
def my_module_weights_init(target_module, init_cfg):
    from mmcv.cnn.utils.weight_init import initialize
    initialize(target_module, init_cfg)

调用初始化方法的代码(可直接调用initialize方法,我为了方便好看改了个名):

复制代码
if self.training:
    my_module_init_cfg = [dict(type='TruncNormal', layer=['Conv2d', 'Linear'], std=.02, bias=0.), dict(type='Constant', layer=['LayerNorm'], val=1., bias=0.),]
    my_module_weights_init(self.gt_seg_downsample_layers, my_module_init_cfg)

欢迎补充其他方便的方法。

相关推荐
知行合一。。。21 分钟前
Python--03--函数入门
android·数据库·python
竹君子23 分钟前
AIDC知识库(3)英伟达Rubin 架构对未来AIDC方案的影响初探
人工智能
朝九晚五ฺ23 分钟前
从零到实战:鲲鹏平台 HPC 技术栈与并行计算
java·开发语言
CUIYD_198925 分钟前
Freemarker 无法转译 & 字符
java·开发语言·spring
棒棒的皮皮31 分钟前
【深度学习】YOLO模型速度优化全攻略(模型 / 推理 / 硬件三层维度)
人工智能·深度学习·yolo·计算机视觉
线束线缆组件品替网32 分钟前
Amphenol RF 同轴线缆:高频 RF 系统设计中 VSWR 与损耗控制实践
网络·人工智能·电脑·硬件工程·材料工程
superman超哥33 分钟前
Rust Vec的内存布局与扩容策略:动态数组的高效实现
开发语言·后端·rust·动态数组·内存布局·rust vec·扩容策略
Evand J36 分钟前
【MATLAB例程,附代码下载链接】基于累积概率的三维轨迹,概率计算与定位,由轨迹匹配和滤波带来高精度位置,带测试结果演示
开发语言·算法·matlab·csdn·轨迹匹配·候选轨迹·完整代码
Yuiiii__37 分钟前
一次并不简单的 Spring 循环依赖排查
java·开发语言·数据库
-曾牛37 分钟前
Yak语言核心基础:语句、变量与表达式详解
数据库·python·网络安全·golang·渗透测试·安全开发·yak