学习率设置(写给自己看)

https://www.cnblogs.com/pprp/p/14975419.html

讲的很好的一个博客。

现往你的.py文件上打上以下代码:

import torch
import numpy as np
from torch.optim import SGD
from torch.optim import lr_scheduler
from torch.nn.parameter import Parameter

model = [Parameter(torch.randn(2, 2, requires_grad=True))]
optimizer = SGD(model, lr=0.1)

然后在最后的循环打上以下代码:

epochs=100
for epoch in (1,epochs+1):
    train()
    test()
    lr_schedulers.step()

这里的train和test是你的训练和测试调用的函数。

学习率参数很难调节,针对图像分类任务,一般使用的是:

1.阶梯型衰减,

就是在指定的批次上降低指定倍数,比如如果100个epoch,设置在1/3和3/4处学习率减小一倍,这种有两种实现方式:

方式一:

lr_schedulers=lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)

方式二:

epochs=100
for epoch in (1,epochs+1):
    if epoch%30 == 0:
        lr = lr*0.1
    train()
    test()
    lr_schedulers.step()

2.MultiStepLR:多个不同速率的衰减

方式一:

scheduler = lr_scheduler.MultiStepLR(optimizer, milestones=[30,80], gamma=0.5)

方式二:

for epoch in (1,epochs+1):
    if epoch == 30:
        lr = lr*0.1
    if epoch == 40:
        lr = lr*0.5
    train()
    test()
    lr_schedulers.step()

3.指数型下降的学习率调节器

公式:

 curr_rate:当前的学习率

 init_rate:初始的学习率

gamma:衰减系数

epochs:计数器,从0计数到训练的迭代次数

decay_step:控制衰减速度

公式表达的含义其实很明显,gamma衰减系数代表的就是衰减函数的形状,>1学习率就增长了,<1学习率就衰减了。代码实现:

X = []
Y = []
# 初始学习率
learning_rate = 0.1
# 衰减系数
decay_rate = 0.1
# decay_steps控制衰减速度
# 如果decay_steps大一些,(global_step / decay_steps)就会增长缓慢一些
#   从而指数衰减学习率decayed_learning_rate就会衰减得慢一些
#   否则学习率很快就会衰减为趋近于0
decay_steps = 60
# 迭代轮数
global_steps = 120
# 指数学习率衰减过程
for global_step in range(0,global_steps):
    decayed_learning_rate = learning_rate * decay_rate**(global_step / decay_steps)
    X.append(global_step / decay_steps)
    Y.append(decayed_learning_rate)
    if global_step==0 or global_step==global_steps-1:
        print("global step: %d, learning rate: %f" % (global_step,decayed_learning_rate))
    
fig = plt.figure(1)
ax = fig.add_subplot(1,1,1)
curve = ax.plot(X,Y,'b',label="learning rate")
ax.legend()
ax.set_xlabel("epochs / decay_steps")
ax.set_ylabel("learning_rate")

你通过设置初始学习率和最后想要下降到的学习率试着模拟一下。 效果还是不错的。

 实现方式:

实质上pytorch里面有:

scheduler = lr_scheduler.ExponentialLR(optimizer, gamma=0.9)

但是和上面的公式是有出入的,他的实现方式其实就是当前的学习率乘以gamma系数值,所以在最后学习率肯定会同样的衰减率torch里面下降的是比上面的快的,所以有两种策略,第一种调整gamma系数然后打印每次的学习率的数值调整到自己想要的学习率大小,即:

我i试了试改成0.96差不多就可以了。

第二种就是把上面的方式封装成一个函数,在for循环里每次调用他,封装成函数就可以使用

LambdaLR学习策略

了,它可以自定义函数,实现方式如下:

# 初始学习率
learning_rate = 0.1
# 衰减系数
decay_rate = 0.1
# decay_steps 控制衰减速度
decay_steps = 60
# 迭代轮数
global_steps = 120


# 自定义指数衰减函数
def exponential_decay(initial_lr, decay_rate, decay_steps, global_step):
    return initial_lr * decay_rate**(global_step / decay_steps)



scheduler = LambdaLR(optimizer, lr_lambda=lambda step: exponential_decay(learning_rate, decay_rate, decay_steps, step))

# 记录学习率的变化
lr_history = []

# 模拟训练过程
for epoch in range(global_steps):
    # 执行训练步骤
    # ...

    # 记录当前学习率
    current_lr = optimizer.param_groups[0]['lr']
    lr_history.append(current_lr)

    # 更新学习率
    scheduler.step()

这个函数就非常的方便,像是上面的多阶段衰减也可以使用这个函数进行实现。

 OneCycleLR

scheduler=lr_scheduler.OneCycleLR(optimizer,max_lr=0.1,pct_start=0.5,total_steps=120,div_factor=10,final_div_factor=10)

可视化 OneCycleLR:

import torch
from torch.optim.lr_scheduler import OneCycleLR
import matplotlib.pyplot as plt

# 定义神经网络和优化器
class SimpleNet(torch.nn.Module):
    def __init__(self):
        super(SimpleNet, self).__init__()
        self.fc = torch.nn.Linear(10, 1)

    def forward(self, x):
        return self.fc(x)

net = SimpleNet()
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)

# 定义 OneCycleLR 学习率调度器
scheduler = OneCycleLR(optimizer, max_lr=0.1, pct_start=0.5, total_steps=120, div_factor=10, final_div_factor=10)

# 记录学习率的变化
lr_history = []

# 模拟训练过程
for epoch in range(120):
    # 执行训练步骤
    # ...

    # 记录当前学习率
    current_lr = optimizer.param_groups[0]['lr']
    lr_history.append(current_lr)

    # 更新学习率
    scheduler.step()

# 绘制学习率变化曲线
plt.plot(range(120), lr_history, label="learning rate")
plt.xlabel("epochs")
plt.ylabel("learning rate")
plt.legend()
plt.show()

最后一个余弦退火学习率衰减CosineAnnealingLR

CosineAnnealingLR是余弦退火学习率,T_max是周期的一半,最大学习率在optimizer中指定,最小学习率为eta_min。这里同样能够帮助逃离鞍点。值得注意的是最大学习率不宜太大,否则loss可能出现和学习率相似周期的上下剧烈波动。

基本上的选择方式是选择1/4个余弦函数的周期。

可视化:

这里官方文档的公式说明讲的很清晰,自行学习吧: 

Parameters 参数

  • optimizer (Optimizer) - 包装优化器。

  • T_max (int) - 最大迭代次数。

  • eta_min (float) - 最低学习率。默认值:0。

  • last_epoch (int) - 上一个纪元的索引。默认值:-1。

  • verbose (bool) – 如果 True ,则在每次更新时向 stdout 打印一条消息。默认值: False .

今天的学习就到这里,散会!

ps:最近心情有点糟糕,六级+期末考试+实验出了些问题,好累,今晚好好睡一觉吧,晚安各位。

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【资源介绍】 基于python实现两层神经网络分类器用于手写数字识别源码+使用说明(深度学习课程作业).zip 该项目是个人课程作业项目,答辩评审分达到95分,代码都经过调试测试,确保可以运行!欢迎下载使用,可用于小白学习、进阶。 该资源主要针对计算机、通信、人工智能、自动化等相关专业的学生、老师或从业者下载使用,亦可作为期末课程设计、课程大作业、毕业设计等。 项目整体具有较高的学习借鉴价值!基础能力强的可以在此基础上修改调整,以实现不同的功能。 神经网络与深度学习课程作业1:一个进行手写数字识别的两层神经网络分类器 这是一个使用NumPy构建的简单两层神经网络分类器,用于分类MNIST数据集。 这里分为三部分:训练、参数查找和测试。 1. 训练 - 首先定义了sigmoid函数和softmax函数用做激活函数,并且计算了激活函数的梯度。然后利用L2正则化定义了loss函数 - 利用反向传播算法计算梯度,进行了具体推导和代码实现 - 学习率下降策略使用指数衰减:每经过epochs个epoch后学习率乘以一个衰减率decay_rate,通过实际训练最后确定epochs=100,decay_rate=0.9可以得到较好的效果 - 具体实现模型训练,其中采用SGD优化器,随机选取batch_size个样本计算梯度,更新参数。 - 保存模型参数到文件“params.npz” 2. 超参数查找: - 通过网格搜索,大致搜寻合适的学习率、隐藏层大小、正则化强度和batch_size - 学习率设置[0,001,0.01,0.1] - 隐藏层设置[50,100,200] - 正则化强度设置[0.0001,0.001,0.01] - batch_sizes设置[64,128,256] - 由于SGD优化存在一定随机性,所以每次训练过程采用五折交叉验证,四份当训练集,一份当测试集,取五次准确率的平均值作为对应参数所相应的准确率 - 最后基于寻找到的合适超参数,根据发现规律进行微调,得到一个最佳的参数结果,并进行训练,得到模型并存储,绘制loss和accuracy曲线,并可视化每层网络参数 3. 测试: 导入模型,用经过参数查找后的模型进行测试,输出分类精度 homewrok_network2.ipynb:包含完整构建过程,包含代码以及输出结果 hyperparameter_selection.json:包含模型利用网格搜索时的输出结果 params_best.npz:最优模型参数 notebook上运行,自建的两层神经网络实现的。 notebook上运行,自建的两层神经网络实现的。 notebook上运行,自建的两层神经网络实现的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值