目录
什么是学习率?
有哪些影响因素?
常用调整方法?
博主介绍:✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉着互联网精神开源贡献精神,答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有需要可以联系作者我哦!
🍅文末三连哦🍅
👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟
一、什么是学习率?
深度学习中的学习率(Learning Rate)是一个至关重要的超参数,它决定了模型在训练过程中更新权重参数的速度与方向。在使用梯度下降法(Gradient Descent)或其变种(如随机梯度下降,Stochastic Gradient Descent, SGD)优化模型时,学习率扮演着核心角色。
具体来说,在每次迭代过程中,模型计算损失函数关于各个参数的梯度,这个梯度指示了参数应当朝着哪个方向调整以最小化损失。学习率就是这个调整过程中的“步伐”大小,即参数更新的量。数学表达式通常是这样的:
其中:
是在时间步 时模型的参数。
是学习率。
是在当前参数下损失函数 关于参数的梯度。
如果学习率设置得过大,那么在每一步迭代中,模型参数可能会跨过最优解,导致震荡或者发散,这被称为“振荡现象”或“不稳定性”。相反,如果学习率设置得太小,模型收敛到最优解的速度将会非常慢,而且可能会陷入局部极小点,而不是全局最优解。
二、有哪些常见的影响因素?
-
问题的复杂度:问题的复杂度反映了模型在训练过程中需要调整的参数数量和模型的复杂度。通常情况下,更复杂的问题需要更小的学习率来确保模型的稳定性和收敛性。
-
数据集的大小:数据集的大小直接影响了模型训练的稳定性和泛化能力。对于较大的数据集,通常可以使用较大的学习率来加快收敛速度;而对于较小的数据集,则需要使用较小的学习率以避免过拟合。
-
学习率的初始值:学习率的初始值对模型的训练过程和性能有重要影响。选择合适的初始学习率是一个关键的调参过程,通常需要进行实验和调整来找到最佳的初始学习率。
-
优化算法的选择:不同的优化算法对学习率的敏感度不同。一些优化算法(如Adam、Adagrad等)具有自适应学习率调整的能力,可以在训练过程中动态地调整学习率,而另一些算法(如SGD)则需要手动调整学习率。
-
学习率衰减策略:学习率衰减策略决定了学习率在训练过程中的变化方式。合适的学习率衰减策略可以提高模型的训练稳定性和泛化能力,对于长时间的训练任务尤为重要。
-
初始参数值:初始参数值对于模型的训练过程和学习率的选择也有影响。不同的初始参数值可能会导致模型在训练过程中出现不同的收敛速度和性能。
-
训练数据的分布:训练数据的分布对模型的训练过程和学习率的选择有直接影响。如果训练数据是非平稳的或者存在类别不平衡的情况,可能需要采用不同的学习率调整策略来保证模型的训练效果。
-
模型架构的选择:不同的模型架构对于学习率的选择和训练过程的稳定性有不同的要求。一些复杂的模型架构可能需要更小的学习率和更复杂的优化算法来进行训练。
三、常用调整方法?
1、固定学习率
这是最简单的学习率调整方法,即在整个训练过程中保持学习率不变。这种方法的优点是简单直观,但缺点是可能无法很好地适应不同阶段的训练过程,导致训练过程不稳定或收敛速度过慢。 如0.1、0.01、0.001等。
2. 学习率衰减(Learning Rate Decay)
学习率衰减是一种常用的学习率调整方法,它随着训练的进行逐渐减小学习率,以提高模型训练的稳定性和泛化能力。常见的学习率衰减方法包括:
指数衰减(Exponential Decay):学习率按指数函数衰减,如 ,其中 是初始学习率,是衰减率,是训练的迭代次数。
initial_learning_rate = 0.1
gamma = 0.95 # 衰减率
decay_steps = 100 # 每多少步衰减一次
learning_rate = initial_learning_rate * gamma ** (step / decay_steps)
# 或者在PyTorch中使用内置scheduler
scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=gamma)
余弦衰减(Cosine Decay):学习率按余弦函数衰减,即 ,其中 是初始学习率,是衰减周期,是当前迭代次数。
initial_learning_rate = 0.1
total_epochs = 100
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=total_epochs, eta_min=0)
# 或者使用带有余弦重启的版本
scheduler = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizer, T_0=total_epochs // 2)
线性衰减(Linear Decay):学习率按线性函数衰减,如,其中 是初始学习率,是衰减率,是训练的迭代次数。
class LinearDecayScheduler(torch.optim.lr_scheduler._LRScheduler):
def __init__(self, optimizer, initial_lr, decay_rate, total_iters):
self.decay_rate = decay_rate
self.total_iters = total_iters
super().__init__(optimizer, last_epoch=-1)
def get_lr(self):
current_iter = self.last_epoch + 1 # PyTorch的last_epoch从0开始计数
lr = self.base_lrs[0] - (self.base_lrs[0] * self.decay_rate * (current_iter / self.total_iters))
return [lr for _ in self.base_lrs]
# 使用示例
optimizer = optim.SGD(model.parameters(), lr=initial_lr)
scheduler = LinearDecayScheduler(optimizer, initial_lr, decay_rate, total_iters)
# 在训练循环中调用scheduler.step()以更新学习率
for epoch in range(num_epochs):
for iter in range(num_iters_per_epoch):
scheduler.step()
# ... 训练步骤 ...
3、自适应学习率算法
自适应学习率算法是一类可以自动调整学习率的优化算法,它们根据参数的梯度信息动态地调整学习率。常见的自适应学习率算法包括:
- Adam(Adaptive Moment Estimation)
- Adagrad(Adaptive Gradient Algorithm)
- RMSProp(Root Mean Square Propagation)
- Adadelta(Adaptive Delta) 这些算法通过考虑历史梯度信息或者自适应地调整学习率的大小来提高模型训练的效率和性能。
Adam算法:
Adam(Adaptive Moment Estimation)是一种自适应学习率算法,结合了动量(Momentum)和自适应学习率调整机制,能够在不同参数的梯度变化范围内自适应地调整学习率,从而提高模型的训练速度和性能。
下面是Adam算法的公式:
1. 初始化参数:
- 和分别为零向量,与模型参数形状相同
- 和 是动量和梯度平方的指数衰减率
- 是学习率
- 是一个很小的数,避免除以零2. 在每个迭代步骤中,对每个参数做如下更新:
- 计算梯度
- 更新一阶矩估计:
- 更新二阶矩估计:
- 矫正一阶矩估计:
- 矫正二阶矩估计:
- 更新参数:
Python代码示例,实现了Adam算法的应用:
import numpy as np
class AdamOptimizer:
def __init__(self, learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8):
self.learning_rate = learning_rate
self.beta1 = beta1
self.beta2 = beta2
self.epsilon = epsilon
self.m = None
self.v = None
self.t = 0
def update(self, parameters, gradients):
if self.m is None:
self.m = np.zeros_like(parameters)
self.v = np.zeros_like(parameters)
self.t += 1
self.m = self.beta1 * self.m + (1 - self.beta1) * gradients
self.v = self.beta2 * self.v + (1 - self.beta2) * (gradients ** 2)
m_hat = self.m / (1 - self.beta1 ** self.t)
v_hat = self.v / (1 - self.beta2 ** self.t)
parameters -= self.learning_rate * m_hat / (np.sqrt(v_hat) + self.epsilon)
# 使用示例
# 初始化优化器
optimizer = AdamOptimizer(learning_rate=0.001)
# 定义模型参数和梯度
parameters = np.random.randn(10)
gradients = np.random.randn(10)
# 更新参数
optimizer.update(parameters, gradients)
Adagrad算法:
Adagrad(Adaptive Gradient Algorithm),它能够根据每个参数的历史梯度信息自适应地调整学习率。Adagrad会为每个参数维护一个学习率,使得在训练过程中,梯度较大的参数拥有较小的学习率,而梯度较小的参数拥有较大的学习率,从而更好地适应不同参数的更新需求。
以下是Adagrad算法的主要步骤:
1. 初始化参数:
- 初始化参数 为随机值
- 初始化梯度累积变量 为零向量,与参数 形状相同
- 初始化全局学习率
- 初始化一个很小的常数 ,避免除以零2. 在每个迭代步骤 中,对每个参数 做如下更新:
- 计算梯度
- 将梯度的平方累积到 中:
- 计算参数的学习率:
- 更新参数:
Adagrad的特点是随着训练的进行,由于 中累积了梯度的平方值,学习率会逐渐减小,从而保证了模型在训练过程中的稳定性和收敛性。
Python代码示例,实现了Adagrad算法的应用:
import numpy as np
class AdagradOptimizer:
def __init__(self, learning_rate=0.01, epsilon=1e-8):
self.learning_rate = learning_rate
self.epsilon = epsilon
self.r = None
def update(self, parameters, gradients):
if self.r is None:
self.r = np.zeros_like(parameters)
self.r += gradients ** 2
lr = self.learning_rate / (np.sqrt(self.r) + self.epsilon)
parameters -= lr * gradients
# 使用示例
# 初始化优化器
optimizer = AdagradOptimizer(learning_rate=0.01)
# 定义模型参数和梯度
parameters = np.random.randn(10)
gradients = np.random.randn(10)
# 更新参数
optimizer.update(parameters, gradients)
RMSProp算法:
RMSProp(Root Mean Square Propagation),它对Adagrad算法进行了改进,解决了Adagrad算法在训练过程中学习率不断减小的问题。RMSProp算法通过使用梯度平方的移动平均来调整学习率,从而实现了对学习率的自适应调整,使得模型的训练更加稳定和高效。
以下是RMSProp算法的主要步骤:
1. 初始化参数:
- 初始化参数为随机值
- 初始化梯度平方的指数加权移动平均变量为零向量,与参数 形状相同
- 初始化全局学习率
- 初始化一个很小的常数,避免除以零2. 在每个迭代步骤 中,对每个参数 做如下更新:
- 计算梯度
- 将梯度的平方累积到 $v$ 中:,其中是一个衰减率,通常取0.9
- 计算参数的学习率:
- 更新参数:
RMSProp算法通过使用梯度平方的指数加权移动平均来调整学习率,使得学习率的调整更加平滑,从而提高了模型训练的稳定性和泛化能力。
Python代码示例,实现了RMSProp算法的应用:
class RMSPropOptimizer:
def __init__(self, learning_rate=0.01, beta=0.9, epsilon=1e-8):
self.learning_rate = learning_rate
self.beta = beta
self.epsilon = epsilon
self.v = None
def update(self, parameters, gradients):
if self.v is None:
self.v = np.zeros_like(parameters)
self.v = self.beta * self.v + (1 - self.beta) * (gradients ** 2)
lr = self.learning_rate / (np.sqrt(self.v) + self.epsilon)
parameters -= lr * gradients
# 使用示例
# 初始化优化器
optimizer = RMSPropOptimizer(learning_rate=0.01)
# 定义模型参数和梯度
parameters = np.random.randn(10)
gradients = np.random.randn(10)
# 更新参数
optimizer.update(parameters, gradients)
Adadelta算法 :
Adadelta是对RMSProp算法的改进。与RMSProp不同的是,Adadelta算法不需要手动设置一个全局学习率,而是使用了一个更加简洁的学习率调整策略,使得模型训练过程更加稳定和高效。
以下是Adadelta算法的主要步骤:
1. 初始化参数:
- 初始化参数为随机值
- 初始化梯度平方的指数加权移动平均变量为零向量,与参数 形状相同
- 初始化更新量的指数加权移动平均变量 为零向量,与参数 形状相同
- 初始化一个很小的常数,避免除以零
- 初始化一个很小的常数 ,用于控制更新量的调整幅度,通常取0.92. 在每个迭代步骤中,对每个参数 做如下更新:
- 计算梯度
- 将梯度的平方累积到 中:
- 计算参数的更新量:
- 将更新量的平方累积到 中:
- 更新参数:
Adadelta算法通过使用更新量的指数加权移动平均来调整学习率,使得学习率的调整更加平滑,从而提高了模型训练的稳定性和泛化能力。
Python代码示例,实现了Adadelta算法的应用:
class AdadeltaOptimizer:
def __init__(self, gamma=0.9, epsilon=1e-8):
self.gamma = gamma
self.epsilon = epsilon
self.v = None
self.s = None
def update(self, parameters, gradients):
if self.v is None:
self.v = np.zeros_like(parameters)
self.s = np.zeros_like(parameters)
self.v = self.gamma * self.v + (1 - self.gamma) * (gradients ** 2)
delta_theta = - np.sqrt(self.s + self.epsilon) / np.sqrt(self.v + self.epsilon) * gradients
self.s = self.gamma * self.s + (1 - self.gamma) * (delta_theta ** 2)
parameters += delta_theta
# 使用示例
# 初始化优化器
optimizer = AdadeltaOptimizer()
# 定义模型参数和梯度
parameters = np.random.randn(10)
gradients = np.random.randn(10)
# 更新参数
optimizer.update(parameters, gradients)
4、多项式衰减(Polynomial Decay)
多项式衰减(Polynomial Decay)是一种学习率调整策略,通过多项式函数对学习率进行衰减,从而在训练过程中逐渐降低学习率。多项式衰减通常用于训练过程中的学习率衰减策略之一,可以帮助模型在训练后期更好地收敛,并提高模型的泛化能力。
多项式衰减的公式通常表示为:
其中:
- 是当前迭代步骤的学习率;
- 是初始学习率;
- 是当前迭代步骤;
- 是总的迭代次数;
- 是多项式衰减的指数,控制衰减的速率。
多项式衰减策略通过调整指数 的大小来控制学习率的衰减速率。当时,学习率将以多项式函数形式缓慢衰减;当时,学习率以线性方式衰减;当时,学习率将以多项式函数形式快速衰减。
Python代码示例,演示了如何实现多项式衰减策略:
def polynomial_decay(initial_learning_rate, current_step, decay_steps, power):
"""
多项式衰减函数
Args:
- initial_learning_rate: 初始学习率
- current_step: 当前迭代步骤
- decay_steps: 衰减步数
- power: 多项式衰减的指数
Returns:
- 当前迭代步骤的学习率
"""
return initial_learning_rate * (1 - current_step / decay_steps) ** power
# 使用示例
initial_learning_rate = 0.01
decay_steps = 1000
power = 0.5
for step in range(1, 1001):
current_learning_rate = polynomial_decay(initial_learning_rate, step, decay_steps, power)
print("Step {}: Learning Rate = {:.6f}".format(step, current_learning_rate))
总结
学习率作为深度学习模型训练过程中的关键调控变量,其重要性不言而喻。在今天的讨论中,我们深入剖析了学习率的概念及其在优化算法中的作用机制。学习率代表了参数更新的步伐大小,直接影响模型收敛的速度和结果的质量。当学习率设定过高时,可能导致模型在寻找最优解的过程中产生剧烈振荡,甚至无法收敛;反之,过低的学习率虽能确保稳定性,却会导致收敛速度过于缓慢,浪费大量计算资源。
针对这一问题,我们探讨了多种动态调整学习率的方法。首先,介绍了传统固定学习率之外的指数衰减、多项式衰减以及步长衰减等策略、还有自适应学习率方法如AdaGrad、RMSprop和Adam因其能够根据各参数的历史梯度信息自动调整学习率而备受青睐,它们有效地解决了传统学习率调整方法存在的诸多局限性。