动态调整学习率 PyTorch optimizer

总述

官网地址:ReduceLROnPlateau
在这里插入图片描述

以ReduceLROnPlateau为例讲解参数

以最后一个为例,详细介绍:
该方法是PyTorch提供的一种基于验证指标的调整方法。它的原理是:当指标停止改善时,降低学习率。当模型的学习停滞时,训练过程通常会受益于将学习率降低2~10倍。该种调整方法读取一个度量指标,如果在“耐心”期间内没有发现它有所改善,那么就会降低学习率。
下面将一一讲解它的形参:
(1)optimizer:在epoch循环之前定义好的优化器
(2)mode:可选str字符串数据,为min或max。当选择min时,代表当度量指标停止下降时,开始减小学习率;当选择max时,代表当度量指标停止上升时,开始减小学习率。
(3)factor:float类型数据,学习率调整的乘法因子,默认值为0.1。
(4)patience:int类型数据,可容忍的度量指标没有提升的epoch数目,默认为10。举例说明,当其设置为10时,我们可以容忍10个epoch内没有提升,如果在第11个epoch依然没有提升,那么就开始降低学习率。
(5)verbose:bool数据,如果设置为True,输出每一次更新的信息,默认为False
(6)threshold:float类型数据,衡量新的最佳阈值,仅关注重大变化,默认为0.0001。
(7)threshold_mode:可选str字符串数据,为rel或abs,默认为rel。在rel模式下,如果mode参数为max,则动态阈值(dynamic_threshold)为best*(1+threshold),如果mode参数为min,则动态阈值为best+threshold,如果mode参数为min,则动态阈值为best-threshold。
(8)cooldown:int类型数据,减少lr后恢复正常操作之前要等待的epoch数,默认为0。
(9)min_lr:float或list类型数据,学习率的下界,默认为0。
(10)eps:float类型数据,学习率的最小变化值。如果调整后的学习率和调整前的差距小于eps的话,那么就不做任何调整,默认为1e-8。

其使用案例为:

>>> optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
>>> scheduler = ReduceLROnPlateau(optimizer, 'min')
>>> for epoch in range(10):
>>>     train(...)
>>>     val_loss = validate(...) # 度量指标
>>>     # Note that step should be called after validate()
>>>     scheduler.step(val_loss) # 根据度量指标调整学习率

这里实现的功能是,采用SGD优化器,以val_loss为衡量指标,如果在10个epoch内(默认patient= 10),loss没有明显下降(默认mode=min),那么,lr就会动态调整为new_lr = lr * factor(默认是factor=0.1),momentum (float, 可选) – 动量因子(默认:0)

补充两个其他函数的书写案例

在这里插入图片描述
参考文章:https://blog.csdn.net/qq_42079689/article/details/102806940

代码实现

import torch
import torch.optim as optim

optimizer = optim.SGD(model.parameters(), lr = Lr, momentum = 0.9)
# torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10, threshold=0.0001, threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-08, verbose=False)
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer,patience=3 ,mode = 'min')

#test.py   
    model.eval()
    test_loss = 0.0
    correct = 0
    with torch.no_grad():
        for batch_index,(data, target)in enumerate (test_loader):
            data,target = data.float(),target.float()
            target = target.view(-1,1)
            output = model(data)                                 
            test_loss += criterion(output, target).item()  
              
            scheduler.step(test_loss) #以test_loss 为衡量指标,调整lr
            
            pred = output.argmax(dim = 1, keepdim=True)# 预测的最大值的下标  
            correct += pred.eq(target.view_as(pred)).sum().item()
    test_loss = test_loss
    all_test_loss.append(test_loss)
    all_test_correct.append(correct / len(test_loader.dataset))   
    print('测试集:损失:{:.4f},{}/{},精度:{:.2f}%'.format(test_loss, correct, len(test_loader.dataset),
                                                  100. * correct / len(test_loader.dataset)))

结果如下(图形并不理想)
在这里插入图片描述将epoch的调整周期设置为3 之后,结果如图
在这里插入图片描述仍然不行呀。。。
考虑不是学习率的问题
下一步调整预测阈值

猜你喜欢

转载自blog.csdn.net/HJ33_/article/details/120503343
今日推荐