前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >深度学习:神经网络优化技巧

深度学习:神经网络优化技巧

原创
作者头像
皮大大
发布于 2025-05-09 07:52:18
发布于 2025-05-09 07:52:18
11000
代码可运行
举报
文章被收录于专栏:深度学习深度学习
运行总次数:0
代码可运行

深度学习知识卡片:神经网络优化技巧

深度学习中,有一个“损失loss”的概念,它告诉我们:模型在训练数据中表现的“多差”。

现在,我们需要利用这个损失来训练我们的网络,使其表现得更好。本质上,我们需要做的是利用损失并尝试将其最小化,因为较低的损失意味着我们的模型将会表现得更好。最小化(或最大化)任何数学表达式的这个过程被称为优化

理解全局最小化和局部最小化

用一张图理解全局最小化和局部最小化:

|200
|200
  • 局部最小化:Local Minima
  • 全局最小化:Global Minima

优化器如何工作

优化器是用于改变神经网络属性(例如权重和学习率)的算法或方法,以减少损失。优化器通过最小化函数来解决优化问题。

为了更好地理解优化器的作用,可以想象一个蒙着眼睛的登山者试图走下一座山。无法确切知道他该往哪个方向走,但他能判断自己是在下山(取得进展)还是在上山(失去进展)。只要他一直朝着下山的方向前进,最终就能到达山脚。

|200
|200

同样,在训练神经网络时,我们无法从一开始就确定模型的权重应该是什么,但可以通过基于损失函数的不断调整(类似于判断登山者是否在下山)来逐步接近目标。

优化器的作用就在于此: 它决定了如何调整神经网络的权重和学习率以减少损失。优化算法通过不断优化损失函数,帮助模型尽可能地输出准确的结果。

9种优化器

列举9种不同类型的优化器以及它们是如何精确地工作以最小化损失函数的。

  1. Gradient Descent
  2. Stochastic Gradient Descent, SGD
  3. Mini-Batch Stochastic Gradient Descent, MB-SGD
  4. SGD with Momentum
  5. Nesterov Accelerated Gradient, NAG
  6. Adaptive Gradient, AdaGrad
  7. AdaDelta
  8. RMSprop
  9. Adam

优化器1:梯度下降Gradient Descent

基本思想

梯度下降(Gradient Descent)是一种优化算法,用于寻找可微函数的局部最小值。其目标是通过迭代调整模型参数,最小化代价函数(Cost Function)。以下是梯度下降算法的基本思想:

  • 目标:找到模型参数的最优值,使得代价函数达到最小值。
  • 方法:利用函数的梯度(即导数)来确定参数调整的方向。梯度(Gradient)指的是函数在某一点的梯度是一个向量,指向函数增长最快的方向。

到底什么是梯度?

"A gradient measures how much the output of a function changes if you change the inputs a little bit." — Lex Fridman (MIT)

梯度下降的核心思想是:沿着梯度的反方向(即函数下降最快的方向)调整参数

算法步骤

  1. 初始化参数
    • 选择初始参数值(通常随机初始化或使用特定策略)。
    • 设置学习率(Learning Rate),学习率决定了每次迭代中参数更新的步长。
  2. 计算梯度: 计算代价函数对每个参数的偏导数,得到梯度向量。
  3. 更新参数: 使用梯度下降更新公式调整参数: $$

\theta = \theta - \alpha \cdot \nabla J(\theta)

$$

其中:

  • $\theta\$ 是模型参数。
  • $\alpha\$ 是学习率。
  • $\nabla J(\theta)$ 是代价函数 $J(\theta)\$ 对参数 $\theta\$ 的梯度。

重复计算梯度和更新参数的过程,直到满足终止条件(如收敛或达到最大迭代次数)。

|280
|280

收敛条件

  • 收敛判断:当代价函数的变化量小于某个阈值,或梯度的范数小于某个阈值时,认为算法收敛。
  • 停止条件:可以设置最大迭代次数,防止算法陷入无限循环。
|320
|320

学习率的作用

  • 学习率的选择
    • 如果学习率过大,可能导致参数更新过度,使代价函数无法收敛甚至发散。
    • 如果学习率过小,会使收敛速度过慢,增加训练时间。
  • 动态调整学习率:在训练过程中,可以采用动态调整学习率的策略,如学习率衰减(Learning Rate Decay),以加速收敛。
|320
|320

通过图像的形式描述不同学习率的过程:

|320
|320

可以看到学习率不能过大或过小。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
for i in range(nb_epochs):   
    params_grad = evaluate_gradient(loss_function, data, params)           
    params = params - learning_rate * params_grad

优缺点

Advantages:

  1. 计算简单
  2. 实现容易
  3. 容易理解

Disadvantages:

  1. 可能陷入局部最小值。
  2. 权重是在计算整个数据集的梯度之后才更新的。因此,如果数据集太大,可能需要花费较长时间才能收敛到最小值。
  3. 需要大量内存来计算整个数据集的梯度。

优化器2:随机梯度下降Stochastic Gradient Descent (SGD)

定义

随机梯度下降(SGD)是一种优化算法,用于在训练机器学习模型时最小化损失函数。它是梯度下降算法的一种扩展,通过每次只使用一个训练样本(或少量样本)来计算梯度,从而减少计算量和内存需求。

基本思想

目标:通过迭代更新模型参数,最小化损失函数 J(θ)。

方法:每次只使用一个训练样本 (x(i),y(i)) 来计算梯度,并更新参数。

在SGD算法中,每次只取一个数据点来计算导数

|240
|240

SGD(随机梯度下降)针对每个训练样本 x(i) 和对应的标签 y(i) 进行参数更新。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
θ = θ − α⋅∂(J(θ;x(i),y(i)))/∂θ

对比随机梯度下降SGD和梯度下降GD:

|320
|320

在左边,随机梯度下降(SGD,其中每步 m=1)为每个样本进行一次梯度下降步骤;而在右边是完整的梯度下降(每整个训练集进行1次步骤)。

观察结果表明,在SGD中,更新需要比梯度下降更多的迭代次数才能到达最小值。在右边,梯度下降到达最小值的步数更少,但SGD算法更“嘈杂”,需要更多的迭代次数。

在TensorFlow中的使用:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
from tensorflow.keras.optimizers import SGD 
optimizer = SGD(learning_rate=0.01, momentum=0.0, nesterov=False

算法步骤

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
- 初始化参数:
  - 随机初始化模型参数 θ。
  - 设置学习率 α。
- 迭代更新:
  - 对于每个训练样本 (x(i),y(i))- 计算损失函数 J(θ) 关于参数 θ 的梯度 ∇J(θ)- 更新参数:
  - θ=θ−α⋅∇J(θ)
- 重复步骤:

重复上述过程,直到满足终止条件(如收敛或达到最大迭代次数)。

优缺点

Advantages:

  • 计算效率高:每次只处理一个样本,计算量小,适合大规模数据集。
  • 内存需求低:不需要一次性加载整个数据集,节省内存。
  • 实时更新:参数在每个样本后更新,能够快速响应数据的变化。

Disadvantages:

  • 噪声大:每次更新基于单个样本,梯度估计可能不准确,导致更新过程“嘈杂”。
  • 收敛速度慢:可能需要更多迭代次数才能收敛到最小值。
  • 易陷入局部最小值:由于更新的随机性,可能在局部最小值附近徘徊。

随机梯度下降(SGD)通过每次只处理一个样本,减少了计算量和内存需求,同时保持了快速的参数更新能力。

虽然存在一定的噪声和收敛速度较慢的问题,但通过适当的调整学习率和优化策略,SGD在许多实际应用中表现出色。

优化器3:小批量随机梯度下降(Mini Batch Stochastic Gradient Descent, MB-SGD)

小批量随机梯度下降(Mini Batch Stochastic Gradient Descent, MB-SGD)是梯度下降算法的一种改进,结合了批量梯度下降(Batch Gradient Descent)和随机梯度下降(Stochastic Gradient Descent, SGD)的优点。

它通过每次使用一个小批量(Mini-Batch)的数据来计算梯度,从而在计算效率和稳定性之间取得平衡。

|500
|500

基本思想

目标:通过迭代更新模型参数,最小化损失函数 J(θ)。

方法:每次从训练集中随机抽取一个小批量的数据(通常包含几十个样本),计算该小批量数据的梯度,并更新参数。

算法步骤

  • 初始化参数:
    • 随机初始化模型参数θ。
    • 设置学习率α。
    • 定义小批量的大小m(通常为2的幂,如32、64、128等)。
  • 划分数据集:

将整个训练集划分为若干个小批量,每个小批量包含 m 个样本。

  • 迭代更新: $$ \nabla J(\theta) = \frac{1}{m} \sum_{i=1}^{m} \nabla J(\theta; x^{(i)}, y^{(i)}) $$
  • 更新参数: $$ \theta = \theta - \alpha \cdot \nabla J(\theta) $$ 重复步骤: 重复上述过程,直到满足终止条件(如收敛或达到最大迭代次数)。

使用mini-batches参数:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
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:

  • 相比于标准的随机梯度下降(SGD)算法,收敛的时间复杂度更低。

Disadvantages::

  • 与梯度下降(GD)算法相比,小批量随机梯度下降(MB-SGD)的更新过程更加“嘈杂”。
  • 比梯度下降(GD)算法需要更长时间才能收敛。
  • 可能会陷入局部最小值。

优化器4:SGD with Momentum

基本原理

小批量随机梯度下降(MB-SGD)算法的一个主要缺点是权重更新非常“嘈杂”。带动量的随机梯度下降(SGD with Momentum)通过降噪梯度克服了这一缺点,它在传统的随机梯度下降(SGD)的基础上引入了动量Momentum机制,在每次更新时,通过考虑历史梯度信息来加速收敛并减少噪声。

|300
|300

算法步骤

  1. 初始化参数
  2. 随机初始化模型参数 $\theta$
  3. 初始化动量参数 v (通常初始化为零向量)。
  4. 设置学习率 $\alpha$ 和动量系数$\gamma $(通常取值为0.9或0.99)。
  5. 迭代更新
  6. 对于每个训练样本$(x^{(i)}, y^{(i)}) $ 或小批量数据:
    1. 计算当前梯度$\nabla J(\theta)$: $$ \nabla J(\theta) = \frac{\partial J(\theta; x^{(i)}, y^{(i)})}{\partial \theta} $$
    2. 更新动量参数 $ v $: $$ v = \gamma \cdot v - \alpha \cdot \nabla J(\theta) $$ 其中:
    • $\gamma\$ 是动量系数,控制历史梯度的衰减速度。
    • $\alpha\$ 是学习率,控制更新步长。
    1. 更新参数$ \theta $: $$ \theta = \theta + v $$
  7. 重复步骤
  8. 重复上述过程,直到满足终止条件(如收敛或达到最大迭代次数)。

优缺点

Advantages:

  • 减少噪声:通过考虑历史梯度信息,减少了更新过程中的噪声。
  • 加速收敛:动量机制帮助模型更快地收敛到最小值,特别是在损失函数的“山谷”中。
  • 减少振荡:在接近最小值时,动量机制可以减少参数更新的振荡。

Disadvantages:

  • 超参数选择:需要选择合适的动量系数 $\gamma\$ 和学习率 $\alpha$,这可能需要一些实验和调整。
  • 计算复杂度:虽然每次更新的计算量与SGD相当,但引入动量机制会增加一些额外的计算开销。

在TensorFlow中的使用:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
from tensorflow.keras.optimizers import SGD 
optimizer = SGD(learning_rate=0.01, momentum=0.9, nesterov=False)

优化器5:Nesterov Accelerated Gradient, NAG

基本原理

动量法每下降一步都是由前面下降方向的一个累积和当前点的梯度方向组合而成。于是一位大神(Nesterov)就开始思考,既然每一步都要将两个梯度方向(历史梯度、当前梯度)做一个合并再下降,那为什么不先按照历史梯度往前走那么一小步,按照前面一小步位置的“超前梯度”来做梯度合并呢?

如此一来,小球就可以先不管三七二十一先往前走一步,在靠前一点的位置看到梯度,然后按照那个位置再来修正这一步的梯度方向。如此一来,有了超前的眼光,小球就会更加”聪明“, 这种方法被命名为Nesterov accelerated gradient 简称 NAG

Nesterov Accelerated Gradient(NAG)是一种改进的梯度下降优化算法,它在传统的动量优化算法的基础上引入了“前瞻性”更新机制,从而提高了收敛速度并减少了震荡

NAG的核心思想是在计算梯度时:

  • 先根据之前的动量方向进行一个预期的更新
  • 然后再根据这个预期位置计算梯度。

这种方法使得参数更新更加“前瞻”,避免了传统动量方法中可能出现的过冲问题。

数学公式

记$vt$为第t次迭代梯度的累积:

|200
|200
  1. 初始化:$ v_0 = 0 $
  2. 第一次迭代: $v1 = \eta \nabla\theta J(\theta) $
  3. 第二次迭代:$ v2 = \gamma v_1 + \eta \nabla\theta J(\theta - \gamma v_1) $
  4. 一般迭代规则(第 ( t ) 次迭代):$ vt = \gamma v{t-1} + \eta \nabla\theta J(\theta - \gamma v{t-1}) $

其中:

  • $ \eta $ 是学习率
  • $ \gamma $ 是动量系数
  • $ \nabla_\theta J(\theta) $是损失函数$J$关于参数$ \theta $的梯度
|300
|300

在TensorFlow中的使用:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
from tensorflow.keras.optimizers import SGD 
optimizer = SGD(learning_rate=0.01, momentum=0.9, nesterov=True)

优化器6: Adaptive Gradient, AdaGrad

对于之前讨论的所有算法,学习率都是固定的

Adaptive Gradient(AdaGrad)算法是一种自适应学习的优化算法,于2011年由Duchi等人提出,它能够根据参数的历史梯度自适应地调整学习率

核心思想

AdaGrad的核心思想是对每个参数的学习率进行适应性调整,从而实现对参数的不同历史梯度的平方和进行自适应调整。

具体来说,AdaGrad通过累积过去所有梯度的平方和来为每个参数动态调整学习率,使得较少更新频繁出现的特征参数具有更大的学习率,而较频繁更新的特征参数则具有更小的学习率。

数学原理

  1. 梯度计算: $$ g = \nabla{\theta{k-1}} L(\theta) $$ 计算损失函数 $ L(\theta)$ 关于参数 $\theta $ 在第 $k-1$ 次迭代时的梯度 $g $ ;其中$\nabla{\theta}$表示梯度运算符,$\theta{k-1}$表示上一步的参数值。
  2. 累积梯度平方和更新:

$$

rk = r{k-1} + g \odot g

$$

在第 k 次迭代时,将当前梯度 g 的平方(逐元素相乘)累加到之前的累积梯度平方和 $ r_{k-1} $ 上,得到新的累积梯度平方和 $ r_k $ 。其中,$\odot$表示元素乘法(即Hadamard乘积)。

  1. 自适应学习率计算: $$ \eta = \frac{\eta_0}{\sqrt{r_k + \epsilon}} $$ 计算自适应学习率,其中 $ \eta_0 $ 是初始学习率, $ r_k $ 是当前的累积梯度平方和, $ \epsilon $ 是一个小的正数(防止除零错误)。通过累积梯度平方和$r_k$来调整学习率$\epsilon$;这样的调整使得学习率对于出现频繁的特征会更小,而对于稀疏特征会更大,有助于提高模型在稀疏数据上的性能
  2. 参数更新: $$ \theta_k = \theta - \eta g $$

完整形式:

$$

\thetak = \theta - \frac{\eta_0}{\sqrt{r_k + \epsilon}} * \nabla{\theta_{k-1}} L(\theta)

$$

使用计算出的自适应学习率 $ \eta $ 和梯度 $ g $ 来更新参数 $ \theta $ 到新值 $ \theta_k $ ,目的是减少损失函数 $ L(\theta) $ 的值。

优缺点

Advantage: 不需要手动更新学习率

Disadvantage:

  • 学习率持续衰减:由于累积的平方梯度持续增加,学习率会持续衰减,最终导致学习率过小,从而使得训练后期模型难以收敛。
  • 存储梯度平方和:需要为每个参数存储一个累积的梯度平方和,这在参数很多时会增加额外的内存开销。

优化器7: AdaDelta

基本原理

AdaGrad存在的问题是,随着迭代次数的增加,学习率会变得非常小,这导致收敛速度变慢。为了避免这个问题,AdaDelta算法采用了一种想法,即取梯度的指数衰减平均值

AdaDelta是Adagrad的一个更稳健的扩展,它根据梯度更新的移动窗口来调整学习率,而不是累积所有过去的梯度。这样,即使进行了很多次更新,AdaDelta也能够继续学习。

AdaDelta算法并没有低效地存储过去的平方梯度,而是将梯度的累积和递归地定义为所有过去平方梯度的衰减平均值。

在时间步 $t$ 的运行平均$Eg^2_t$仅依赖于先前的累积平均值和当前的梯度:

|350
|350

在AdaDelta算法中不需要设置默认的学习率:

|350
|350

优缺点

Advantage:

  1. AdaDelta不需要手动设置学习率,因为它会根据迭代过程中的梯度信息来自适应地调整学习率。
  2. 对稀疏数据表现良好:在处理稀疏数据时,AdaDelta能够动态调整学习率,防止学习率过快减小,从而避免收敛速度变慢的问题。
  3. 减少对初始条件的敏感性:AdaDelta对初始化条件的敏感性较低,因为它会根据训练过程中的情况进行自适应调整。

Disadvantage:

收敛速度:与一些更新的优化方法(如Adam)相比,AdaDelta可能不会那么快地收敛。

优化器8: RMSprop(Root Mean Square Propagation)

基本原理

RMSprop(Root Mean Square Propagation)算法是一种自适应学习率的优化算法,由 Geoffrey Hinton 提出,旨在解决梯度下降及其变体在优化过程中学习率固定不变时可能导致的收敛速度慢或不收敛的问题。

RMSprop通过为每个参数动态调整学习率来改进这一点,特别适用于处理非平稳目标函数。

基本原理:

  1. 初始化:
  2. 参数$\theta$
  3. 梯度平方的指数加权平均值$Eg^2$为0
  4. 设置学习率$ η $(比如0.001)
  5. 设置衰减率 ρ(比如0.9)
  6. 梯度计算

在每次迭代中,计算损失函数 $L(θ)$关于参数$θ$的梯度$g$

  1. 更新梯度平方的指数加权平均值$Eg^2$:
|300
|300
  1. 参数更新

使用下面的参数更新参数$\theta$

|300
|300

其中,$ϵ$ 是一个小的正数(例如$10^{−8}$),用于防止除零错误。

优缺点

Advantage:

  1. 自适应学习率:RMSprop为每个参数动态调整学习率,使得学习率与梯度的平方的指数加权平均值的平方根成反比。这有助于处理稀疏数据和非平稳目标函数。
  2. 防止梯度爆炸:通过限制梯度更新的幅度,RMSprop有助于防止梯度爆炸问题。
  3. 无需手动调整学习率:RMSprop自动调整学习率,减少了手动调整学习率的需求。

Disadvantage:

  1. 可能需要调整超参数:尽管RMSprop自动调整学习率,但仍然需要选择合适的衰减率 ρ 和学习率 η。
  2. 在某些情况下可能不稳定:在某些情况下,RMSprop可能不如其他优化算法(如Adam)稳定。

优化器9:Adaptive Moment Estimation(Adam)

在机器学习中,Adam(Adaptive Moment Estimation,自适应矩估计)作为一种高效的优化算法脱颖而出。它旨在调整每个参数的学习率。

基本原理

Adam可以看作是结合了RMSprop和带动量的随机梯度下降(SGD with Momentum)的优化算法。

Adam为每个参数计算自适应学习率。除了像AdaDelta和RMSprop那样存储过去梯度平方的指数衰减平均值$v_t$之外,Adam还维护了一个过去梯度的指数衰减平均值$m_t$,这与动量方法类似。

如果说动量可以被看作是一个在斜坡上滚动的球,那么Adam的行为则像是一个带有摩擦的重球,因此它更倾向于在误差曲面的平坦最小值处停留。

数学公式

核心:Adam通过考虑梯度的一阶矩二阶矩的移动平均值,改进了梯度下降的方法,使得它能够智能地适应每个参数的学习率。

|300
|300

其中,$m_k和v_k$分别是梯度的一阶矩和二阶矩的估计,$\beta_1和\beta_2$是控制两个矩估计得指数衰减率,范围在0到1之间,通常设置为0.9和0.999。$\epsilon$是个非常小的数(例如1e-8),防止除数为零。k是当前迭代的次数,用于做偏差校正。

|350
|350

Adam代码的核心代码:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 深度学习知识卡片:神经网络优化技巧
    • 理解全局最小化和局部最小化
    • 优化器如何工作
    • 9种优化器
  • 优化器1:梯度下降Gradient Descent
    • 基本思想
    • 算法步骤
    • 收敛条件
    • 学习率的作用
    • 优缺点
  • 优化器2:随机梯度下降Stochastic Gradient Descent (SGD)
    • 定义
    • 基本思想
    • 算法步骤
    • 优缺点
  • 优化器3:小批量随机梯度下降(Mini Batch Stochastic Gradient Descent, MB-SGD)
    • 基本思想
    • 算法步骤
  • 优化器4:SGD with Momentum
    • 基本原理
    • 算法步骤
    • 优缺点
  • 优化器5:Nesterov Accelerated Gradient, NAG
    • 基本原理
    • 数学公式
  • 优化器6: Adaptive Gradient, AdaGrad
    • 核心思想
    • 数学原理
    • 优缺点
  • 优化器7: AdaDelta
    • 基本原理
    • 优缺点
  • 优化器8: RMSprop(Root Mean Square Propagation)
    • 基本原理
    • 优缺点
  • 优化器9:Adaptive Moment Estimation(Adam)
    • 基本原理
    • 数学公式
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档