跳到主要内容

梯度下降

一、直观理解:沿着最陡的下坡方向一步步走​

梯度下降(Gradient Descent)是求解无约束(或简单约束)非线性优化的基本一阶方法。把目标函数 f(x)f(x) 想象成地面高度,当前位置的梯度 ∇f(x)\nabla f(x) 指向上升最快的方向,因此反方向 −∇f(x)-\nabla f(x) 就是局部最陡的下坡方向。

每次沿下坡方向走一小步:

xk+1=xk−αk∇f(xk)x_{k+1}=x_k-\alpha_k\nabla f(x_k)

步长 αk\alpha_k 太小会爬得极慢,太大可能越过谷底甚至发散。算法并不保证一次走到全局最低点:在非凸「山地」上,它可能停在某个局部山谷。

在数学建模中,梯度下降及其变体(动量、Adam 等)常见于参数拟合、机器学习式目标、以及理解 fminunc/fmincon 内部的一阶逻辑。对光滑凸问题,它可靠;对一般非凸问题,需要多初值与谨慎解释。

二、适用场景与优缺点​

类型说明
适用场景目标可微;无约束或仅有简单边界;维度较高、海森矩阵难求;需要理解一阶优化或自写迭代;凸光滑问题的教学与中等精度求解。
核心优点每步只需要梯度,存储 O(n)O(n);实现简单;大规模问题可配合随机梯度;理论清晰。
局限与缺点收敛相对牛顿法更慢(尤其病态谷地);步长敏感;非凸时仅局部最优;有约束时需投影或改用 fmincon 等。

使用前确认:

  1. ff 是否可微,梯度能否解析或可靠数值差分;
  2. 问题是否(近似)凸;
  3. 变量尺度是否统一(否则梯度分量失衡);
  4. 终止精度与最大迭代是否匹配需求。

三、核心原理:下降方向与步长​

1. 无约束问题​

min⁡x∈Rnf(x)\min_{x\in\mathbb{R}^n} f(x)

若 ff 在 x∗x^* 可微且取得局部极小,则一阶必要条件:

∇f(x∗)=0\nabla f(x^*)=0

梯度下降构造点列使 f(xk+1)<f(xk)f(x_{k+1})<f(x_k)(在步长合适时),并希望 ∥∇f(xk)∥→0\|\nabla f(x_k)\|\to 0。

2. 为什么是负梯度​

由一阶泰勒展开:

f(x−α∇f)≈f(x)−α∥∇f∥2f(x-\alpha\nabla f)\approx f(x)-\alpha\|\nabla f\|^2

当 α>0\alpha>0 充分小时,右侧小于 f(x)f(x),故负梯度是下降方向。

3. 步长策略​

  • 固定步长:实现简单,需 0<α<2/L0<\alpha<2/L(LL 为梯度 Lipschitz 常数)一类条件;
  • 线搜索:如 Armijo / 回溯,保证充分下降;
  • 精确线搜索:αk=arg⁡min⁡α>0f(xk−α∇f)\alpha_k=\arg\min_{\alpha>0}f(x_k-\alpha\nabla f),一维问题可做,高维成本高。

4. 收敛性直觉​

  • 强凸且梯度 Lipschitz:线性收敛(误差按比例缩小);
  • 病态二次型(海森条件数大):等高线又长又窄,负梯度来回震荡,收敛慢——这是引入牛顿法、预处理的动机;
  • 非凸:可能收敛到鞍点或局部极小。

5. 投影梯度(简单约束)​

若 x∈Cx\in C 且 CC 为箱约束等易投影集合:

xk+1=PC(xk−αk∇f(xk))x_{k+1}=P_C\bigl(x_k-\alpha_k\nabla f(x_k)\bigr)

一般非线性约束更适合约束优化算法(SQP、内点)而非手写朴素投影。

四、关键决策​

1. 解析梯度 vs 数值梯度​

有公式尽量手写梯度,又快又准。数值差分步长 δ\delta 过大过小都会错。

2. 变量缩放​

若 x1x_1 是 10610^6 量级、x2x_2 是 10−210^{-2},应标准化,否则步长难以共用。

3. 终止条件​

常用:∥∇f∥<ε\|\nabla f\|<\varepsilon、相对函数下降、∥xk+1−xk∥\|x_{k+1}-x_k\|、迭代上限。应组合使用,避免数值噪声导致永不停止。

4. 多初值​

非凸时从多个 x0x_0 启动,取最好结果,并报告初值敏感性。

5. 何时换方法​

中小规模、需要二阶收敛:牛顿 / fminunc 拟牛顿;有复杂约束:fmincon;黑箱不可微:直接搜索或智能优化兜底。

五、MATLAB 示例​

例 1:手写梯度下降求 Rosenbrock 附近的极小(示意)​

Rosenbrock:f(x,y)=(a−x)2+b(y−x2)2f(x,y)=(a-x)^2+b(y-x^2)^2,全局最小在 (a,a2)(a,a^2)。

a = 1; b = 100;
f = @(x) (a - x(1))^2 + b*(x(2) - x(1)^2)^2;
grad = @(x) [ ...
-2*(a - x(1)) - 4*b*x(1)*(x(2) - x(1)^2); ...
2*b*(x(2) - x(1)^2) ...
];

x = [-1.2; 1.0]; % 经典初值
alpha0 = 1e-3;
maxIter = 20000;
tol = 1e-8;
histF = zeros(maxIter, 1);

for k = 1:maxIter
g = grad(x);
histF(k) = f(x);
if norm(g) < tol
histF = histF(1:k);
break;
end
% 回溯线搜索
alpha = 0.5;
c = 1e-4;
while f(x - alpha*g) > f(x) - c*alpha*(g'*g) && alpha > 1e-16
alpha = alpha * 0.5;
end
x = x - alpha * g;
end

fprintf("迭代 %d 次, x=(%.6f, %.6f), f=%.3e, ||g||=%.3e\n", ...
numel(histF), x(1), x(2), f(x), norm(grad(x)));

figure;
semilogy(histF, "LineWidth", 1.2);
xlabel("迭代"); ylabel("f(x)"); title("梯度下降目标值下降曲线");
grid on;

例 2:用 MATLAB 优化工具箱(BFGS 拟牛顿,一阶信息)​

fun = @(x) (1 - x(1))^2 + 100*(x(2) - x(1)^2)^2;
x0 = [-1.2; 1];
opts = optimoptions("fminunc", ...
"Algorithm", "quasi-newton", ...
"SpecifyObjectiveGradient", false, ...
"Display", "iter");
[xOpt, fOpt, exitflag, output] = fminunc(fun, x0, opts);
fprintf("fminunc: exit=%d, x=(%.6f,%.6f), f=%.3e, iter=%d\n", ...
exitflag, xOpt(1), xOpt(2), fOpt, output.iterations);

例 3:带箱约束的投影梯度​

% min (x-3)^2 + (y+1)^2 s.t. 0<=x,y<=1
f = @(x) (x(1)-3)^2 + (x(2)+1)^2;
g = @(x) [2*(x(1)-3); 2*(x(2)+1)];
x = [0.5; 0.5];
for k = 1:200
x = x - 0.1 * g(x);
x = min(max(x, 0), 1); % 投影到 [0,1]^2
end
disp(x'); % 应接近 (1,0)

六、如何解释结果​

报告应包括:

  1. 目标函数与是否凸的判断(或声明未知);
  2. 初值、步长策略、终止容差;
  3. 最终点 x∗x^*、函数值、梯度范数;
  4. 迭代次数与下降曲线;
  5. 多初值时的最好/最差/分散程度;
  6. exitflag(若用工具箱)含义;
  7. 约束问题中是否满足边界/约束。

非凸时表述为「求得的局部极小」,不要写「全局最优」,除非有凸性或全局方法支持。

七、常见误区​

1. 步长固定过大导致发散​

目标值震荡上升时,首先减小步长或加回溯。

2. 把梯度下降当全局优化器​

多峰函数必须多起点或换全局策略。

3. 忽略量纲​

未缩放变量会导致某些方向几乎不动。

4. 数值梯度步长乱设​

δ=1\delta=1 对单位量级变量过大;δ=10−20\delta=10^{-20} 会淹没于浮点误差。

5. 有复杂约束仍硬套无约束梯度下降​

等式/不等式约束应使用拉格朗日、KKT 体系下的约束算法或 fmincon。

6. 收敛到 ∥∇f∥≈0\|\nabla f\|\approx 0 就以为一定是极小​

还可能是鞍点;可检查海森正定性或做局部采样。

八、小结​

梯度下降的核心思想可以概括为:

沿负梯度方向迭代更新决策变量,配合适当步长使目标值下降,直至梯度近似为零,从而找到局部极小点。

它是非线性规划的一阶基石,适合可微、大规模或教学场景。建模中应重视缩放、线搜索与多初值;需要更快收敛时考虑牛顿法,有约束时上升到 KKT 与 fmincon,黑箱难解时才考虑智能优化兜底。