深度学习中的梯度

深度学习中的梯度

深度学习之详解常见梯度算法(概念、公式、原理、算法实现过程)

什么是梯度

梯度的提出只为回答一个问题:
函数在变量空间的某一点处,沿着哪一个方向有最大的变化率?

函数在某一点的梯度是这样一个向量,它的方向与取得最大方向导数的方向一致,而它的模为方向导数的最大值。

梯度向量的方向是函数增长最快的方向,其大小是该方向上的变化率

1)梯度是一个向量,即有方向有大小;
2)梯度的方向是最大方向导数的方向;
3)梯度的值是最大方向导数的值。

在反向传播中,梯度是损失函数关于网络参数的导数,它指示了损失函数在参数空间中增加最快的方向。

为什么要做梯度下解

既然在变量空间的某一点处,函数沿梯度方向具有最大的变化率,那么在优化目标函数的时候,自然是沿着负梯度方向去减小函数值,以此达到我们的优化目标。

梯度反向传播

反向传播传播的是损失函数关于每个权重和偏置的梯度
梯度指示了如何调整参数以减少损失。

梯度反向传播(Backpropagation)是神经网络中用于训练模型的关键算法。在反向传播过程中,梯度会从输出层反向传递到输入层,用于更新网络中的权重。梯度反向传播涉及对网络中每一层的权重和激活函数进行微分,计算损失函数相对于每个权重的梯度。

梯度反向传播会经过多层反复相乘的原因与链式法则(Chain Rule)有关,这是微积分中用于求解复合函数导数的基本法则。在神经网络中,每个神经元的输出可以看作是输入、权重和激活函数的复合结果。因此,要计算损失相对于网络中某个权重的梯度,就需要应用链式法则,将损失对激活函数的导数与激活函数对权重的导数相乘。

以下是梯度反向传播中链式法则应用的一个简化示例:

假设一个神经网络包含多个层,每层有多个神经元,每个神经元的输出 ( y ) 可以表示为:

[ y = f(z) ]

其中 ( z ) 是输入加权和 ( w \cdot x + b )(( w ) 是权重向量,( x ) 是输入向量,( b ) 是偏置),( f ) 是激活函数。

损失函数 ( L ) 相对于权重 ( w ) 的梯度可以表示为:

[ \frac{\partial L}{\partial w} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial z} \cdot \frac{\partial z}{\partial w} ]

这里:

  • ( \frac{\partial L}{\partial y} ) 是损失相对于输出 ( y ) 的梯度。
  • ( \frac{\partial y}{\partial z} ) 是激活函数 ( f ) 相对于 ( z ) 的导数。
  • ( \frac{\partial z}{\partial w} ) 是 ( z ) 相对于权重 ( w ) 的导数。

在反向传播过程中,首先计算输出层的梯度 ( \frac{\partial L}{\partial y} ),然后使用链式法则递归地计算前面各层的梯度。每一步都涉及到对激活函数的导数和权重的导数进行乘法运算。

当神经网络很深时,即存在很多层,这些梯度乘积会沿着网络层级反复进行。如果激活函数的导数值(如sigmoid或tanh函数在接近饱和区的导数)很小,或者权重本身较小,那么经过多次乘法后,梯度可能会变得非常小,导致梯度消失问题。相反,如果梯度值在每一步都较大,那么它们在多次乘法后可能会变得非常大,导致梯度爆炸问题。

为了解决这些问题,研究人员已经提出了多种技术,如使用ReLU激活函数(其在正区间内导数为常数,可以缓解梯度消失问题),权重初始化策略,梯度裁剪,以及改进的优化算法等。

梯度消失和梯度爆炸

梯度消失和梯度爆炸本质就是激活函数(的导数)和权重相互作用产生的联合效果

梯度消失和梯度爆炸的根源主要是因为深度神经网络结构以及**激活函数选择不当(函数的导数数值过小会导致梯度消失)**,目前优化神经网络的方法都是基于反向传播的思想,即根据损失函数计算的误差通过反向传播的方式,指导深度网络权值的更新。

在反向传播时对激活函数进行求导。如果在此部分大于1,那么随着层数的增加,求出的梯度的更新将以指数形式增加,发生梯度爆炸。如果此部分小于1,那么随着层数的增加求出的梯度更新的信息会以指数形式衰减,发生梯度消失。

梯度消失: 即在反向传播过程中,由于梯度值逐层传递时逐渐变小,权重的更新将非常微小,导致较靠近输入层的层难以有效地学习到输入数据的特征和模式。

梯度爆炸 在深度神经网络训练过程中,梯度值逐层传递时逐渐增大,并且可能超出网络的数值范围的问题。当梯度值变得非常大时,参数更新的幅度也会变得非常大,导致模型变得不稳定,甚至无法收敛。

梯度消失通常与以下几个因素有关:

  1. 激活函数的选择:某些激活函数,如Sigmoid或Tanh,在其饱和区(即输入值非常大或非常小的区域)的梯度非常小,这可能导致在反向传播过程中梯度值快速减小。

  2. 网络的深度:在很深的网络中,由于梯度需要通过多个层进行传播,每个层的梯度乘积将导致最终的梯度值变得非常小。

  3. 权重初始化:不适当的权重初始化可能导致梯度消失或梯度爆炸。

  4. 学习率设置:过大的学习率可能导致梯度爆炸,而过小的学习率可能导致梯度更新过慢,相当于梯度消失。

具体例子:

  1. Sigmoid激活函数
    假设一个神经网络使用Sigmoid激活函数,其梯度为 ( \sigma’(x) = \sigma(x)(1 - \sigma(x)) )。当 ( \sigma(x) ) 接近1或0时,梯度 ( \sigma’(x) ) 将接近0。例如,如果 ( \sigma(x) = 0.9 ),则梯度 ( \sigma’(x) = 0.9 \times (1 - 0.9) = 0.09 )。在深层网络中,连续多个这样的梯度乘积将导致最终梯度非常小。

  2. 深度网络
    考虑一个具有10层的神经网络,每层使用Sigmoid激活函数。如果每层的梯度乘积为0.1(这是一个合理的假设,因为Sigmoid激活函数的梯度通常小于1),那么经过10层后,初始梯度为1的梯度将减少到 ( 1 \times 0.1^{10} = 1 \times 10^{-10} ),这几乎为零。

  3. 长短期记忆网络(LSTM)
    LSTM设计之初就是为了解决传统RNN中的梯度消失问题。在标准的RNN中,梯度需要通过时间步进行传播,这同样会导致梯度消失。LSTM通过引入门控机制来缓解这个问题,允许梯度在时间序列中更有效地流动。

解决梯度消失的方法:

  • 使用ReLU或其变种:ReLU及其变种(如Leaky ReLU)在正区间内具有恒定的梯度,这有助于缓解梯度消失问题。

  • 权重初始化:使用如He初始化或Xavier初始化等策略,可以更好地控制训练初期的梯度大小。

  • 梯度裁剪:在优化过程中限制梯度的更新幅度,以避免梯度爆炸,同时也可以减轻梯度消失的影响。

  • 使用残差连接:在网络中使用残差连接(如在ResNet中)可以帮助梯度直接流向前面的层。

  • 适当的学习率调度:通过学习率衰减或自适应学习率优化算法(如Adam)来调整学习率。

method
1.正则化:通过 L1 或 L2 正则化来控制参数的大小,防止梯度值过大。
2.梯度剪裁(Gradient Clipping):限制梯度值的范围,将超出阈值的梯度进行裁剪。
3.预训练:可以先使用无监督学习或其他方式进行预训练,提供一个比较好的初始参数,从而减小梯度消失和爆炸的可能性。
4.层标准化(Layer Normalization)或批标准化(Batch Normalization):对层输出进行标准化,使其均值为0、方差为1,有助于缓解梯度消失情况。
5.参数初始化:合理选择参数的初始化方法,如使用 Xavier 或 He 等初始化方法,可以减小梯度消失和爆炸的概率。
6.更稳定的激活函数:使用 ReLU、Leaky ReLU 或其变体等激活函数,可以避免梯度消失,并且有助于缓解梯度爆炸。
7.Residual Connections(残差连接):在网络中增加跨层连接,可以传递较浅层的梯度信息,缓解梯度消失和爆炸。

Residual Connections

残差连接引入了一种跨层传递的机制,即在网络的某些层中,将前一层的输出直接加到后一层的输入中去。这种机制可以有效地传递一定的梯度信息,避免了网络深度增加时出现的梯度消失问题,同时也能够克服一些非凸优化问题,使得网络更容易优化。
具体而言,假设某一层的输入为 x,输出为 y,则残差连接的实现形式可以表示为:
y=F(x)+x
其中 F(x) 表示该层的非线性变换操作,即前向传播过程。在反向传播梯度计算时,则会将损失函数 L 反向传播到该层,生成梯度 ∂L/∂y,并将该梯度传递到 x,从而计算 ∂L/∂x,即该层输入 x 对损失函数的梯度。

梯度下降算法

梯度下降(Gradient Descent)是一种优化算法,用于寻找最小化损失函数(或成本函数)的参数值

损失函数衡量了模型预测值与真实值之间的差异,而梯度下降则是用于更新模型的参数(例如权重和偏置),以最小化这个差异。

对于非凸损失函数,梯度下降可能只能找到局部最小值而不是全局最小值

以下是梯度下降算法的基本步骤:

  1. 初始化参数:随机初始化模型参数或使用预设的值。

  2. 计算梯度:计算损失函数对每个参数的偏导数,这些偏导数构成了梯度向量。梯度指向损失函数增长最快的方向。

  3. 更新参数:根据梯度和一个学习率(步长)来更新每个参数。参数更新的公式通常是:
    [ \theta_i := \theta_i - \eta \cdot \frac{\partial J}{\partial \theta_i} ]
    其中,(\theta_i) 是第(i)个参数,(\eta) 是学习率,(\frac{\partial J}{\partial \theta_i}) 是损失函数(J)对参数(\theta_i)的偏导数。

  4. 重复迭代:重复步骤2和3,直到满足停止条件,如梯度足够小、达到预定的迭代次数或损失函数值不再显著减小。

梯度下降算法有几种变体,用于提高性能和稳定性:

  • 批量梯度下降(Batch Gradient Descent):每次迭代使用整个数据集来计算梯度和更新参数。这种方法计算准确,但可能计算成本高,且在大数据集上效率低。

  • 随机梯度下降(Stochastic Gradient Descent, SGD):每次迭代只使用一个训练样本来计算梯度和更新参数。SGD通常更快,但可能会有较大的噪声,导致训练过程不稳定。

  • 小批量梯度下降(Mini-batch Gradient Descent):每次迭代使用一小部分数据(称为小批量)来计算梯度和更新参数。这是批量梯度下降和随机梯度下降的折中方案,通常在实践中效果较好。

  • 动量(Momentum):在SGD的基础上增加了动量项,可以帮助梯度下降更快地收敛,同时减少震荡。

  • AdaGrad:Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,它通过将学习率分别应用于每个参数的梯度的平方来调整学习率,从而使得稀疏梯度的参数得到更大的更新,稠密梯度的参数得到较小的更新。Adagrad算法通常用于处理稀疏数据集和非凸优化问题。

  • RMSProp:RMSProp(Root Mean Square Propagation)是一种自适应学习率的优化算法,它在Adam算法之前提出,通过计算梯度的平方的移动平均来调整学习率,从而加速收敛过程。RMSProp算法通常用于优化神经网络的训练。解决了AdaGrad学习率过快减小的问题。

  • Adam:自适应矩估计算法,结合了随机梯度下降(SGD)和动量(Momentum)方法的优点,是目前非常流行的优化算法之一。

Adam算法的关键特性:

Adam(Adaptive Moment Estimation)是一种用于训练神经网络的梯度下解优化算法 以及 自适应学习率算法(lr会改变)

Adam 算法和传统的随机梯度下降不同。
随机梯度下降保持单一的学习率(即 alpha)更新所有的权重,学习率在训练过程中并不会改变。
Adam 通过计算梯度的一阶矩估计和二阶矩估计而为不同的参数设计独立的自适应性学习率。

自适应学习率: Adam算法能够为每个参数自动调整学习率,这是通过估计梯度的一阶矩(均值)和二阶矩(方差)来实现的。

动量方法: Adam算法利用过去梯度的指数加权平均值来更新参数,这类似于动量方法,有助于加速收敛并减少震荡。

计算效率: Adam算法在每次迭代中只需要计算一次前向和反向传播,这使得它在计算资源有限的情况下非常有效。

内存效率: 与其他一些需要存储过去所有梯度的优化算法相比,Adam只需要存储一阶矩和二阶矩的估计值,因此内存使用更少。

梯度下降算法及其变体在深度学习中被广泛使用,它们通过有效地调整模型参数来最小化损失函数,从而训练出性能良好的深度学习模型。

应用:
Adam算法在许多深度学习任务中都非常流行,特别是在需要处理大量参数和复杂模型的场景中。它的优点包括:

易于使用: 只需要调整少量超参数。
快速收敛: 在许多情况下,Adam算法能够比传统的SGD更快地收敛。
鲁棒性: 对学习率的选择不太敏感,因此在实际应用中更容易使用。


深度学习中的梯度
https://cs-lb.github.io/2024/05/17/深度学习/深度学习中的梯度/
作者
Liu Bo
发布于
2024年5月17日
许可协议