长春网络建站模板,在线设计发型,宿迁网络推广公司,邓州市建设局网站本文针深度学习中不同的优化器进行了汇总#xff0c;包括公式实现、代码示例、演变过程和优缺点做了较为详细的分析。
随机梯度下降#xff08;SGD#xff09;
随机梯度下降#xff08;SGD#xff09;是一种简单但极其有效的优化算法#xff0c;经常用于训练各种类型的…本文针深度学习中不同的优化器进行了汇总包括公式实现、代码示例、演变过程和优缺点做了较为详细的分析。
随机梯度下降SGD
随机梯度下降SGD是一种简单但极其有效的优化算法经常用于训练各种类型的机器学习模型特别是大规模数据集上的深度学习模型。SGD 的核心在于每次更新参数时只使用数据集中的一个样本或一小批样本来计算梯度这与传统的批量梯度下降BGD算法相比可以大大加快计算速度并降低内存需求。
提出的契机
在 SGD 被普遍采纳之前批量梯度下降是最常见的优化方法它在每一步都使用整个数据集来计算梯度并更新参数。虽然这种方法理论上可以保证在凸优化问题上收敛到全局最优解但在面对大规模数据集时每次迭代都需要大量的计算资源和时间。SGD 的提出正是为了解决这个问题通过每次只使用一个样本或一小批样本来估计真实梯度从而加速训练过程并使得模型能够在线更新和处理大数据。
理论与公式
SGD 的基本更新公式非常简单
选择初始参数 θ 0 \theta_0 θ0 和学习率 η \eta η。在每一次迭代 k k k 中随机选择一个样本 i i i或一小批样本计算该样本上的梯度 g ∇ θ k − 1 L i ( θ ) g \nabla_{\theta_{k-1}} L_i(\theta) g∇θk−1Li(θ) 其中 L i ( θ ) L_i(\theta) Li(θ) 是在第 i i i 个样本上的损失函数。更新参数 θ k θ k − 1 − η g \theta_{k} \theta_{k-1} - \eta g θkθk−1−ηg
这里没有 r k r_k rk 的概念因为 SGD 不涉及梯度累积或调整学习率的复杂机制。每次迭代直接使用当前梯度进行参数更新。
代码示例
下面是 SGD 算法的一个简单 Python 代码示例
def sgd_update(parameters, gradients, lr0.01):for param, grad in zip(parameters, gradients):param - lr * grad这个函数接受 parameters模型参数列表gradients对应梯度列表以及 lr学习率作为输入然后使用 SGD 公式更新每个参数。
优缺点
优点
效率高 由于每次只处理一个样本或一小批样本SGD 可以快速完成迭代特别适合大规模数据集。在线学习 SGD 可以用于在线学习场景即模型可以随着新数据的到来实时更新。跳出局部最优 SGD 因为其随机性有可能跳出局部最优找到更好的解。
缺点
收敛问题 由于每次更新只使用一个样本SGD 的收敛过程可能会非常嘈杂导致训练不稳定。超参数调整 学习率等超参数的选择对 SGD 性能有很大影响而且不容易调整。可能不是最优解 在非凸优化问题上SGD 可能只能找到局部最优解而非全局最优解。
总的来说SGD 是一种高效且广泛应用的优化算法尤其适用于大规模数据集。然而其随机性也带来了一些挑战比如可能的训练不稳定
梯度下降 Momentum
动量梯度下降Momentum Gradient Descent是一种优化算法用于训练机器学习模型特别是神经网络模型。它是在标准梯度下降算法的基础上引入了动量概念以解决梯度下降中的一些问题例如局部最小值、鞍点等。 提出背景 动量梯度下降算法的提出是为了解决传统梯度下降算法中的一些问题。
在高度曲折的损失函数表面上的震荡收敛速度缓慢等。 通过引入动量的概念可以在一定程度上加速收敛并且有助于跳出局部最小值。
理论
动量梯度下降的核心思想是引入动量因子使得更新方向不仅取决于当前梯度还考虑了之前更新方向的影响。这样可以在一定程度上平滑更新路径加速收敛。
公式
While 条件 g ← ∇ θ k − 1 L ( θ ) g \leftarrow \nabla_{\theta_{k-1}} L(\theta) g←∇θk−1L(θ) # 计算梯度 w k α w k − 1 ( 1 − α ) g w_k \alpha w_{k-1} (1 - \alpha) g wkαwk−1(1−α)g # 计算动量 θ k θ k − 1 − η w k \theta_{k} \theta_{k-1} - \eta w_k θkθk−1−ηwk # 更新参数
其中 θ k − 1 \theta_{k-1} θk−1是第k-1步的模型参数向量。 ∇ L ( θ k − 1 ) \nabla L(\theta_{k-1}) ∇L(θk−1) 是损失函数 L L L 对参数 θ k − 1 \theta_{k-1} θk−1 的梯度。 η \eta η是学习率。 α \alpha α是动量参数通常取值在 0 到 1 之间决定了历史梯度对当前更新的影响程度。 w k w_k wk是动量表示历史梯度的加权累积。
代码示例
下面是一个简单的 Python 代码示例演示了如何使用动量梯度下降算法来训练一个简单的线性回归模型
import numpy as npdef momentum_gradient_descent(params, grads, velocities, lr0.01, momentum0.9):for param, grad, velocity in zip(params, grads, velocities):velocity[:] momentum * velocity lr * gradparam[:] - velocity优缺点
优点
加速收敛动量可以帮助加速SGD在相关方向上的收敛并抑制振荡使得训练过程更快。降低震荡通过平滑梯度动量方法可以减少训练过程中的震荡使得更新过程更稳定。逃离局部最小动量的累积可以帮助算法跳出局部最小值。
缺点
超参数敏感动量系数的选择对算法的性能影响很大需要仔细调整。可能错过最小值过大的动量可能会导致算法在最小值附近“冲过头”从而错过最优解。
Adagrad
AdaGradAdaptive Gradient Algorithm是一种自适应学习率的梯度下降算法于2011年由Duchi等人提出。这个算法主要是为了解决标准的梯度下降算法中学习率一成不变的问题。在标准的梯度下降算法中如果学习率过大可能会导致算法在最小值附近震荡而不收敛如果学习率过小又会导致收敛速度过慢。AdaGrad算法通过自适应调整每个参数的学习率尝试解决这个问题。
理论和公式
AdaGrad算法的核心思想是对每个参数根据其历史梯度的平方和进行自适应地调整学习率。这意味着对于出现频率高的特征其学习率会较低而对于出现频率低的特征其学习率会较高。这种方式使得模型在稀疏数据上的表现更好。
AdaGrad的参数更新公式如下 while 条件: g ∇ θ k − 1 L ( θ ) g \nabla_{\theta_{k-1}} L(\theta) g∇θk−1L(θ) r k r k − 1 g ⊙ g r_{k} r_{k-1} g \odot g rkrk−1g⊙g η η r k ϵ \eta \frac{\eta}{\sqrt{r_{k} \epsilon}} ηrkϵ η θ k θ − η g \theta_{k} \theta - \eta g θkθ−ηg g ∇ θ k − 1 L ( θ ) g \nabla_{\theta_{k-1}} L(\theta) g∇θk−1L(θ): g g g代表损失函数 L ( θ ) L(\theta) L(θ)关于参数 θ \theta θ在 θ k − 1 \theta_{k-1} θk−1点的梯度其中 ∇ θ \nabla_{\theta} ∇θ表示梯度运算符 θ k − 1 \theta_{k-1} θk−1表示上一步的参数值。 r k r k − 1 g ⊙ g r_{k} r_{k-1} g \odot g rkrk−1g⊙g: r k r_{k} rk代表到当前迭代为止所有梯度平方的累积和 ⊙ \odot ⊙表示元素乘法即Hadamard乘积。这里 r k r_{k} rk用于调整学习率以适应不同参数的不同梯度值。 η η r k ϵ \eta \frac{\eta}{\sqrt{r_{k} \epsilon}} ηrkϵ η: 这里通过累积梯度平方和 r k r_{k} rk来调整学习率 η \eta η。 ϵ \epsilon ϵ是一个很小的常数用于防止分母为零。这样的调整使得学习率对于出现频繁的特征会更小而对于稀疏特征会更大有助于提高模型在稀疏数据上的性能。 θ k θ − η g \theta_{k} \theta - \eta g θkθ−ηg: 这是参数更新的步骤新的参数 θ k \theta_{k} θk通过从当前参数 θ \theta θ减去学习率 η \eta η乘以梯度 g g g来计算。这一步是基于梯度下降算法的目的是减少损失函数 L ( θ ) L(\theta) L(θ)的值。
代码示例
一个简单的AdaGrad算法的Python代码示例如下
import numpy as np# AdaGrad optimizer functiondef adagrad_optimizer(grad, params, sqr_grads, learning_rate0.01, epsilon1e-8):sqr_grads grad ** 2adjusted_grad grad / (np.sqrt(sqr_grads) epsilon)params - learning_rate * adjusted_grad# Example usageparams np.array([1.0, 2.0]) # Initial parameters
grads np.array([0.2, -0.3]) # Example gradients
sqr_grads np.zeros_like(params) # Initialize square gradients sumadagrad_optimizer(grads, params, sqr_grads)
print(params) # Updated parameters优缺点
优点
自适应学习率对于每个参数AdaGrad根据其历史梯度的平方和自适应调整学习率减少了手动调节学习率的需要。适用于稀疏数据对于稀疏特征AdaGrad能够自动提高其学习率使得模型更快地学习到这些特征的重要性。
缺点
学习率持续衰减由于累积的平方梯度持续增加学习率会持续衰减最终导致学习率过小从而使得训练后期模型难以收敛。存储梯度平方和需要为每个参数存储一个累积的梯度平方和这在参数很多时会增加额外的内存开销。
AdaGrad算法在处理稀疏数据和不同频率特征的调整上具有优势但在长期训练中可能会遇到学习率过小的问题。为了克服这个问题后续研究者提出了AdaGrad的改进版本如RMSProp和Adam这些算法在各种机器学习任务中得到了广泛的应用。
RMSProp
RMSPropRoot Mean Square Propagation是一种自适应学习率的优化算法主要用于深度学习中的参数更新。旨在解决 Adagrad 算法在深度学习训练过程中学习率逐渐减小直至无法进一步学习的问题。
提出的契机
Adagrad 算法通过累积历史梯度的平方来调整每个参数的学习率从而实现对频繁更新参数的惩罚和对不频繁更新参数的鼓励。然而Adagrad 也存在一个问题随着参数更新的累积学习率会越来越小最终导致学习过程提前结束。RMSProp 通过引入一个衰减系数来解决这个问题使得历史信息能够指数级衰减从而避免了学习率持续下降的问题。
理论与公式
RMSProp 的核心思想是对每个参数使用不同的学习率这些学习率是根据参数的最近梯度大小自适应调整的。具体来说RMSProp 使用平方梯度的指数加权移动平均来调整学习率从而使得学习率的调整更加平滑。
修改后的公式如下
While 条件 g ∇ θ k − 1 L ( θ ) g \nabla_{\theta_{k-1}} L(\theta) g∇θk−1L(θ) r k β r k − 1 ( 1 − β ) g ⊙ g r_{k} \beta r_{k-1} (1 - \beta) g \odot g rkβrk−1(1−β)g⊙g η η r k ϵ \eta \frac{\eta}{\sqrt{r_{k} \epsilon}} ηrkϵ η θ k θ k − 1 − η g \theta_{k} \theta_{k-1} - \eta g θkθk−1−ηg
其中 ⊙ \odot ⊙ 表示元素乘积 β \beta β 是衰减系数通常设置为 0.9用于控制历史信息的衰减速度 ϵ \epsilon ϵ 是为了避免除以 0 的小常数通常设置为 1 e − 8 1e-8 1e−8。
代码示例
下面是一个简单的 RMSProp 更新规则的 Python 代码示例
def rmsprop_update(parameters, gradients, sq_grads, lr0.01, beta0.9, epsilon1e-8):for param, grad in zip(parameters, gradients):sq_grads[param] beta * sq_grads[param] (1 - beta) * (grad ** 2)param_update lr / (np.sqrt(sq_grads[param]) epsilon) * gradparam - param_update在这个函数中parameters 是模型参数列表gradients 是对应的梯度列表sq_grads 是历史梯度平方的累积需要初始化lr 是学习率beta 和 epsilon 是 RMSProp 算法的超参数。
优缺点
优点
自适应学习率调整 RMSProp 通过考虑最近的梯度大小来自适应地调整每个参数的学习率避免了全局学习率带来的一些问题。解决了 Adagrad 的缺陷 通过引入衰减因子解决了 Adagrad 学习率持续下降直至消失的问题。
缺点
超参数依赖 RMSProp 的效果在很大程度上依赖于衰减因子等超参数的选择。可能不适合所有问题 尽管 RMSProp 在许多深度学习问题中表现良好但它并不保证在所有问题上都是最优的。
RMSProp 是一种强大的优化算法特别适合处理非凸优化和深度学习中的大规模问题。然而正如任何算法一样理解其工作原理和局限性对于有效地应用它至关重要。
Adam
AdamAdaptive Moment Estimation是一种广泛使用的深度学习优化算法由 Diederik P. Kingma 和 Jimmy Ba 在 2014 年提出。它结合了动量法Momentum和 RMSProp 的思想旨在通过计算梯度的一阶矩估计和二阶矩估计来调整每个参数的学习率从而实现更高效的网络训练。
提出的契机
在 Adam 提出之前研究者们已经在使用像 Momentum 和 RMSProp 这样的优化算法来加速深度神经网络的训练过程。然而这些算法各有优势和局限。Momentum 善于处理梯度的方向和大小而 RMSProp 善于调整学习率以应对数据的稀疏性。Adam 的提出是为了结合这两种算法的优点同时减少它们的缺点提供一种更加鲁棒的优化解决方案。
理论与公式
Adam 算法的关键在于同时计算梯度的一阶矩均值和二阶矩未中心的方差的指数移动平均并对它们进行偏差校正以确保在训练初期时梯度估计不会偏向于 0。
算法的更新规则如下
While 条件 g ∇ θ k − 1 L ( θ ) g \nabla_{\theta_{k-1}} L(\theta) g∇θk−1L(θ) m k β 1 m k − 1 ( 1 − β 1 ) g m_{k} \beta_1 m_{k-1} (1 - \beta_1) g mkβ1mk−1(1−β1)g v k β 2 v k − 1 ( 1 − β 2 ) g ⊙ g v_{k} \beta_2 v_{k-1} (1 - \beta_2) g \odot g vkβ2vk−1(1−β2)g⊙g m ^ k m k 1 − β 1 k \hat{m}_{k} \frac{m_{k}}{1 - \beta_1^k} m^k1−β1kmk v ^ k v k 1 − β 2 k \hat{v}_{k} \frac{v_{k}}{1 - \beta_2^k} v^k1−β2kvk θ k θ k − 1 − η v ^ k ϵ m ^ k \theta_{k} \theta_{k-1} - \frac{\eta}{\sqrt{\hat{v}_{k}} \epsilon} \hat{m}_{k} θkθk−1−v^k ϵηm^k
其中 m k m_{k} mk 和 v k v_{k} vk 分别是梯度的一阶矩和二阶矩的估计 β 1 \beta_1 β1 和 β 2 \beta_2 β2 是控制这两个矩估计的指数衰减率通常设置为 0.9 和 0.999。 ϵ \epsilon ϵ是一个非常小的数例如1e-8防止除以零。 k是当前迭代次数用于做偏差校正。 β 1 k β 1 × β 1 × … × β 1 \beta_1^k \beta_1 \times \beta_1 \times \ldots \times \beta_1 β1kβ1×β1×…×β1 共乘以 k k k 次 β 2 k β 2 × β 2 × … × β 2 \beta_2^k \beta_2 \times \beta_2 \times \ldots \times \beta_2 β2kβ2×β2×…×β2 共乘以 k k k 次
在 Adam 优化算法中 β 1 k \beta_1^k β1k 和 β 2 k \beta_2^k β2k 用于进行偏差校正bias correction。这是因为在算法的初期由于 m k m_k mk 和 v k v_k vk分别是梯度的一阶矩和二阶矩的估计是从 0 开始初始化的会导致它们在初始阶段被低估。特别是当 β 1 \beta_1 β1 和 β 2 \beta_2 β2 接近 1 时这个偏差会更加显著。为了补偿这种估计的偏差Adam 算法引入了偏差校正步骤。
偏差校正的作用 对 m k m_k mk的偏差校正 初始时刻一阶矩 m k m_k mk 的值偏小因为它是梯度值的加权平均起始所有梯度都被初始化为 0。通过除以 1 − β 1 k 1 - \beta_1^k 1−β1k可以将 m k m_k mk 的值放大使其更快地接近实际的梯度均值。随着迭代次数 k k k的增加 β 1 k \beta_1^k β1k 会趋向于 0偏差校正因子 1 − β 1 k 1 - \beta_1^k 1−β1k 就会趋向于 1偏差校正的影响会逐渐减小。 对 v k v_k vk 的偏差校正 类似地二阶矩 v k v_k vk梯度平方的加权平均也会在初始阶段被低估。通过除以 1 − β 2 k 1 - \beta_2^k 1−β2k可以增加 v k v_k vk 的值使其更接近实际的梯度平方的均值。随着 k k k 的增加偏差校正因子 1 − β 2 k 1 - \beta_2^k 1−β2k 也会趋向于 1。
偏差校正的重要性
偏差校正对于 Adam 算法的性能至关重要特别是在训练的初期阶段。没有偏差校正算法可能会因为初始的低估而导致学习步长太小进而影响训练的速度和效果。通过偏差校正Adam 算法可以更快地调整其参数更新的大小加速初期的学习过程并提高整体的优化效率。随着训练的进行这种校正变得不那么重要因为 m k m_k mk 和 v k v_k vk 会逐渐积累足够的信息来准确估计梯度的一阶和二阶矩。
代码示例
以下是 Adam 优化算法的 Python 代码示例
def adam_update(parameters, gradients, m, v, t, lr0.001, beta10.9, beta20.999, epsilon1e-8):for param, grad in zip(parameters, gradients):m[param] beta1 * m[param] (1 - beta1) * gradv[param] beta2 * v[param] (1 - beta2) * (grad ** 2)m_corrected m[param] / (1 - beta1 ** t)v_corrected v[param] / (1 - beta2 ** t)param_update lr * m_corrected / (np.sqrt(v_corrected) epsilon)param - param_update这个函数中parameters 和 gradients 分别是模型参数和梯度的列表m 和 v 是梯度一阶和二阶矩的估计t 是当前迭代次数lr, beta1, beta2, epsilon 是 Adam 算法的超参数。
优缺点
优点
自适应学习率 Adam 通过计算一阶和二阶矩估计来为每个参数自适应地调整学习率。偏差校正 初始阶段梯度估计可能偏低通过偏差校正可以加速初期的学习速率。适应性强 Adam 在很多不同的模型和数据集上都表现出了良好的性能。
缺点
超参数调整 尽管默认的超参数在很多情况下都表现良好但某些问题可能需要仔细的超参数调整。内存需求 相对于一些简单的优化算法Adam 需要存储更多的变量例如一阶和二阶矩估计这可能会增加计算资源的消耗。
Adam 由于其优秀的性能和适应性已经成为深度学习领域中最受欢迎的优化算法之一。理解其工作原理对于有效利用这一工具至关重要。