栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【OpenPCDet】优化器之adam

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【OpenPCDet】优化器之adam

    OpenPCDet到目前版本(v 0.3.0)为止集成的优化器有3种:adam,sgd和adam_onecyel。这个可见代码build_optimizer(model,optim_cfg)函数。

def build_optimizer(model, optim_cfg):
    if optim_cfg.OPTIMIZER == 'adam':
        optimizer = optim.Adam(model.parameters(), lr=optim_cfg.LR, weight_decay=optim_cfg.WEIGHT_DECAY)
    elif optim_cfg.OPTIMIZER == 'sgd':
        optimizer = optim.SGD(
            model.parameters(), lr=optim_cfg.LR, weight_decay=optim_cfg.WEIGHT_DECAY,
            momentum=optim_cfg.MOMENTUM
        )
    elif optim_cfg.OPTIMIZER == 'adam_onecycle':
        def children(m: nn.Module):
            return list(m.children())

        def num_children(m: nn.Module) -> int:
            return len(children(m))

        flatten_model = lambda m: sum(map(flatten_model, m.children()), []) if num_children(m) else [m]
        get_layer_groups = lambda m: [nn.Sequential(*flatten_model(m))]

        optimizer_func = partial(optim.Adam, betas=(0.9, 0.99)) #Adam超参数
        optimizer = OptimWrapper.create(
            optimizer_func, 3e-3, get_layer_groups(model), wd=optim_cfg.WEIGHT_DECAY, true_wd=True, bn_wd=True
        )
    else:
        raise NotImplementedError

    return optimizer

平常训练用得较多的是adam_onecycle。它本质上是adam优化器再加上onecycle学习率调整策略。我比较关心的是这个onecycle的学习率调整策略,在这里使用一个少量样本的训练集来认识一下关于onecycle学习率调整中涉及到的若干参数。

OPTIMIZATION:
    BATCH_SIZE_PER_GPU: 5
    NUM_EPOCHS: 100

    OPTIMIZER: adam_onecycle
    LR: 0.003
    WEIGHT_DECAY: 0.01
    MOMENTUM: 0.9

    MOMS: [0.95, 0.85]
    PCT_START: 0.3
    DIV_FACTOR: 10
    DECAY_STEP_LIST: [35, 45]
    LR_DECAY: 0.1
    LR_CLIP: 0.0000001

    LR_WARMUP: False
    WARMUP_EPOCH: 1

    GRAD_NORM_CLIP: 10

我设置的训练集样本为100,BATCH_SIZE为5,总的训练epochs数num_epochs为100。按此计算的话,总的训练迭代次数为200。训练过后得到的lr曲线如下: 

  

 我把要关注的几个点在图中以红色圆圈标示了出来。从左至右,第一个红圈为学习率的起点low_lr,它的值是由配置文件中给定的两个参数LR和DIV_FACTOR计算得到,low_lr = LR / DIR_FACTOR,即0.0003。第二个红圈是学习率最大的地方lr_max,它正是配置文件中设置的LR,值为0.003。第三个红圈为训练结束时学习率lr_end。

class oneCycle(LRSchedulerStep):
    def __init__(self, fai_optimizer, total_step, lr_max, moms, div_factor,
                 pct_start):
        self.lr_max = lr_max
        self.moms = moms             #e.g. [0.95, 0.85]
        self.div_factor = div_factor #e.g. 10
        self.pct_start = pct_start   #学习率上升的部分step数量的占比, e.g. 0.4
        a1 = int(total_step * self.pct_start) 
        a2 = total_step - a1
        low_lr = self.lr_max / self.div_factor   #初始学习率
        lr_phases = (
            (0, partial(annealing_cos, low_lr, self.lr_max)), #上升期,low_lr-->lr_max
            (self.pct_start, partial(annealing_cos, self.lr_max, low_lr / 1e4)) #下降期,lr_max->low_lr/1e4
        )
        mom_phases = (
            (0, partial(annealing_cos, *self.moms)),
            (self.pct_start, partial(annealing_cos,*self.moms[::-1]))
        )
        fai_optimizer.lr, fai_optimizer.mom = low_lr, self.moms[0]
        super().__init__(fai_optimizer, total_step, lr_phases, mom_phases)

总的说的,adam_oncycle中学习率曲线的变化分成两个部分。第一个部分是由low_lr上升到lr_max,这一部分由PCT_START这个系数控制上升阶段的迭代次数(PCT_START*num_total_iters),由cos函数控制调整步长。第二部分是学习率由lr_max下降到lr_end,剩余迭代次数当然就是(1-PCT_START)*num_total_iters,同样是由cos函数控制调整步长。 在具体的训练任务中,通过合理地调整LR、PCT_START等参数来使训练任务达到最优。至于配置文件中的其它参数,如:DECAY_STEP_LIST、LR_DECAY、LR_DECAY_STEP等,在adam_onecycle优化器中并未使用到。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/581072.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号