神经网络中的梯度下降算法

转载:http://blog.youkuaiyun.com/u013709270/article/details/78667531

一、概述

  梯度下降算法(Gradient Descent Optimization)是神经网络模型训练最常用的优化算法。对于深度学习模型,基本都是采用梯度下降算法来进行优化训练的。梯度下降算法背后的原理:目标函数这里写图片描述关于参数这里写图片描述的梯度将是目标函数下降最快的方向。对于最小化优化问题,只需要将参数沿着梯度相反的方向前进一个步长,就可以实现目标函数的下降。这个步长又称为学习速率这里写图片描述。参数更新公式如下:

这里写图片描述

其中这里写图片描述是参数的梯度,根据计算目标函数这里写图片描述采用数据量的不同,梯度下降算法又可以分为批量梯度下降算法(Batch Gradient Descent)随机梯度下降算法(Stochastic Gradient Descent)小批量梯度下降算法(Mini-batch Gradient Descent)。对于批量梯度下降算法,其这里写图片描述是在整个训练集上计算的,如果数据集比较大,可能会面临内存不足问题,而且其收敛速度一般比较慢。随机梯度下降算法是另外一个极端,这里写图片描述是针对训练集中的一个训练样本计算的,又称为在线学习,即得到了一个样本,就可以执行一次参数更新。所以其收敛速度会快一些,但是有可能出现目标函数值震荡现象,因为高频率的参数更新导致了高方差。小批量梯度下降算法是折中方案,选取训练集中一个小批量样本计算这里写图片描述,这样可以保证训练过程更稳定,而且采用批量训练方法也可以利用矩阵计算的优势,这是目前最常用的梯度下降算法。

  对于神经网络模型,借助于BP算法可以高效地计算梯度,从而实施梯度下降算法。但梯度下降算法一个老大难的问题是:不能保证全局收敛。如果这个问题解决了,深度学习的世界会和谐很多。梯度下降算法针对凸优化问题原则上是可以收敛到全局最优的,因为此时只有唯一的局部最优点。而实际上深度学习模型是一个复杂的非线性结构,一般属于非凸问题,这意味着存在很多局部最优点(鞍点),采用梯度下降算法可能会陷入局部最优,这应该是最头疼的问题。这点和进化算法如遗传算法很类似,都无法保证收敛到全局最优。因此,我们注定在这个问题上成为“高级调参师”。可以看到,梯度下降算法中一个重要的参数是学习速率,适当的学习速率很重要:学习速率过小时收敛速度慢,而过大时导致训练震荡,而且可能会发散。理想的梯度下降算法要满足两点:收敛速度要快,且能全局收敛。为了这个理想,出现了很多经典梯度下降算法的变种,下面将分别介绍它们。

1. 冲量梯度下降算法(Momentum optimization)

  冲量梯度下降算法是BorisPolyak在1964年提出的,其基于这样一个物理事实:将一个小球从山顶滚下,其初始速率很慢,但在加速度作用下速率很快增加,并最终由于阻力的存在达到一个稳定速率。对于冲量梯度下降算法,其更新方程如下:

这里写图片描述
这里写图片描述

可以看到,参数更新时不仅考虑当前梯度值,而且加上了一个积累项(冲量),但多了一个超参这里写图片描述,一般取接近1的值如0.9。相比原始的梯度下降算法,冲量梯度下降算法有助于加速收敛。当梯度与冲量方向一致时,冲量项会增加,而相反时,冲量项减少,因此冲量梯度下降算法可以减少训练的震荡过程。TensorFlow中提供了这一优化器:tf.train.MomentumOptimizer(learning_rate=learning_rate,momentum=0.9)。

2. NAG算法(Nesterov Accelerated Gradient)

  NAG算法全称Nesterov Accelerated Gradient,是YuriiNesterov在1983年提出的对冲量梯度下降算法的改进版本,其速度更快。其变化之处在于计算“超前梯度”更新冲量项,具体公式如下:

这里写图片描述
这里写图片描述

既然参数要沿着这里写图片描述更新,不妨计算未来位置这里写图片描述的梯度,然后合并两项作为最终的更新项,其具体效果如图1所示,可以看到一定的加速效果。在TensorFlow中,NAG优化器为:tf.train.MomentumOptimizer(learning_rate=learning_rate,momentum=0.9, use_nesterov=True)

这里写图片描述
图1 NAG算法效果图

3. AdaGrad算法

  AdaGrad算法是Duchi在2011年提出的一种学习速率自适应的梯度下降算法。在训练迭代过程,其学习速率是逐渐衰减的,经常更新的参数其学习速率衰减更快,这是一种自适应算法。其更新过程如下:

这里写图片描述
这里写图片描述

  其中这里写图片描述是梯度平方的积累量,在进行参数更新时,学习速率要除以这个积累量的平方根,其中加上一个很小值这里写图片描述是为了防止除0的出现。由于是该项逐渐增加的,那么学习速率是衰减的。考虑如图2所示的情况,目标函数在两个方向的坡度不一样,如果是原始的梯度下降算法,在接近坡底时收敛速度比较慢。而当采用AdaGrad,这种情况可以被改观。由于比较陡的方向梯度比较大,其学习速率将衰减得更快,这有利于参数沿着更接近坡底的方向移动,从而加速收敛。

这里写图片描述
图2 AdaGrad算法的效果图

  前面说到AdaGrad其学习速率实际上是不断衰减的,这会导致一个很大的问题,就是训练后期学习速率很小,导致训练过早停止,因此在实际中AdaGrad一般不会被采用,下面的算法将改进这一致命缺陷。不过TensorFlow也提供了这一优化器:tf.train.AdagradOptimizer。

4. RMSprop算法

  RMSprop算法是Hinton在他的课程上讲到的,其算是对Adagrad算法的改进,主要是解决学习速率过快衰减的问题。其实思路很简单,类似Momentum思想,引入一个超参数,在积累梯度平方项进行衰减:

这里写图片描述
这里写图片描述

  这里写图片描述可以认为仅仅对距离时间较近的梯度进行积累,其中这里写图片描述一般取值0.9,其实这样就是一个指数衰减的均值项,减少了出现的爆炸情况,因此有助于避免学习速率很快下降的问题。同时Hinton也建议学习速率设置为0.001。RMSprop是属于一种比较好的优化算法了,在TensorFlow中当然有其身影:tf.train.RMSPropOptimizer (learning_rate=learning_rate,momentum=0.9, decay=0.9, epsilon=1e-10)。不得不说点题外话,同时期还有一个Adadelta算法,其也是Adagrad算法的改进,而且改进思路和RMSprop很像,但是其背后是基于一次梯度近似代替二次梯度的思想,感兴趣的可以看看相应的论文,这里不再赘述。

5. Adam算法(Adaptive moment estimation)

  Adam算法,全称Adaptive moment estimation,是Kingma等在2015年提出的一种新的优化算法,其结合了Momentum和RMSprop算法的思想。相比Momentum算法,其学习速率是自适应的,而相比RMSprop,其增加了冲量项。所以,Adam是两者的结合体:

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

  可以看到前两项和Momentum和RMSprop是非常一致的,由于这里写图片描述这里写图片描述的初始值一般设置为0,在训练初期其可能较小,第三和第四项主要是为了放大它们,最后一项是参数更新。其中超参数的建议值是:这里写图片描述这里写图片描述这里写图片描述,Adm是性能非常好的算法,在TensorFlow其实现如下: tf.train.AdamOptimizer(learning_rate=0.001,beta1=0.9, beta2=0.999, epsilon=1e-08)。

二、学习速率的选择

  前面也说过学习速率的问题,对于梯度下降算法,这应该是一个最重要的超参数。如果学习速率设置得非常大,那么训练可能不会收敛,就直接发散了;如果设置的比较小,虽然可以收敛,但是训练时间可能无法接受;如果设置的稍微高一些,训练速度会很快,但是当接近最优点会发生震荡,甚至无法稳定。不同学习速率的选择影响可能非常大,如图3所示。

这里写图片描述
图3 不同学习效率的训练效果图

  理想的学习速率是:刚开始设置较大,有很快的收敛速度,然后慢慢衰减,保证稳定到达最优点。所以,前面的很多算法都是学习速率自适应的。除此之外,还可以手动实现这样一个自适应过程,如实现学习速率指数式衰减:这里写图片描述

  在TensorFlow中,你可以这样实现:

initial_learning_rate = 0.1
decay_steps = 10000
decay_rate = 1/10
global_step = tf.Variable(0, trainable=False)
learning_rate = tf.train.exponential_decay(initial_learning_rate,                           
                            global_step, decay_steps, decay_rate)
# decayed_learning_rate = learning_rate *
#                decay_rate ^ (global_step / decay_steps)
optimizer = tf.train.MomentumOptimizer(learning_rate, momentum=0.9)
training_op = optimizer.minimize(loss, global_step=global_step)

三、总结

  本文简单介绍了梯度下降算法的分类以及常用的改进算法,总结来看,优先选择学习速率自适应的算法如RMSprop和Adam算法,大部分情况下其效果是较好的。还有一定要特别注意学习速率的问题,其实还有很多方面会影响梯度下降算法,如梯度的消失与爆炸,这也是要额外注意的。最后不得不说,梯度下降算法目前无法保证全局收敛还将是一个持续性的数学难题。

参考文献:
1. Anoverview of gradient descent optimization algorithms: http://sebastianruder.com/optimizing-gradient-descent/.
2. Hands-OnMachine Learning with Scikit-Learn and TensorFlow, Aurélien Géron, 2017.
3. NAG:http://proceedings.mlr.press/v28/sutskever13.pdf.
4. Adagrad:http://www.jmlr.org/papers/volume12/duchi11a/duchi11a.pdf.
5.RMSprop:http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf.
6. Adadelta:https://arxiv.org/pdf/1212.5701v1.pdf.
7. Adam:https://arxiv.org/pdf/1412.6980.pdf.
8. 不同的算法的效果可视化:https://imgur.com/a/Hqolp.

<think>嗯,用户想了解神经网络中的梯度下降算法。首先,我需要回忆一下梯度下降的基本概念。梯度下降是优化算法,用于最小化损失函数,通过调整参数来找到最小值。神经网络里参数很多,梯度下降帮助更新权重。 应该从基础开始解释,比如什么是梯度,为什么需要下降。可能用户对数学部分不太熟悉,需要用简单的例子说明。比如,想象在山顶找最快下山的路,梯度就是最陡的方向,每一步走多远是学习率。 然后要分步骤讲清楚流程:初始化参数,计算损失函数的梯度,更新参数,重复直到收敛。这里要注意学习率的作用,太大可能震荡,太小收敛慢。 接下来得联系到神经网络的具体应用。前向传播计算预测值,反向传播计算梯度,然后用梯度下降更新权重。可能需要提到批量梯度下降、随机梯度下降和小批量梯度下降的区别,用户可能听说过这些变种。 还要注意可能的常见问题,比如局部最优、鞍点、学习率调整策略,比如Adam优化器。但用户可能只需要基础,暂时不用深入这些进阶内容。 要确保语言通俗易懂,避免太多公式,但必要的数学符号要用LaTeX规范。比如损失函数的梯度用$\nabla L(\theta)$,参数更新公式用$\theta = \theta - \eta \nabla L(\theta)$。 用户可能想知道为什么梯度下降有效,或者在实际训练中如何应用。可能需要举一个简单的例子,比如线性回归中的参数更新,再类比到神经网络。 检查有没有错误的地方,比如梯度方向是否正确,参数更新的步骤是否正确。另外,要确认是否符合格式要求,行内公式用$...$,独立公式用$$...$$,结构清晰,分步骤说明。</think>神经网络中的梯度下降算法是一种通过迭代调整参数来最小化损失函数的优化方法。以下是分步解释: --- ### 一、核心思想 梯度下降的目标是找到使损失函数$L(\theta)$最小的参数$\theta$(例如神经网络的权重和偏置)。其本质是**沿着损失函数梯度的反方向更新参数**,因为梯度方向指向函数值增长最快的方向,反方向则是下降最快的方向。 --- ### 二、数学表达 1. **梯度计算** 对参数$\theta$求损失函数的梯度: $$\nabla L(\theta) = \left( \frac{\partial L}{\partial \theta_1}, \frac{\partial L}{\partial \theta_2}, \dots \right)$$ 2. **参数更新公式** 以学习率$\eta$(步长)沿梯度反方向更新: $$\theta_{new} = \theta_{old} - \eta \cdot \nabla L(\theta_{old})$$ --- ### 三、具体步骤(以神经网络为例) 1. **前向传播** 输入数据通过神经网络计算预测值,得到损失$L$。 *示例*:对输入$x$,输出$\hat{y} = f_\theta(x)$,损失$L = \frac{1}{2}(y - \hat{y})^2$ 2. **反向传播** 从输出层反向计算每个参数的梯度$\frac{\partial L}{\partial \theta}$,利用链式法则逐层分解。 3. **参数更新** 使用梯度下降公式调整所有参数。 4. **重复迭代** 直到损失收敛或达到停止条件。 --- ### 四、关键概念 1. **学习率($\eta$)** - 过大:可能跳过最优解或震荡 - 过小:收敛速度慢 *示例*:$\eta=0.01$是常见初始值 2. **局部最优与鞍点** 在高维空间中,局部最优较少,但梯度接近零的鞍点会影响收敛。 --- ### 五、变种算法 1. **批量梯度下降(BGD)** 使用全部数据计算梯度,计算成本高但稳定。 2. **随机梯度下降(SGD)** 每次随机选一个样本计算梯度,速度快但波动大。 3. **小批量梯度下降(Mini-batch GD)** 折中方案,每次用一小批数据(如32/64个样本),平衡效率与稳定性。 --- ### 六、可视化理解 想象在山谷中寻找最低点: - 当前位置:当前参数$\theta$ - 坡度方向:梯度$\nabla L(\theta)$ - 步幅:学习率$\eta$ - 目标:通过多次“迈步”到达谷底 --- ### 七、代码示例(伪代码) ```python for epoch in range(num_epochs): # 前向传播计算损失 y_pred = forward(x, theta) loss = compute_loss(y, y_pred) # 反向传播计算梯度 gradients = backward(y_pred, y) # 更新参数 theta = theta - learning_rate * gradients ``` --- ### 总结 梯度下降神经网络训练的基石,其核心是通过**计算梯度**和**迭代更新参数**逐步逼近最优解。实际应用中需结合学习率调整、动量(Momentum)等方法提升性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值