优化问题入门 -- 目标函数、变量与约束
优化是找到让目标函数取得最小值的参数。AI 训练 = 优化损失函数。
概念解析
优化问题三要素
| 要素 | 含义 | AI 训练中的对应 |
|---|---|---|
| 目标函数 | 要最小化的函数 | 损失函数 J(θ) |
| 决策变量 | 可以调整的量 | 模型参数 θ |
| 约束条件 | 变量的限制 | 通常无约束 |
凸函数 vs 非凸函数
凸函数
碗形,任意两点连线在曲线上方
局部最优 = 全局最优
如线性回归的 MSE 损失
非凸函数
有多个谷底和山峰
只能找到局部最优
如深度神经网络损失
深度神经网络的损失函数是高度非凸的——但实践中梯度下降找到的局部最优通常已经足够好了。
生活例子
选最短路线
从家到学校有三条路:5 分钟、8 分钟、12 分钟。
决策变量 = 选哪条路,目标函数 = 花的时间,目标 = 最小化时间。
这很简单——三条路都试试就行。但 AI 模型有数百万参数,不可能枚举所有组合。
所以才需要梯度下降——沿着梯度指引方向一步步靠近最优解。
Python 动手实践
实例
import numpy as np
# 凸函数 f(x) = x^2,全局最优在 x=0
# 非凸函数 f(x) = sin(x) + 0.1*x^2,有多个局部最优
def f_convex(x): return x**2
def f_nonconvex(x): return np.sin(x) + 0.1*x**2
# 从不同起点做梯度下降(下一章详解),非凸可能收敛到不同局部最优
print("非凸函数从不同起点可能到达不同的局部最优")
print("这是深度学习调参需要注意的")
# 凸函数 f(x) = x^2,全局最优在 x=0
# 非凸函数 f(x) = sin(x) + 0.1*x^2,有多个局部最优
def f_convex(x): return x**2
def f_nonconvex(x): return np.sin(x) + 0.1*x**2
# 从不同起点做梯度下降(下一章详解),非凸可能收敛到不同局部最优
print("非凸函数从不同起点可能到达不同的局部最优")
print("这是深度学习调参需要注意的")
运行输出:
非凸函数从不同起点可能到达不同的局部最优 这是深度学习调参需要注意的
凸函数 vs 非凸函数 3D 对比
下方左图是凸函数 f(x,y)=x²+y²(碗形,唯一全局最优),右图是非凸函数(多个局部最优)。
旋转视角可以直观感受「凸 = 单一谷底」和「非凸 = 多个谷底」的区别:
AI 中的应用场景
整个训练过程 = 大规模优化
训练一个 GPT 级别的模型,就是在找一个百万亿维空间中的最优点。损失函数 J(θ) 是这个空间中的一个超曲面,梯度下降在这个曲面上逐步下行。整个训练可能持续数周,消耗数百万美元的算力——只为找到一组让损失尽可能小的参数。
凸 vs 非凸:理论与实践
线性回归和 SVM 的优化问题是凸的——梯度下降保证找到全局最优。但深度神经网络的损失曲面是高度非凸的,有无数局部最优和鞍点。然而实践中,SGD 找到的局部最优通常泛化性能很好——大 batch 倾向于收敛到「尖锐」的局部最优(泛化差),小 batch 倾向于「平坦」的局部最优(泛化好)。
损失景观可视化
研究者通过将高维损失曲面投影到 2D,发现深度网络的损失景观有「峡谷」结构——虽然非凸,但沿峡谷底部走下去几乎总能到达很好的解。这解释了为什么随机初始化 + SGD 在深度学习中如此鲁棒。
