在深度学习中,有一个“损失loss”的概念,它告诉我们:模型在训练数据中表现的“多差”。
现在,我们需要利用这个损失来训练我们的网络,使其表现得更好。本质上,我们需要做的是利用损失并尝试将其最小化,因为较低的损失意味着我们的模型将会表现得更好。最小化(或最大化)任何数学表达式的这个过程被称为优化。
用一张图理解全局最小化和局部最小化:
优化器是用于改变神经网络属性(例如权重和学习率)的算法或方法,以减少损失。优化器通过最小化函数来解决优化问题。
为了更好地理解优化器的作用,可以想象一个蒙着眼睛的登山者试图走下一座山。无法确切知道他该往哪个方向走,但他能判断自己是在下山(取得进展)还是在上山(失去进展)。只要他一直朝着下山的方向前进,最终就能到达山脚。
同样,在训练神经网络时,我们无法从一开始就确定模型的权重应该是什么,但可以通过基于损失函数的不断调整(类似于判断登山者是否在下山)来逐步接近目标。
优化器的作用就在于此: 它决定了如何调整神经网络的权重和学习率以减少损失。优化算法通过不断优化损失函数,帮助模型尽可能地输出准确的结果。
列举9种不同类型的优化器以及它们是如何精确地工作以最小化损失函数的。
梯度下降(Gradient Descent)是一种优化算法,用于寻找可微函数的局部最小值。其目标是通过迭代调整模型参数,最小化代价函数(Cost Function)。以下是梯度下降算法的基本思想:
到底什么是梯度?
"A gradient measures how much the output of a function changes if you change the inputs a little bit." — Lex Fridman (MIT)
梯度下降的核心思想是:沿着梯度的反方向(即函数下降最快的方向)调整参数。
\theta = \theta - \alpha \cdot \nabla J(\theta)
$$
其中:
重复计算梯度和更新参数的过程,直到满足终止条件(如收敛或达到最大迭代次数)。
通过图像的形式描述不同学习率的过程:
可以看到学习率不能过大或过小。
for i in range(nb_epochs):
params_grad = evaluate_gradient(loss_function, data, params)
params = params - learning_rate * params_grad
Advantages:
Disadvantages:
随机梯度下降(SGD)是一种优化算法,用于在训练机器学习模型时最小化损失函数。它是梯度下降算法的一种扩展,通过每次只使用一个训练样本(或少量样本)来计算梯度,从而减少计算量和内存需求。
目标:通过迭代更新模型参数,最小化损失函数 J(θ)。
方法:每次只使用一个训练样本 (x(i),y(i)) 来计算梯度,并更新参数。
在SGD算法中,每次只取一个数据点来计算导数。
SGD(随机梯度下降)针对每个训练样本 x(i) 和对应的标签 y(i) 进行参数更新。
θ = θ − α⋅∂(J(θ;x(i),y(i)))/∂θ
对比随机梯度下降SGD和梯度下降GD:
在左边,随机梯度下降(SGD,其中每步 m=1)为每个样本进行一次梯度下降步骤;而在右边是完整的梯度下降(每整个训练集进行1次步骤)。
观察结果表明,在SGD中,更新需要比梯度下降更多的迭代次数才能到达最小值。在右边,梯度下降到达最小值的步数更少,但SGD算法更“嘈杂”,需要更多的迭代次数。
在TensorFlow中的使用:
from tensorflow.keras.optimizers import SGD
optimizer = SGD(learning_rate=0.01, momentum=0.0, nesterov=False
- 初始化参数:
- 随机初始化模型参数 θ。
- 设置学习率 α。
- 迭代更新:
- 对于每个训练样本 (x(i),y(i)):
- 计算损失函数 J(θ) 关于参数 θ 的梯度 ∇J(θ)。
- 更新参数:
- θ=θ−α⋅∇J(θ)
- 重复步骤:
重复上述过程,直到满足终止条件(如收敛或达到最大迭代次数)。
Advantages:
Disadvantages:
随机梯度下降(SGD)通过每次只处理一个样本,减少了计算量和内存需求,同时保持了快速的参数更新能力。
虽然存在一定的噪声和收敛速度较慢的问题,但通过适当的调整学习率和优化策略,SGD在许多实际应用中表现出色。
小批量随机梯度下降(Mini Batch Stochastic Gradient Descent, MB-SGD)是梯度下降算法的一种改进,结合了批量梯度下降(Batch Gradient Descent)和随机梯度下降(Stochastic Gradient Descent, SGD)的优点。
它通过每次使用一个小批量(Mini-Batch)的数据来计算梯度,从而在计算效率和稳定性之间取得平衡。
目标:通过迭代更新模型参数,最小化损失函数 J(θ)。
方法:每次从训练集中随机抽取一个小批量的数据(通常包含几十个样本),计算该小批量数据的梯度,并更新参数。
将整个训练集划分为若干个小批量,每个小批量包含 m 个样本。
使用mini-batches参数:
for i in range(nb_epochs):
np.random.shuffle(data)
for batch in get_batches(data, batch_size=50):
params_grad = evaluate_gradient(loss_function, batch, params)
params = params - learning_rate * params_grad
Advantages:
Disadvantages::
小批量随机梯度下降(MB-SGD)算法的一个主要缺点是权重更新非常“嘈杂”。带动量的随机梯度下降(SGD with Momentum)通过降噪梯度克服了这一缺点,它在传统的随机梯度下降(SGD)的基础上引入了动量Momentum机制,在每次更新时,通过考虑历史梯度信息来加速收敛并减少噪声。
Advantages:
Disadvantages:
在TensorFlow中的使用:
from tensorflow.keras.optimizers import SGD
optimizer = SGD(learning_rate=0.01, momentum=0.9, nesterov=False)
动量法每下降一步都是由前面下降方向的一个累积和当前点的梯度方向组合而成。于是一位大神(Nesterov)就开始思考,既然每一步都要将两个梯度方向(历史梯度、当前梯度)做一个合并再下降,那为什么不先按照历史梯度往前走那么一小步,按照前面一小步位置的“超前梯度”来做梯度合并呢?
如此一来,小球就可以先不管三七二十一先往前走一步,在靠前一点的位置看到梯度,然后按照那个位置再来修正这一步的梯度方向。如此一来,有了超前的眼光,小球就会更加”聪明“, 这种方法被命名为Nesterov accelerated gradient 简称 NAG
Nesterov Accelerated Gradient(NAG)是一种改进的梯度下降优化算法,它在传统的动量优化算法的基础上引入了“前瞻性”更新机制,从而提高了收敛速度并减少了震荡。
NAG的核心思想是在计算梯度时:
这种方法使得参数更新更加“前瞻”,避免了传统动量方法中可能出现的过冲问题。
记$vt$为第t次迭代梯度的累积:
其中:
在TensorFlow中的使用:
from tensorflow.keras.optimizers import SGD
optimizer = SGD(learning_rate=0.01, momentum=0.9, nesterov=True)
对于之前讨论的所有算法,学习率都是固定的。
Adaptive Gradient(AdaGrad)算法是一种自适应学习率的优化算法,于2011年由Duchi等人提出,它能够根据参数的历史梯度自适应地调整学习率。
AdaGrad的核心思想是对每个参数的学习率进行适应性调整,从而实现对参数的不同历史梯度的平方和进行自适应调整。
具体来说,AdaGrad通过累积过去所有梯度的平方和来为每个参数动态调整学习率,使得较少更新频繁出现的特征参数具有更大的学习率,而较频繁更新的特征参数则具有更小的学习率。
$$
rk = r{k-1} + g \odot g
$$
在第 k 次迭代时,将当前梯度 g 的平方(逐元素相乘)累加到之前的累积梯度平方和 $ r_{k-1} $ 上,得到新的累积梯度平方和 $ r_k $ 。其中,$\odot$表示元素乘法(即Hadamard乘积)。
完整形式:
$$
\thetak = \theta - \frac{\eta_0}{\sqrt{r_k + \epsilon}} * \nabla{\theta_{k-1}} L(\theta)
$$
使用计算出的自适应学习率 $ \eta $ 和梯度 $ g $ 来更新参数 $ \theta $ 到新值 $ \theta_k $ ,目的是减少损失函数 $ L(\theta) $ 的值。
Advantage: 不需要手动更新学习率
Disadvantage:
AdaGrad存在的问题是,随着迭代次数的增加,学习率会变得非常小,这导致收敛速度变慢。为了避免这个问题,AdaDelta算法采用了一种想法,即取梯度的指数衰减平均值。
AdaDelta是Adagrad的一个更稳健的扩展,它根据梯度更新的移动窗口来调整学习率,而不是累积所有过去的梯度。这样,即使进行了很多次更新,AdaDelta也能够继续学习。
AdaDelta算法并没有低效地存储过去的平方梯度,而是将梯度的累积和递归地定义为所有过去平方梯度的衰减平均值。
在时间步 $t$ 的运行平均$Eg^2_t$仅依赖于先前的累积平均值和当前的梯度:
在AdaDelta算法中不需要设置默认的学习率:
Advantage:
Disadvantage:
收敛速度:与一些更新的优化方法(如Adam)相比,AdaDelta可能不会那么快地收敛。
RMSprop(Root Mean Square Propagation)算法是一种自适应学习率的优化算法,由 Geoffrey Hinton 提出,旨在解决梯度下降及其变体在优化过程中学习率固定不变时可能导致的收敛速度慢或不收敛的问题。
RMSprop通过为每个参数动态调整学习率来改进这一点,特别适用于处理非平稳目标函数。
基本原理:
在每次迭代中,计算损失函数 $L(θ)$关于参数$θ$的梯度$g$
使用下面的参数更新参数$\theta$
其中,$ϵ$ 是一个小的正数(例如$10^{−8}$),用于防止除零错误。
Advantage:
Disadvantage:
在机器学习中,Adam(Adaptive Moment Estimation,自适应矩估计)作为一种高效的优化算法脱颖而出。它旨在调整每个参数的学习率。
Adam可以看作是结合了RMSprop和带动量的随机梯度下降(SGD with Momentum)的优化算法。
Adam为每个参数计算自适应学习率。除了像AdaDelta和RMSprop那样存储过去梯度平方的指数衰减平均值$v_t$之外,Adam还维护了一个过去梯度的指数衰减平均值$m_t$,这与动量方法类似。
如果说动量可以被看作是一个在斜坡上滚动的球,那么Adam的行为则像是一个带有摩擦的重球,因此它更倾向于在误差曲面的平坦最小值处停留。
核心:Adam通过考虑梯度的一阶矩和二阶矩的移动平均值,改进了梯度下降的方法,使得它能够智能地适应每个参数的学习率。
其中,$m_k和v_k$分别是梯度的一阶矩和二阶矩的估计,$\beta_1和\beta_2$是控制两个矩估计得指数衰减率,范围在0到1之间,通常设置为0.9和0.999。$\epsilon$是个非常小的数(例如1e-8),防止除数为零。k是当前迭代的次数,用于做偏差校正。
Adam代码的核心代码:
def adam_update(parameters, gradients, m, v, t, lr=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8):
for param, grad in zip(parameters, gradients):
m[param] = beta1 * m[param] + (1 - beta1) * grad
v[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
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有