梯度下降不是直觉,而是必然

54 阅读3分钟

在机器学习的世界里,我们经常听到“梯度下降”(Gradient Descent)这个词。它是训练神经网络的引擎,是模型变聪明的核心动力。

但是,当你开始翻看教材或代码时,会觉得梯度下降直观易懂。然而,当你真的想要细致理解它时,却发现大多数教程不是照本宣科地复述定义,就是直接甩出一张参数表格。这种“快餐式”讲解,往往让人知其然,却不知其所以然。(我一开始就是晕乎乎的)

我需要说明的是,梯度下降绝对不是凭直觉拍脑袋想出来的,它背后有非常严谨的数学基础。很多教材只告诉你“梯度指向上升最快,所以反方向下降”, 但并没告诉你: 这个结论本身就是从泰勒展开和最优化原理推导出来的!!!

在本文中,我不会跳过任何关键细节。我们将一起从头走一遍梯度下降的完整逻辑:不回避数学,不回避伪代码,不依赖黑箱类比,更不会用一张表格敷衍了事——只为让你真正“看见”梯度是如何一步步工作的。

一、背景:我们在做什么?

训练模型的过程,其实就是 找最低点 的过程。

想象你被困在一座高山上(损失函数 Loss Function),四周雾气缭绕,你看不到山脚在哪。你的目标是用最快的速度下到山谷最低处(Loss 最小化)。

你手上有一个指南针(梯度),它能告诉你当前位置最陡峭的下坡方向。

梯度下降的核心公式永远只有这一个:

新位置=旧位置步长×下坡方向新位置=旧位置−步长×下坡方向

但 BGD、SGD、Mini-batch GD 的区别在于:你到底要把周围的地形看多清楚,才敢迈出这一步?

二、梯度下降

直接上公式:

wnew=woldηJ(wold)\mathbf{w}_{new} = \mathbf{w}_{old}−η \cdot ∇J(\mathbf{w}_{old})

为什么梯度下降公式长这样?公式是怎么来的?

2.1 我们的目标是什么?

假设我们训练一个模型,它有参数 w\mathbf{w},我们希望让损失函数 J(w)J(\mathbf{w}) 尽可能小。

也就是说,我们希望找到让 J(w)J(\mathbf{w}) 最小的 w\mathbf{w} ,这是一道最优化问题。

2.2 在当前参数 wold\mathbf{w}_{old} 附近,损失函数 J(w)J(\mathbf{w}) 长什么样?(泰勒展开,线性近似)

在点 woldw_{old} 附近,我们用 泰勒展开 把损失函数近似为:

J(wold+Δw)J(wold)+J(wold)TΔwJ(\mathbf{w}_{\text{old}} + \Delta \mathbf{w}) \approx J(\mathbf{w}_{\text{old}}) + \nabla J(\mathbf{w}_{\text{old}})^T \Delta \mathbf{w}

如果你觉得上面这个公式不太能看懂,那么请看下面的这个公式

f(x+Δx)f(x)+f(x)Δxf(x+Δx)≈f(x)+f^{\prime}(x) \cdot Δx

这下一定看懂了吧!!!

我们再来一遍:

J(wold+Δw)J(wold)+J(wold)TΔwJ(\mathbf{w}_{\text{old}} + \Delta \mathbf{w}) \approx J(\mathbf{w}_{\text{old}}) + \nabla J(\mathbf{w}_{\text{old}})^T \Delta \mathbf{w}

这里的含义是:

  • 真实的损失曲面 J(wold)J(\mathbf{w}_{\text{old}}) 可能很复杂
  • ΔwΔ\mathbf{w} 的模长是人为设定的值,我们一般写作 ηη
  • 但是在一个“足够小的区域”里,它可以用一个线性函数(关于 ΔwΔ\mathbf{w} 的线性函数)近似

这个线性近似,是所有梯度方法的基础。

2.3 要下降得最多,应该沿哪个方向?

回到上面提到的梯度下降公式,J(wold+Δw)J(\mathbf{w}_{\text{old}} + \Delta \mathbf{w}) 是改变了 Δw\Delta \mathbf{w} 之后的损失函数值,与改变之前的值 J(wold)J(\mathbf{w}_{\text{old}}) 相差 J(wold)TΔw\nabla J(\mathbf{w}_{\text{old}})^T \Delta \mathbf{w},那么问题“下降得最多”就转化成了如何让 J(wold)TΔw\nabla J(\mathbf{w}_{\text{old}})^T \Delta \mathbf{w} 最小,我们来分析一下。

J(wold)TΔw=J(wold)Δwcosθ \nabla J(\mathbf{w}_{\text{old}})^T \Delta \mathbf{w} = ||\nabla J(\mathbf{w}_{\text{old}})|| \cdot ||\Delta \mathbf{w}|| \cdot \cos θ

我们需要注意的是,J\nabla Jw\mathbf{w} 都是向量,J\nabla J 的大小和方向是固定的,J(wold)\nabla J(\mathbf{w}_{\text{old}}) 代表的是目前的损失值的情况,自然是一个定数。而 w\mathbf{w} 是需要我们人为干涉的部分。w\mathbf{w} 的大小和方向都是待设定的,其中 w\mathbf{w} 的大小换种说法就是 ΔwΔ\mathbf{w} 的模长,我们会在一开始就设置好,即 Δw=η||Δ\mathbf{w}|| = η,所以式子中只剩下 cosθ\cosθ 还可以改动了。

问题又变成了如何让 cosθ\cosθ 最小,答案已经出来了,cosθ\cosθ 最小为 1-1,带回原式:

J(wold)TΔw=J(wold)Δwcosθ=J(wold)η(1)=ηJ(wold)\begin{aligned} \nabla J(\mathbf{w}_{\text{old}})^T \Delta \mathbf{w} &= \|\nabla J(\mathbf{w}_{\text{old}})\| \cdot \|\Delta \mathbf{w}\| \cdot \cos\theta \\ &= \|\nabla J(\mathbf{w}_{\text{old}})\| \cdot \eta \cdot (-1) \\ &= -\eta \cdot \|\nabla J(\mathbf{w}_{\text{old}})\| \end{aligned}

是不是已经有点那味儿了?

我们别忘了分析这个 cosθ=1cosθ = -1 背后的含义,它告诉了我们“要下降得最多,应该沿哪个方向?”,其实 1-1 是这样来的:

J(wold)TΔw=J(wold)η(1)J(wold)TJ(wold)TJ(wold)ηJ(wold)J(wold)\begin{aligned} \nabla J(\mathbf{w}_{\text{old}})^T \Delta \mathbf{w} &= \|\nabla J(\mathbf{w}_{\text{old}})\| \cdot \eta \cdot (-1) \\ &\Leftarrow \frac{\nabla J(\mathbf{w}_{\text{old}})^T}{\|\nabla J(\mathbf{w}_{\text{old}})^T\|} \cdot \|\nabla J(\mathbf{w}_{\text{old}})\| \cdot \eta \cdot - \frac{\nabla J(\mathbf{w}_{\text{old}})}{\|\nabla J(\mathbf{w}_{\text{old}})\|} \end{aligned}

其中 J(wold)TJ(wold)T\frac{\nabla J(\mathbf{w}_{\text{old}})^T}{\|\nabla J(\mathbf{w}_{\text{old}})^T\|} 代表了 J(wold)T\nabla J(\mathbf{w}_{\text{old}})^T 的方向,当且仅当 Δw\Delta \mathbf{w} 的方向为 J(wold)J(wold)- \frac{\nabla J(\mathbf{w}_{\text{old}})}{\|\nabla J(\mathbf{w}_{\text{old}})\|} 时,可以使得 cosθ=1\cos\theta = -1,此时 Δw\Delta \mathbf{w} 的方向就是损失函数 JJ 的梯度反方向!

我们通过数理推导得知让损失下降最快的方向,就是梯度的反方向。 所以这时,我们应该让 w\mathbf{w} 沿着损失函数 JJ 的梯度反方向进行 优化,这样是局部最高效的!因而可以获得 w\mathbf{w} 的优化公式:

wnew=woldηJ(wold)J(wold)\mathbf{w}_{new} = \mathbf{w}_{old}−η \cdot \frac{\nabla J(\mathbf{w}_{\text{old}})}{\|\nabla J(\mathbf{w}_{\text{old}})\|}

J\nabla J 告诉了我们,w\mathbf{w} 该往哪个方向走。但是,应该不仅仅是方向,我们想一想,J\nabla J 既有方向,又有模长,我们现在只利用到了它的方向,或许模长这个值还蕴藏着一些玄机。目前更新幅度应该只由手动设定的 η(学习率) 来决定,这样下降的会不会太慢了?

我们注意到梯度的模长反映 “局部曲率”“误差陡峭程度”。也就是说,梯度越大,说明你站在“更陡的地方”,自然可以走更大的步长!梯度的模长正是衡量“函数在该方向上变化速度”的量,变化越快(梯度大),你可以走得更多。

从数学直觉上来分析,J(w)J(w) 在附近变化得很快,也就是说:

  • 线性近似的“有效区域”更大
  • 换句话说,你可以走更大步,线性近似仍然有效
  • 所以不会“冲过头”

接下来,我们改变原来的“单位梯度法”,让“地势陡峭程度(梯度模长)”参与步长控制:

wnew=woldηJ(wold)\mathbf{w}_{new} = \mathbf{w}_{old}−η \cdot ∇J(\mathbf{w}_{old})

三、一些反省

做了这么一长串的数学推导,我想告诉大家的是——梯度下降绝对不是凭直觉拍脑袋想出来的(可细品),它背后有非常严谨的数学基础。很多教材只告诉你“梯度指向上升最快,所以反方向下降”, 但并没告诉你: 这个结论本身就是从泰勒展开和最优化原理推导出来的!!!