pytorch学习十一 ---- 学习率调整策略以及tensorboad

在优化器中有很多超参数,如学习率、momentum等。其中学习率直接控制参数更新的一个大小,在整个训练当中,学习率也不是一成不变的。

为什么要调整学习率?

学习率是直接控制更新的步伐,从梯度下降的公式w_{i+1} = w_i - LR*g(w_i)可以看出,参数更新中LR*g(w_i)是学习率乘以一个梯度(更新量),在这里学习率直接控制了参数更新的大小。一般我们在刚开始训练时,学习率会设定比较大,让更新步伐较大,到了后期,学习率LR会下降,让参数更新的步伐变小。

pytorch中提供了多种学习率调整策略,其主要基于下面这个基类:

class _LRScheduler(object):
    def __init__(self,optimizer,last_epoch=-1):

    def get_lr(self):
        raise NotImplementedError

主要属性:

  • optimizer:关联的优化器
  • last_epoch:记录epoch数
  • base_lrs:记录初始学习率

主要方法:

  • step():更新下一个epoch的学习率
  • get_lr():虚函数,计算下一个epoch的学习率

 

pytorch提供的6中学习率调整策略:

1. lr_scheduler.StepLR(optimizer,step_size,gamma=0.1,last_epoch=-1)

功能:等间隔调整学习率

主要参数:

  • step_size:调整间隔数
  • gamma:调整系数

调整方式:lr = lr * gamma

import torch
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
torch.manual_seed(1)

LR = 0.1
iteration = 10
max_epoch = 200
# ------------------------------ fake data and optimizer  ------------------------------

weights = torch.randn((1), requires_grad=True)
target = torch.zeros((1))
optimizer = optim.SGD([weights], lr=LR, momentum=0.9)

# ------------------------------ 1 Step LR ------------------------------
# flag = 0
flag = 1
if flag:

    scheduler_lr = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.1)  # 设置学习率下降策略

    lr_list, epoch_list = list(), list()
    for epoch in range(max_epoch):

        lr_list.append(scheduler_lr.get_lr())
        epoch_list.append(epoch)

        for i in range(iteration):

            loss = torch.pow((weights - target), 2)
            loss.backward()

            optimizer.step()
            optimizer.zero_grad()

        scheduler_lr.step()

    plt.plot(epoch_list, lr_list, label="Step LR Scheduler")
    plt.xlabel("Epoch")
    plt.ylabel("Learning rate")
    plt.legend()
    plt.show()

从运行结果可以看出,每隔50个epoch后,就会降低一次学习率,开始的时候lr为0.1,运行50个epoch后,更新lr 为lr*gamma = 0.1*0.1 =0.01,然后同理,每隔50个epoch,则乘以gamma=0.1,来更新lr。

第二个调整策略:

2. lr_scheduler.MultiStepLR(optimizer,milestones,gamma=0.1,last_epoch=-1)

功能:按给定间隔调整学习率

主要参数:

milestones:设定调整时刻数

gamma:调整系数

调整方式:lr = lr * gamma

# ------------------------------ 2 Multi Step LR ------------------------------
# flag = 0
flag = 1
if flag:

    milestones = [50, 125, 160]
    scheduler_lr = optim.lr_scheduler.MultiStepLR(optimizer, milestones=milestones, gamma=0.1)

    lr_list, epoch_list = list(), list()
    for epoch in range(max_epoch):

        lr_list.append(scheduler_lr.get_lr())
        epoch_list.append(epoch)

        for i in range(iteration):

            loss = torch.pow((weights - target), 2)
            loss.backward()

            optimizer.step()
            optimizer.zero_grad()

        scheduler_lr.step()

    plt.plot(epoch_list, lr_list, label="Multi Step LR Scheduler\nmilestones:{}".format(milestones))
    plt.xlabel("Epoch")
    plt.ylabel("Learning rate")
    plt.legend()
    plt.show()

在代码中我们设置的milestone为50、125、160,从运行结果可以看出,其在每个milestone处进行lr 更新。这与step LR不同,step LR是等间隔的,这里是自定义间隔。

 

3.  lr_scheduler.ExponentialLR(optimizer,gamma,last_epoch=-1)

功能:按指数衰减调整学习率

主要参数

gamma:指数的底

调整方式:lr = lr *gamma^{epoch}

# ------------------------------ 3 Exponential LR ------------------------------
# flag = 0
flag = 1
if flag:

    gamma = 0.95
    scheduler_lr = optim.lr_scheduler.ExponentialLR(optimizer, gamma=gamma)

    lr_list, epoch_list = list(), list()
    for epoch in range(max_epoch):

        lr_list.append(scheduler_lr.get_lr())
        epoch_list.append(epoch)

        for i in range(iteration):

            loss = torch.pow((weights - target), 2)
            loss.backward()

            optimizer.step()
            optimizer.zero_grad()

        scheduler_lr.step()

    plt.plot(epoch_list, lr_list, label="Exponential LR Scheduler\ngamma:{}".format(gamma))
    plt.xlabel("Epoch")
    plt.ylabel("Learning rate")
    plt.legend()
    plt.show()

我们可以看到运行结果中学习率呈指数下降趋势。

 

4. lr_scheduler.CosineAnnealingLR(optimizer,T_max,eta_min=0,last_epoch=-1)

功能:余弦周期调整学习率

主要参数:

  • T_max:下降周期(1/2周期)
  • eta_min:学习率下限

调整方式:\eta_t = \eta_{min} +\frac{1}{2}(\eta_{max}-\eta_{min})(1+cos(\frac{T_{cur}}{T_{max}}\pi))

# ------------------------------ 4 Cosine Annealing LR ------------------------------
# flag = 0
flag = 1
if flag:

    t_max = 50
    scheduler_lr = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=t_max, eta_min=0.)

    lr_list, epoch_list = list(), list()
    for epoch in range(max_epoch):

        lr_list.append(scheduler_lr.get_lr())
        epoch_list.append(epoch)

        for i in range(iteration):

            loss = torch.pow((weights - target), 2)
            loss.backward()

            optimizer.step()
            optimizer.zero_grad()

        scheduler_lr.step()

    plt.plot(epoch_list, lr_list, label="CosineAnnealingLR Scheduler\nT_max:{}".format(t_max))
    plt.xlabel("Epoch")
    plt.ylabel("Learning rate")
    plt.legend()
    plt.show()

从结果可以看出,200个epoch中,学习率从0.1逐渐下降到0,在50个epoch时达到最低,50是有T_max决定的,任何又经过50个epoch后,上升到最高。因此,周期为两个T_max。

 

5. lr_scheduler.ReduceLROnPlateau(optimizer,mode="min",factor=0.1,patience=10,verbose=False,threshold=0.0001,threshold_mode="rel",cooldown=0,min_lr=0,eps=1e-08)

功能:监控指标,当指标不再变化则调整

主要参数:

  • mode:min/max两种模式(min模式下观察检测的指标是否下降,如loss,max则检测观察指标是否上升,如accuracy)
  • factor:调整系数(相当于上诉中的gamma)
  • patience:“耐心”,接受几次不变化(连续10次没有变化或不满足要求,则调整学习率)
  • cooldown:“冷却时间”,停止监控一段时间
  • verbose:是否打印日志
  • min_lr:学习率下限
  • eps:学习率衰减最小值
# ------------------------------ 5 Reduce LR On Plateau ------------------------------
# flag = 0
flag = 1
if flag:
    loss_value = 0.5
    accuray = 0.9

    factor = 0.1
    mode = "min"
    patience = 10
    cooldown = 10
    min_lr = 1e-4
    verbose = True

    scheduler_lr = optim.lr_scheduler.ReduceLROnPlateau(optimizer, factor=factor, mode=mode, patience=patience,
                                                        cooldown=cooldown, min_lr=min_lr, verbose=verbose)

    for epoch in range(max_epoch):
        for i in range(iteration):

            # train(...)

            optimizer.step()
            optimizer.zero_grad()

        if epoch == 5:
            loss_value = 0.4

        scheduler_lr.step(loss_value)

 

6. lr_scheduler.LambdaLR(optimizer,lr_lambda,last_epoch=-1)

功能:自定义调整策略

主要参数:

  • lr_lambda:function or list
# ------------------------------ 6 lambda ------------------------------
# flag = 0
flag = 1
if flag:

    lr_init = 0.1

    weights_1 = torch.randn((6, 3, 5, 5))
    weights_2 = torch.ones((5, 5))

    optimizer = optim.SGD([
        {'params': [weights_1]},
        {'params': [weights_2]}], lr=lr_init)

    lambda1 = lambda epoch: 0.1 ** (epoch // 20)
    lambda2 = lambda epoch: 0.95 ** epoch

    scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=[lambda1, lambda2])

    lr_list, epoch_list = list(), list()
    for epoch in range(max_epoch):
        for i in range(iteration):

            # train(...)

            optimizer.step()
            optimizer.zero_grad()

        scheduler.step()

        lr_list.append(scheduler.get_lr())
        epoch_list.append(epoch)

        print('epoch:{:5d}, lr:{}'.format(epoch, scheduler.get_lr()))

    plt.plot(epoch_list, [i[0] for i in lr_list], label="lambda 1")
    plt.plot(epoch_list, [i[1] for i in lr_list], label="lambda 2")
    plt.xlabel("Epoch")
    plt.ylabel("Learning Rate")
    plt.title("LambdaLR")
    plt.legend()
    plt.show()

 

学习率调整总结:

1.有序调整:step、MultiStep、Exponential和CosineAnnealing

2.自适应调整:ReduceLROnPleateau

3.自定义调整:Lambda

学习率初始化:

1. 设置较小数:0.01、0.001、0.0001

2. 搜索最大学习率:《Cyclical Learning Rates for Training Neural Networks》

 

可视化方法--- TensorBoard的使用

TensorBoard:是TensorFlow中强大的可视化工具,支持标量、图像、文本、音频、视频和Embedding等多种数据可视化。

运行机制:

首先在python脚本中记录可视化的数据,也就是我们在可视化中需要监控哪些数据,我们就需要将这些数据监控起来。将记录的数据放入硬盘当中event file(事件文件),接着我们在终端tensorboard中读取event file,然后tensorboard就会在web端进行可视化,这就是tensorboard的运行机制。

首先安装tensorboard

pip install tensorflow==1.14.0
pip install tensorboard

安装过程中tensorflow版本号需要大于等原因1.14.0,我支持强制让tensorflow为1.14.0,tensorboard也为1.14.0

编写简单的测试代码

import numpy as np
from torch.utils.tensorboard import SummaryWriter

writer = SummaryWriter(comment='test_tensorboard')

for x in range(100):

    writer.add_scalar('y=2x', x * 2, x)
    writer.add_scalar('y=pow(2, x)',  2 ** x, x)
    
    writer.add_scalars('data/scalar_group', {"xsinx": x * np.sin(x),
                                             "xcosx": x * np.cos(x),
                                             "arctanx": np.arctan(x)}, x)
writer.close()

运行该脚本,会生成如下文件:

接着在pycharm下的terminal下运行生成的runs文件:

接着在该路径下运行以下代码:

tensorboard --logdir=./runs

接着会生成对应的网址:

TensorBoard 1.14.0 at http://LAPTOP-UVUKGK1D:6006/ (Press CTRL+C to quit)

运行该网址得到如下界面:



 


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值