三分钟入门了解什么是梯度下降
梯度下降学习可观看以下视频:
吴恩达机器学习 - 网易云课堂
前言
在开始探讨梯度下降之前,先引入一个实际问题:工厂成本最优化,即工厂如何做决策(控制决策变量)使总成本最低?
当问题中只包含一个决策变量(比如产量 \(x\))时,我们可以画出二维平面图——横轴是产量,纵轴是总成本,通过对曲线上的点求导或观察曲线最低点就能找到最优解。
但现实中的优化问题往往有多个变量,例如:
-
二维参数问题:成本函数同时依赖于产量 \(x\) 和原材料采购价 \(y\),记作 \(C(x,y)\)。
这时可以在三维空间画图(\(x\) 轴、\(y\) 轴、\(C\) 轴),图形像一个山谷。我们要找的是“谷底” (\(x^∗\),\(y^∗\)),使成本最低。 -
三维参数问题:假如再增加一个变量 \(z\)(比如设备运行时间),成本函数变成 \(C(x,y,z)\)。
我们无法在四维空间中直观作图,但数学上依然可以形象的定义“梯度”并搜索最小值。
当参数数量过大,无法绘制直观的图像,该如何找到最优解呢?这就需要梯度下降法这类数值优化算法。下面用几个简单例子说明它如何解决问题。
1.一维参数问题
假设总成本 \(C(x)\) 只取决于产量 \(x\)(单位:千件),且函数形式为:
其中 \(C\) 的单位是万元。我们想找到使总成本最低的产量 \(x^*\)。
(1) 解析求解(求导法)
对 \(C(x)\) 求导:\(C'(x) = 2x - 4\)
令导数为零:\(2x - 4 = 0 \quad \Rightarrow \quad x = 2\)
二阶导数 \(C''(x) = 2 > 0\),说明 \(x=2\) 是极小值点。
最优产量:\(x^* = 2\)(千件),最低成本:
(2) 图形示意(二维平面)
横轴为产量 \(x\),纵轴为总成本 \(C(x)\)。曲线是一个开口向上的抛物线,最低点在 \((2, 3)\)。

绘图代码如下:
点击查看代码
import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
def C(x):
return x**2 - 4*x + 7
x = np.linspace(0, 4, 200)
y = C(x)
plt.figure(figsize=(8, 5))
plt.plot(x, y, 'b-', linewidth=2, label=r'$C(x)=x^2-4x+7$')
x_min = 2
y_min = C(x_min)
plt.plot(x_min, y_min, 'ro', markersize=8, label=f'最低点 ({x_min}, {y_min})')
plt.annotate(f'({x_min}, {y_min})',
xy=(x_min, y_min),
xytext=(x_min+0.3, y_min+0.5),
arrowprops=dict(arrowstyle='->', color='gray'))
plt.xlabel('产量 x (千件)', fontsize=12)
plt.ylabel('总成本 C(x) (万元)', fontsize=12)
plt.title('工厂成本最优化:一维成本函数曲线', fontsize=14)
plt.grid(True, linestyle='--', alpha=0.6)
plt.legend()
plt.show()
(3) 用梯度下降(一维情况就是“导数下降”)求解
在多元问题中,梯度是一个向量,指向函数值上升最快的方向;负梯度方向则是下降最快的方向。
虽然一维问题不需要梯度下降,但为了统一思想,我们可以模拟。
在一维情况下,“梯度”退化为导数 \(C'(x)\)。若 \(C'(x)>0\),函数在 \(x\) 处递增,要减小 \(C(x)\) 应向左移动(减小 \(x\));若 \(C'(x)<0\),应向右移动。
我们假设:
- 初始点 \(x_0 = 4\),学习率 \(\eta = 0.1\)。
- 梯度(即导数)\(C'(x) = 2x - 4\)。
- 更新规则:$$x_{\text{new}} = x_0 - \eta \cdot C'(x_0)$$
其中 \(η>0\) 称为学习率,控制每一步的步长。
第一次迭代:
计算过程:\(C'(4)=4\)(正值),所以负梯度方向为负,\(x\) 减小,从 4 降至 3.6。
第二次:
此时 \(C'(3.6)=3.2>0\),继续向左移动。
多次迭代后逐渐逼近 \(x=2\)。这就是梯度下降在一维问题中的体现。
关键思想
- 方向由导数符号决定:若导数为正,说明当前点位于最优解右侧,需要减小 \(x\);若导数为负,则需要增大 \(x\)。
- 步长受学习率控制:\(η\) 太大可能导致跳过最优点(震荡),太小则收敛缓慢。
2. 二维参数问题举例
假设成本函数为
这是一个开口向上的抛物面,最低点在 \((0,0)\),最小成本为 \(0\)。
(1) 计算梯度
由 \(C(x,y)=x^{2}+y^{2}\)
得 \(\frac{\partial C}{\partial x} = 2x,\qquad \frac{\partial C}{\partial y} = 2y\)
故
(2) 初始化参数
选取初始点 \((x_0, y_0) = (3, 2)\)
学习率 \(\eta = 0.1\)
(3) 第一次迭代(手工模拟)
更新规则:
得到新点
比较两次的成本:
成本从 \(13\) 下降到 \(8.32\),并且新点 \((2.4,1.6)\) 到原点的距离更短,说明确实在向最小值靠近。
(4) 多次迭代的效果
如果继续迭代,点列将沿着一条直线逼近原点 $$(0,0)$$。例如第二次迭代:
成本降至 $$1.92{2}+1.28=3.6864+1.6384=5.3248$$依此类推,随着迭代次数增加,\((x_k, y_k) \to (0,0)\),成本趋近于 \(0\)。

说明
- 左侧三维图:彩色曲面代表成本函数,红色点线表示从 (3,2) 出发,沿最陡下降方向(负梯度)逐步走向谷底 (0,0)。
- 右侧等高线图:圆圈代表成本值相同的等高线,下降路径垂直于等高线(梯度方向),最终收敛到中心。
绘图代码如下:
点击查看代码
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# 设置中文字体(避免字体缺失问题)
plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows
# plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei'] # Linux
plt.rcParams['axes.unicode_minus'] = False
# 定义成本函数
def C(x, y):
return x**2 + y**2
# 梯度函数
def grad_C(x, y):
return np.array([2*x, 2*y])
# 梯度下降迭代(手动模拟多步)
def gradient_descent(start, learning_rate, steps):
path = [start]
for _ in range(steps):
g = grad_C(path[-1][0], path[-1][1])
new_point = path[-1] - learning_rate * g
path.append(new_point)
return np.array(path)
# 参数设置
start = (3, 2)
eta = 0.1
steps = 5 # 迭代5步
path = gradient_descent(start, eta, steps)
# ------------------ 1. 绘制三维曲面 + 下降路径 ------------------
fig = plt.figure(figsize=(12, 5))
# 子图1:3D曲面
ax1 = fig.add_subplot(121, projection='3d')
x_vals = np.linspace(-1, 4, 100)
y_vals = np.linspace(-1, 3, 100)
X, Y = np.meshgrid(x_vals, y_vals)
Z = C(X, Y)
ax1.plot_surface(X, Y, Z, cmap='viridis', alpha=0.7, edgecolor='none')
ax1.scatter(path[:,0], path[:,1], C(path[:,0], path[:,1]),
c='red', s=50, label='梯度下降路径点')
ax1.plot(path[:,0], path[:,1], C(path[:,0], path[:,1]),
'r--', linewidth=2, label='下降轨迹')
ax1.scatter(*start, C(*start), color='blue', s=80, label='起始点 (3,2)')
ax1.scatter(0, 0, 0, color='green', s=100, label='最优解 (0,0)')
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax1.set_zlabel('成本 C(x,y)')
ax1.set_title('三维山谷图与梯度下降路径')
ax1.legend()
# 子图2:等高线图 + 下降路径
ax2 = fig.add_subplot(122)
contour = ax2.contour(X, Y, Z, levels=20, cmap='viridis')
ax2.clabel(contour, inline=True, fontsize=8)
ax2.plot(path[:,0], path[:,1], 'ro-', markersize=6, linewidth=2, label='下降路径')
ax2.scatter(*start, color='blue', s=80, label='起始点 (3,2)')
ax2.scatter(0, 0, color='green', s=100, label='最优解 (0,0)')
ax2.set_xlabel('x')
ax2.set_ylabel('y')
ax2.set_title('等高线图(山谷投影)')
ax2.legend()
ax2.grid(True, linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()
# 打印各步坐标
print("梯度下降迭代过程:")
for i, point in enumerate(path):
print(f"第{i}步: ({point[0]:.4f}, {point[1]:.4f}), 成本 = {C(*point):.4f}")
3. 三维参数问题举例
设成本函数为
\(C(x,y,z) = (x-1)^2 + (y+2)^2 + z^2\)
三个变量独立,理论最优解是 \(x=1, y=-2, z=0\),最小成本 \(0\)。
梯度:
\(\nabla C = \left( 2(x-1),\; 2(y+2),\; 2z \right)\)
从初始点 \((0,0,0)\) 开始,学习率 \(\eta=0.2\),一次更新:
新点 \((0.4, -0.8, 0)\) 更靠近 \((1,-2,0)\)。继续迭代最终收敛。
关键点:即使有 3 个参数,我们无法画出四维图像,但梯度下降的计算过程与二维参数时完全一样——只需把梯度向量的长度扩展到 3(或任意维度 \(n\)),每次沿负梯度方向走一小步即可。
总结
| 参数个数 | 可视化可能性 | 寻找最优解的方法 |
|---|---|---|
| 1 | 二维平面曲线 | 求导或观察图形 |
| 2 | 三维曲面(山谷形) | 梯度下降 / 求偏导方程组 |
| 3 及以上 | 无法直接画图 | 梯度下降(或其它数值优化算法) |
| 核心概念 | 说明 |
|---|---|
| 梯度方向 | 函数值上升最快的方向,负梯度即下降最快方向 |
| 学习率 | 控制每步步长,太大震荡,太小收敛慢 |
| 更新规则 | \(x_{\text{new}} = x_0 - \eta \cdot \nabla C(x_0)\) |
梯度下降的核心思想不依赖于维度——只要知道每个参数对应的偏导数(梯度分量),就能一步步“走下山谷”。这就是它在机器学习和复杂工程优化中被广泛使用的原因。
📢 声明:本文借助AI辅助工具进行资料整理与初稿生成,所有内容均经过作者本人的详细核对、修改与编排,文责自负。

浙公网安备 33010602011771号