梯度下降

损失函数是衡量模型预估值和真实值差异的度量,之所以存在差异是因为模型中的参数(比如感知机中的 w w w和 b b b)还有待训练,在神经网络中由于参数动辄上亿,如果没有一个策略全凭直觉去调就算到宇宙爆炸也很难优化好。目前常用的策略是反向传播,而梯度下降法就是反向传播中的一种方法,其基本思想是通过迭代的方式,沿着损失函数的梯度的反方向更新参数,从而逐步逼近函数的最小值。

基本概念

在了解梯度下降的算法之前,我们先了解下面一些概念。

  1. 导数:
    1. 意义: 导数衡量了函数在某一点的瞬时变化率,也就是函数在这一点的斜率。直观地说,导数告诉我们函数在某点的变化趋势,是在增加还是减少。
  2. 偏导数:
    1. 意义: 当我们有一个多变量函数时,偏导数表示在一个特定变量的变化方向上的变化率。对于一个二元函数,偏导数就是在其中一个变量上的导数。
  3. 梯度:
    1. 意义: 梯度是一个向量(向量有方向和大小),其中每个元素是在对应维度上的偏导。在多变量函数中,梯度指示了函数在某一点上变化最快的方向,沿着梯度向量的方向,更加容易找到函数的最大值。沿着梯度向量相反的方向,更加容易找到函数的最小值。
    2. 实际计算例子: 假设有一个二元函数: f ( x , y ) = x 2 + 5 y f(x,y) = x^{2} + 5y f(x,y)=x2+5y,我们想计算它在点 (1,3)处的梯度。首先计算偏导数:
      ∂ f ∂ x = 2 x ⇒ ∂ f ∂ x ( 1 , 3 ) = 2 \frac{{∂f}}{{∂x}} = 2 x ⇒ \frac{{∂f}}{{∂x}}(1,3)=2 ∂x∂f=2x⇒∂x∂f(1,3)=2
      ∂ f ∂ y = 5 ⇒ ∂ f ∂ y ( 1 , 3 ) = 5 \frac{{∂f}}{∂{y}} = 5 ⇒ \frac{{∂f}}{{∂y}}(1,3)=5 ∂y∂f=5⇒∂y∂f(1,3)=5
      • 梯度 ∇ f ∇f ∇f(∇ 读 nabla)就是由偏导数组成的向量: ∇ f ( 1 , 3 ) = ( 2 , 5 ) ∇f(1,3)=(2,5) ∇f(1,3)=(2,5)。这告诉我们在点 (1,3)处,函数变化最快的方向是 (2,5)。
  4. 目标函数: 也称为假设函数(hypothesis function),它是为了拟合输入样本的函数。需要拿它跟真实值计算loss。
    1. 回归任务(线性回归)的目标函数是 h θ ( x ) = θ 0 + θ 1 x 1 + . . . + θ n x n = ∑ i = 0 n θ i x i h_{\theta}(x)=\theta_0+\theta_1{x_1}+...+\theta_n{x_n} = \sum_{i=0}^{n}\theta_{i}x_{i} hθ(x)=θ0+θ1x1+...+θnxn=∑i=0nθixi
    2. 二分类任务(sigmoid)的目标函数是 h θ ( x ) = 1 1 + e − ∑ i = 1 n θ i x i h_{\theta}(x)=\frac{1}{1+e^{-\sum_{i=1}^{n}\theta_{i}x_{i}}} hθ(x)=1+e−∑i=1nθixi1
    3. 多分类任务:在深度学习中,特别是神经网络的分类层,常使用Softmax函数。对于一个具有K个类别的问题,Softmax 函数将输入的 K 维向量转换为一个表示每个类别概率的 K 维向量。形式如下: S o f t m a x ( z ) i = e z i ∑ j = 1 m e z j Softmax(z)i=\frac{e^{z_i}}{\sum{j=1}^{m}{e^{z_j}}} Softmax(z)i=∑j=1mezjezi
      1. 其中 z z z是输入向量的未归一化分数, S o f t m a x ( z ) i Softmax(z)_i Softmax(z)i表示第 i 个类别的预测概率。
  5. 损失函数:
    1. 交叉熵损失函数(Cross-Entropy Loss):
      1. 定义: 交叉熵是信息论中的概念,用于度量两个概率分布之间的差异。在神经网络中,交叉熵常用于分类问题。对于二分类问题,损失函数为二分类交叉熵;对于多分类问题,损失函数为多分类交叉熵。
      2. 二分类: J ( θ ) = − ( y l o g ( h θ ( x ) ) + ( 1 − y ) l o g ( 1 − h θ ( x ) ) ) J(\theta)=−(ylog(h_{\theta}(x))+(1−y)log(1−h_{\theta}(x))) J(θ)=−(ylog(hθ(x))+(1−y)log(1−hθ(x)))
      3. 多分类(softmax): J ( θ ) = − ∑ i = 1 m y i l o g ( a i ) J(\theta) = -\sum_{i=1}^{m}y_{i}log(a_i) J(θ)=−∑i=1myilog(ai),其中 y i y_i yi表示第i个分类的真实概率, a i a_i ai表示第 i i i 个分类的预估概率(也就是Softmax求出的第 i i i个值)。但在现实中的多分类任务中通常只有一个结果,就是说某一个分类为1其余都为0,假设训练数据的真实输出为第 j j j个为1,损失函数变成: J ( θ ) = − l o g ( a j ) J(\theta) = -log(a_j) J(θ)=−log(aj)
    2. 均方差损失函数(Mean Squared Error,MSE):
      1. 定义: 均方差损失函数用于回归问题,它度量实际输出与期望输出之间的平方差。在神经网络中,常用于输出是连续数值的问题。
      2. 公式: J ( θ ) = 1 2 n ∑ i = 1 n ( y i − h θ ( x ) i ) 2 J(\theta) = \frac{1}{2n}\sum_{i=1}^{n}{(y_{i}-h_{\theta}(x)i)^{2}} J(θ)=2n1∑i=1n(yi−hθ(x)i)2*,其中* y i y_i yi表示第 i i i个样本的真实值, h θ ( x ) i h_{\theta}(x)_i hθ(x)i表示第 i i i个样本的预估值。
  6. 学习率: 每一步沿梯度反方向前进的长度,该参数过大容易越过最优解,过小则收敛速度慢,在实际应用中可以多取一些值,从大到小分别运行算法,观察迭代效果,如果损失函数在变小说明取值有效,否则要增大步长。

梯度下降法详解

通过上面的介绍,我们已经对损失函数有了一定的了解,并且可以沿着梯度的反方向一步步迭代求解,得到最小化的损失函数,举个下山的例子,人如果要最快下到山底,每一步都沿着当前最陡峭的方向(也就是梯度的反方向)下降,当然这样走下去,有可能我们不能走到山脚,而是到了某一个局部的山峰低处。

上面的图像(来源:Andrew Ng Machine Learning)是损失函数 J J J的曲面,这里的变量有两个 θ 0 \theta_0 θ0和 θ 1 \theta_1 θ1,所以画出来是三维的,如果有更多的参数则是更高维空间的曲面。

接下来我拿线性回归举例一步步演示如何通过梯度下降法实现参数的迭代更新。

  1. 线性回归的目标函数是 h θ ( x ) = ∑ i = 1 n θ i x i h_{\theta}(x)=\sum_{i=1}^{n}\theta_{i}x_{i} hθ(x)=∑i=1nθixi,损失函数是 J ( θ ) = 1 2 n ∑ i = 1 n ( y i − h θ ( x ) i ) 2 J(\theta) = \frac{1}{2n}\sum_{i=1}^{n}{(y_{i}-h_{\theta}(x)_i)^{2}} J(θ)=2n1∑i=1n(yi−hθ(x)i)2
  2. 损失函数的梯度是:
    ∂ J ( θ 0 , θ 1 . . . , θ n ) ∂ θ i = ∂ J ( θ 0 , θ 1 . . . , θ n ) ∂ θ 0 , ∂ J ( θ 0 , θ 1 . . . , θ n ) ∂ θ 1 , . . . , ∂ J ( θ 0 , θ 1 . . . , θ n ) ∂ θ n = 1 n ∑ j = 1 n ( y j − h θ ( x ) j ) x i ( j ) \frac{∂J(\theta_0,\theta_1...,\theta_n)}{∂\theta_i} = \\frac{∂J(\\theta_0,\\theta_1...,\\theta_n)}{∂\\theta_0}, \\frac{∂J(\\theta_0,\\theta_1...,\\theta_n)}{∂\\theta_1},...,\\frac{∂J(\\theta_0,\\theta_1...,\\theta_n)}{∂\\theta_n} = \frac{1}{n}\sum_{j=1}^{n}{(y_{j}-h_{\theta}(x)_j)}x_i^{(j)} ∂θi∂J(θ0,θ1...,θn)=∂θ0∂J(θ0,θ1...,θn),∂θ1∂J(θ0,θ1...,θn),...,∂θn∂J(θ0,θ1...,θn)=n1j=1∑n(yj−hθ(x)j)xi(j)
  • 注意这里的 j j j是第 j j j个样本, x i ( j ) x_i^{(j)} xi(j) 是第 j j j个样本的第 i i i个特征。
  • 当前点的梯度方向是由所有的样本决定的。
  1. 有了梯度后就可以结合学习率(步长)去更新 θ \theta θ参数: θ i = θ i − α 1 n ∑ j = 1 n ( y j − h θ ( x ) j ) x i ( j ) \theta_{i} = \theta_{i} - \alpha\frac{1}{n}\sum_{j=1}^{n}{(y_{j}-h_{\theta}(x)_j)}x_i^{(j)} θi=θi−αn1∑j=1n(yj−hθ(x)j)xi(j)
    • 其中 α \alpha α是学习率
  2. 如果所有的 θ \theta θ在当次的下降距离都小于阈值 ϵ \epsilon ϵ则计算停止。

链式求导

目前比较火的深度神经网络的隐藏层非常多,在如此多层的网络结构中要想实现反向传播就要用到链式求导,从上面这张图中随便选一个感知机,它是由 w 、 b 、 z 和 a w、b、z和a w、b、z和a四部分组成。

  • z i l = w i l ∗ a l − 1 + b i l z_i^{l} = w_i^{l} * a^{l-1} + b_i^{l} zil=wil∗al−1+bil
  • w i l 表示第 l 层的第 i 个感知机的 w 参数,由于是全连接,所以 w 的个数等于 l − 1 层的感知机数量,即 w i l 可拆解为 w i , 1 \[ l , w i , 2 l , . . . , w i , n l ] w_i^{l}表示第 l层的第 i个感知机的 w 参数,由于是全连接,所以w的个数等于 l-1层的感知机数量,即 w_i^{l}可拆解为 w_{i,1}\^{\[l},w_{i,2}^{l},...,w_{i,n}^{l}] wil表示第l层的第i个感知机的w参数,由于是全连接,所以w的个数等于l−1层的感知机数量,即wil可拆解为wi,1\[l,wi,2l,...,wi,nl]
  • a l − 1 则是 l − 1 层的每个感知机的输出。 a^{l-1}则是 l-1层的每个感知机的输出。 al−1则是l−1层的每个感知机的输出。
  • b i l 是第 l 层第 i 个感知机的偏置项。 b_i^{l}是第 l层第 i个感知机的偏置项。 bil是第l层第i个感知机的偏置项。
  • 每个感知机的输出 a i l = σ ( z i l ) a_i^{l} = \sigma(z_i^{l}) ail=σ(zil),其中 σ \sigma σ是激活函数,作用是非线性变换,提高模型拟合能力。

损失函数 J ( y ( k ) , a l ( k ) ) J(y^{(k)}, a^{l(k)}) J(y(k),al(k))中的 y ( k ) y^{(k)} y(k)表示第 k k k个样本的真实值, a l ( k ) a^{l(k)} al(k)表示第 k k k个样本的第 l l l层的输出(方括号表示网络层,圆括号表示样本)。为了提升理解我把最后的 J ( y ( k ) , a l ( k ) ) J(y^{(k)},a^{l(k)}) J(y(k),al(k))当做第 l + 1 l+1 l+1 ,它的损失是由第 l l l层的输出也就是 a l a^{l} al导致的,此时求第 l + 1 l+1 l+1层损失函数 J J J的梯度:

  • ∇ J l + 1 = ∂ J l + 1 ∂ a l \nabla{J^{l+1}} = \frac{∂{J^{l+1}}}{∂a^{l}} ∇Jl+1=∂al∂Jl+1
  • 由于 a l = σ ( z l ) = σ ( w l ∗ a l − 1 + b l ) a^{l} = \sigma(z^{l}) = \sigma(w^{l} * a^{l-1} + b^{l}) al=σ(zl)=σ(wl∗al−1+bl),所以 J J J的梯度就是分别对 w l w^{l} wl a l − 1 a^{l-1} al−1 b l b^{l} bl求偏导,需要链式求导将其展开,即
    • ∂ J l + 1 ∂ a l = ( ∂ J l + 1 ∂ w l , ∂ J l + 1 ∂ a l − 1 , ∂ J l + 1 ∂ b l ) = ( ∂ J l + 1 ∂ σ ∂ σ ∂ z l ∂ z l ∂ w l , ∂ J l + 1 ∂ σ ∂ σ ∂ z l ∂ z l ∂ a l − 1 , ∂ J l + 1 ∂ σ ∂ σ ∂ z l ∂ z l ∂ b l ) \frac{∂J^{l+1}}{∂a^{l}} = (\frac{∂J^{l+1}}{∂w^{l}},\frac{∂J^{l+1}}{∂a^{l-1}},\frac{∂J^{l+1}}{∂b^{l}}) = (\frac{∂J^{l+1}}{∂\sigma}\frac{∂\sigma}{∂z^{l}}\frac{∂z^{l}}{∂w^{l}},\frac{∂J^{l+1}}{∂\sigma}\frac{∂\sigma}{∂z^{l}}\frac{∂z^{l}}{∂a^{l-1}}, \frac{∂J^{l+1}}{∂\sigma}\frac{∂\sigma}{∂z^{l}}\frac{∂z^{l}}{∂b^{l}}) ∂al∂Jl+1=(∂wl∂Jl+1,∂al−1∂Jl+1,∂bl∂Jl+1)=(∂σ∂Jl+1∂zl∂σ∂wl∂zl,∂σ∂Jl+1∂zl∂σ∂al−1∂zl,∂σ∂Jl+1∂zl∂σ∂bl∂zl)
    • 首先 J J J先对 σ \sigma σ求导, σ \sigma σ再对 z z z求导, z z z最后分别对 w 、 a 和 b w、a和b w、a和b求导,由于 w w w是一个向量,所以对 w w w求导就是对其中每个元素求偏导,即: ∂ J l + 1 ∂ w l = ( ∂ J l + 1 ∂ w 1 l , ∂ J l + 1 ∂ w 2 l , . . . , ∂ J l + 1 ∂ w i l ) \frac{∂J^{l+1}}{∂w^{l}} = (\frac{∂J^{l+1}}{∂w_1^{l}},\frac{∂J^{l+1}}{∂w_2^{l}},...,\frac{∂J^{l+1}}{∂w_i^{l}}) ∂wl∂Jl+1=(∂w1l∂Jl+1,∂w2l∂Jl+1,...,∂wil∂Jl+1), a 和 b a和b a和b也是这样就先不展开了。

有了梯度后接下来对参数更新:
w 1 l = w 1 l − α ∂ J l + 1 ∂ w 1 l , b 1 l = b 1 l − α ∂ J l + 1 ∂ b 1 l w_1^{l} = w_1^{l} - \alpha{\frac{∂J^{l+1}}{∂w_1^{l}}}, b_1^{l} = b_1^{l} - \alpha{\frac{∂J^{l+1}}{∂b_1^{l}}} w1l=w1l−α∂w1l∂Jl+1,b1l=b1l−α∂b1l∂Jl+1
w 2 l = w 2 l − α ∂ J l + 1 ∂ w 2 l , b 2 l = b 2 l − α ∂ J l + 1 ∂ b 2 l w_2^{l} = w_2^{l} - \alpha{\frac{∂J^{l+1}}{∂w_2^{l}}}, b_2^{l} = b_2^{l} - \alpha{\frac{∂J^{l+1}}{∂b_2^{l}}} w2l=w2l−α∂w2l∂Jl+1,b2l=b2l−α∂b2l∂Jl+1

.

.
w i l = w i l − α ∂ J l + 1 ∂ w i l , b i l = b i l − α ∂ J l + 1 ∂ b i l w_i^{l} = w_i^{l} - \alpha{\frac{∂J^{l+1}}{∂w_i^{l}}}, b_i^{l} = b_i^{l} - \alpha{\frac{∂J^{l+1}}{∂b_i^{l}}} wil=wil−α∂wil∂Jl+1,bil=bil−α∂bil∂Jl+1

由于 ∂ J l + 1 ∂ a l − 1 \frac{∂J^{l+1}}{∂a^{l-1}} ∂al−1∂Jl+1没有办法直接更改,它依赖前面 l − 1 l-1 l−1层的输出也就是 a l − 1 a^{l-1} al−1的改变,所以可以把 ∂ J l + 1 ∂ a l − 1 \frac{∂J^{l+1}}{∂a^{l-1}} ∂al−1∂Jl+1当做第 l l l层损失函数的值,也就是 J l = ∂ J l + 1 ∂ a l − 1 J^{l} = \frac{∂J^{l+1}}{∂a^{l-1}} Jl=∂al−1∂Jl+1,这样就实现了损失值从 l + 1 l+1 l+1层到 l l l层的传导,整个过程循环迭代起来。

常见梯度下降法

根据更新参数时使用的样本量,梯度下降法可以分为批量、小批量和随机梯度下降法。

  1. 批量梯度下降法(BGD)

    • 该方法的标志是使用该batch的所有样本来进行更新:

      θ i = θ i − α 1 n ∑ j = 1 n ( y j − h θ ( x ) j ) x i ( j ) \theta_{i} = \theta_{i} - \alpha\frac{1}{n}\sum_{j=1}^{n}{(y_{j}-h_{\theta}(x)_j)}x_i^{(j)} θi=θi−αn1∑j=1n(yj−hθ(x)j)xi(j)

    • 当训练样本量级非常大时,每次参数更新都要使用所有的样本显然会花费较长计算时间,导致整体的训练效率低下,这种方法仅存在理论层面。

  2. 随机梯度下降法(SGD)

    • 该方法的标志是从该batch中随机选取一个样本j来求梯度。对应的更新公式是:

      θ i = θ i − α ( y j − h θ ( x ) j ) x i ( j ) \theta_{i} = \theta_{i} - \alpha{(y_{j}-h_{\theta}(x)_j)}x_i^{(j)} θi=θi−α(yj−hθ(x)j)xi(j)

    • 由于每次随机选一个样本计算梯度更新参数,训练速度很快,但由于随机选的样本有一定的不确定性,可能会导致非最优解。

  3. 小批量梯度下降法(MBGD)

    • 这种方法是批量和随机两种方法的折中,比如统计一个地区居民的平均身高,现实中不太可能把所有的用户都统计到,而是随机选出一批用户,计算这批用户的平均身高来代表这一地区,更新公式是:

      θ i = θ i − α 1 m ∑ j = 1 m ( y j − h θ ( x ) j ) x i ( j ) \theta_{i} = \theta_{i} - \alpha\frac{1}{m}\sum_{j=1}^{m}{(y_{j}-h_{\theta}(x)_j)}x_i^{(j)} θi=θi−αm1∑j=1m(yj−hθ(x)j)xi(j),其中 m m m表示随机选出的 m m m个用户。

在实际业务中,如果数据集非常大但内存有限,或者需要处理在线学习问题,那么随机梯度下降可能是一个合适的选择。如果有足够的计算资源,且数据集规模适中,那么可以尝试小批量梯度下降甚至批量梯度下降。

最后

通过前面的介绍,我相信大家对梯度下降法有了深入的了解。在实际应用中,我们通常对模型的训练和收敛速度有着较高的要求。除了前面提到的从样本集大小的角度考虑,还有一些优化方法可以在提升收敛速度方面发挥重要作用,其中包括动量法、Adagrad、RMSprop 和 Adam 等。

在接下来的文章中,我将深入介绍梯度下降中的各类优化改进方法,以帮助大家更好地理解如何调整模型的训练过程,提高训练效率。敬请期待。

相关推荐
bIo7lyA8v1 分钟前
算法复杂度评估的实验统计方法与可视化的技术8
算法
李老师讲编程22 分钟前
中国电子学会图形化2020.12月Scratch三级考级题
算法·scratch·信息学奥赛·图形化编程·scratch素材
退休倒计时43 分钟前
【每日一题】LeetCode 53. 最大子数组和 TypeScript
数据结构·算法·leetcode·typescript
旖-旎1 小时前
FloodFill(图像渲染)(1)
c++·算法·深度优先·力扣
戴西软件1 小时前
戴西 DLM 许可授权管理系统:破解无网络环境下工业软件授权难题,助力制造企业降本增效
网络·人工智能·python·深度学习·程序人生·算法·制造
2601_961875241 小时前
法考资料2026|全套|资料已整理
数据结构·算法·链表·贪心算法·eclipse·线性回归·动态规划
无限码力1 小时前
美团研发岗 4月18号笔试真题 - 坐标
算法·美团笔试真题·美团笔试题·美团研发岗笔试题·美团研发岗4月18号真题
有点。2 小时前
C++倍增法(练习题)
c++·算法
智者知已应修善业3 小时前
【51单片机8位数码管同时倒计时从9999】2024-1-25
c++·经验分享·笔记·算法·51单片机