神经网络中学习率 warmup 策略为什么有效?学习率应该怎么变化会比较好?

Linear Scale

随着Batch Size增大,学习率也需要增大

如何调整:Batch Size理解、如何调整batch size和学习率之间的关系?_batch size 比较大时,需要把learning rate也调大吗-CSDN博客

Warmup

在训练最开始,模型中绝大多数参数都是随机初始化的,与最终模型很远。一开始就使用一个很大的LR,会增加不确定性。所以在训练最开始,先使用一个较小的LR,训练几轮Epoch后,再使用较大的LR。

1.直观理解就是最开始的时候,loss大,如果学习率太大,gradient也就弄的很大,容易崩,结果什么都学不到。所以最开始步子小一些,等模型收敛到合适的位置,loss不再爆炸,再加大学习率开始快速学习。

和你说的sgd的用法也不矛盾,但是那个的前提是模型不容易跑崩。

2.有同感,实际跑起来的时候,一开始如果保证网络不崩掉,lr就得调小,直观上到平台期以后(实际上并没有到),再做decay,loss更降不动,倒是增大lr反而又能观察到loss的下降。随机权值并不见得是个好的初始化方式,warm-up倒也可以看做某种程度上的“预训练”

通俗的解释:

3.开车进入一个新城市的时候,一开始总是要小心翼翼驾驶的,否则容易出事故,过一会了大致了解了周边环境了才能提速。

Decay

一直使用较大的LR也有问题,在训练中后期,过大的LR可能导致模型在最优解附近震荡,无法快速收敛。

所以,在中后期,需要将LR进行一些衰减(Decay)。ResNet论文中最初使用的Step Decay:每训练30个Epoch,LR衰减为刚才的0.1倍。还有Cosine衰减

Step Decay 和 cosine decay

最好的学习率调整方案:

Linear + Warmup + Decay

将以上三种LR策略组合起来,可以形成一个完整的LR策略:

  1. 根据Batch Size大小,线性地缩放LR基准值,
  2. 前几个Epoch使用较小的LR先进行Warmup逐渐增大学习率,
  3. 之后逐渐对LR进行Decay衰减。

整个训练过程随着epoch增加,学习率的变化方案

一般的学习率应该怎么选择?

batch-size用8-64

学习率10的-4到10的-2。

示例代码:

rcg用的就是这样的lr调整代码

此处给一个示例代码,到时候按需要调整即可

import math
import argparse

def adjust_learning_rate_cosine_epoch(optimizer, epoch, args):
    """Decay the learning rate with half-cycle cosine after warmup"""
    if epoch < args.warmup_epochs:
        lr = args.lr * epoch / args.warmup_epochs 
    else:
        lr = args.min_lr + (args.lr - args.min_lr) * 0.5 * \
            (1. + math.cos(math.pi * (epoch - args.warmup_epochs) / (args.epochs - args.warmup_epochs)))
    for param_group in optimizer.param_groups:
        if "lr_scale" in param_group:
            param_group["lr"] = lr * param_group["lr_scale"]
        else:
            param_group["lr"] = lr
    return lr

def adjust_learning_rate_cosine_step(optimizer, current_step, lr, **kwargs):
    """
    Linear + Warmup + cosine-Decay
    用于step为单位的程序
    :param optimizer:
    :param step:
    :param kwargs:
    :return:
    """

    warmup_steps = kwargs['warmup_steps']
    total_steps = kwargs['total_steps']
    lr = lr
    min_lr = kwargs['min_lr']


    if current_step < warmup_steps:
        lr = lr * current_step / warmup_steps
    else:
        lr = min_lr + (lr - min_lr) * 0.5 * (1. + math.cos(math.pi * (current_step - warmup_steps) / (total_steps - warmup_steps)))

    for param_group in optimizer.param_groups:
        if "lr_scale" in param_group:
            param_group["lr"] = lr * param_group["lr_scale"]
        else:
            param_group["lr"] = lr

    return lr




def adjust_learning_rate_const(optimizer, epoch, args):
    """Decay the learning rate with half-cycle cosine after warmup"""
    if epoch < args.warmup_epochs:
        lr = args.lr * epoch / args.warmup_epochs
    else:
        lr = args.lr
    for param_group in optimizer.param_groups:
        if "lr_scale" in param_group:
            param_group["lr"] = lr * param_group["lr_scale"]
        else:
            param_group["lr"] = lr
    return lr




def get_args_parser():
    parser = argparse.ArgumentParser('RDM training', add_help=False)
    parser.add_argument('--epochs', default=400, type=int)
    parser.add_argument('--accum_iter', default=1, type=int, help='Accumulate gradient iterations (for increasing the effective batch size under memory constraints)')

    # Optimizer parameters
    parser.add_argument('--weight_decay', type=float, default=0.05, help='weight decay (default: 0.05)')
    parser.add_argument('--lr', type=float, default=None, metavar='LR', help='learning rate (absolute lr)')
    parser.add_argument('--blr', type=float, default=1e-3, metavar='LR', help='base learning rate: absolute_lr = base_lr * total_batch_size')
    parser.add_argument('--min_lr', type=float, default=0., metavar='LR', help='decay lower lr bound for cyclic schedulers that hit 0')
    parser.add_argument('--cosine_lr', action='store_true', help='Use cosine lr scheduling.')
    parser.add_argument('--warmup_epochs', default=0, type=int)


# data_iter_step / len(data_loader) + epoch:是将学习率细致调整到了epoch中的step内,而不是简单的一个epoch用一个lr
adjust_learning_rate_cosine_step(optimizer, current_step, lr, **args)
# forward
# backward
# optimizer

# updata_lr
lr = optimizer.param_groups[0]["lr"]


Learning Rate Schedule:CNN学习率调整策略 - 知乎

神经网络中 warmup 策略为什么有效;有什么理论解释么? - 知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马鹏森

太谢谢了

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值