【玩转yolov5】请看代码之参数管理及学习率调整

    yolov5中的优化器(optimizer)将模型可学习的参数分成了三个组,分别为pg0:BN参数,pg1:一般权重(weight)参数,pg2:偏置(biase)参数,通过param_group来管理3组参数。param_group的意义在于可以针对不同的参数组量身定制学习率(lr)、衰减(weight_decay)、动量(moment)等超参数。例如在某一模型中,希望特征提取部分的权值参数的学习率小一点,学习更新慢一点,这时可以把特征提取的参数设置为一组参数,而对于后面全连接分类层,希望其学习率大一点,学习快一点。这时,可以把整个模型参数设置为两组,一组为特征提取部分的参数,另一部分是全连接层的参数,对这两组设置不同的学习率或超参数。

def train(...): 
   #....省略.....
    pg0, pg1, pg2 = [], [], []  # optimizer parameter groups
        #将模型分成三组(weight,bn,bias,其它所有参数)优化
    for k, v in model.named_modules():
        if hasattr(v, 'bias') and isinstance(v.bias, nn.Parameter):
            pg2.append(v.bias)  # biases
        if isinstance(v, nn.BatchNorm2d):
            pg0.append(v.weight)  # no decay
        elif hasattr(v, 'weight') and isinstance(v.weight, nn.Parameter):
            pg1.append(v.weight)  # apply decay

    if opt.adam:
        optimizer = optim.Adam(pg0, lr=hyp['lr0'], betas=(hyp['momentum'], 0.999))  # adjust beta1 to momentum
    else:
        #nesterov梯度下降是继动量梯度下降之后的一种梯度下降的修正方法,也是继承了动量梯度的思想
        optimizer = optim.SGD(pg0, lr=hyp['lr0'], momentum=hyp['momentum'], nesterov=True)

    #添加参数组,设置weight,bias的优化方式
    optimizer.add_param_group({'params': pg1, 'weight_decay': hyp['weight_decay']})  # add pg1 with weight_decay
    optimizer.add_param_group({'params': pg2})  # add pg2 (biases)
    logger.info('Optimizer groups: %g .bias, %g conv.weight, %g other' % (len(pg2), len(pg1), len(pg0)))
    del pg0, pg1, pg2
    #....省略....

    学习率的调整yolov5使用pytorch已经封装好的torch.optim.lr_scheduler.LambdaLR方法,訪方法包含三个参数:

  • lr_lambda, function or list,一个计算学习率调整倍数的函数,输入通常为step,当有多个参数组时设为list;
  • last_epoch,这个变量用来指示学习率是否需要调整,当last_epoch符合设定的间隔时就会对学习率进行调整,当为-1时,学习率设置为初始值;
import math
import matplotlib.pyplot as plt
%matplotlib inline

def one_cycle(y1=0.0, y2=1.0, steps=100):
    # lambda function for sinusoidal ramp from y1 to y2
    return lambda x: ((1 - math.cos(x * math.pi / steps)) / 2) * (y2 - y1) + y1

lrf=0.2
epochs=300
lr_lambda=one_cycle(1,lrf,epochs)

lr_of_epoch = []
for last_epoch in range(epochs):
    lr = lr_lambda(last_epoch)
    lr_of_epoch.append(lr)

#s:点的面积
#c:颜色
plt.scatter(range(epochs),lr_of_epoch,s=1,c='green')
plt.title("yolov5 default lr_lambda")

【玩转yolov5】请看代码之参数管理及学习率调整_第1张图片

base_lr = 0.01
lr_of_epoch = []
for last_epoch in range(epochs):
    #lr=base_lr * lambda(last_epoch)
    lr = base_lr * lr_lambda(last_epoch)
    lr_of_epoch.append(lr)

#s:点的面积
#c:颜色
plt.scatter(range(epochs),lr_of_epoch,s=1,c='red')
plt.title("yolov5 default lr decay policy")

【玩转yolov5】请看代码之参数管理及学习率调整_第2张图片

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