投影梯度法
投影梯度法在梯度下降每一步后,把暂时走出可行域的点拉回约束集合。设 非空、闭且凸,要最小化可微函数 。欧氏投影 是 中距离 最近的点;算法一步为 闭凸性保证每个 有唯一投影。若只做普通梯度下降而不投影,下一步可能根本不符合资源或概率范围的约束。
一个被边界挡住的最小值
在 上最小化 。无约束极小点 3 不在区间中;从 、步长 开始,梯度 ,先走到 ,投影后 。下一步有 ,暂定 ,但 ,所以 。区间投影就是把数夹在左右端点之间: 这里停在边界并非“梯度为零”:;原因是所有可以继续减少函数的方向都指向区间外。
投影不等式与停止条件
令 。对任意 ,线段 仍在 。函数 在 取得单侧最小值,因此右导数 ,即 反过来,展开距离平方也说明满足这条不等式的 就是最近点。把 、 代入,得到固定点条件 如果 是凸的,切平面不等式进一步给 ,故固定点是全局最优。这也解释了凸优化词条中边界最优点为何可以有非零梯度。若 非凸,固定点只满足一阶必要条件,不能当作全局最优证书。
在多维中,投影不一定能逐坐标截断。例如两个权重必须非负且总和为一,构成集合 。把暂定点 的每个坐标分别截到 仍是 ,总和为 1.5,根本不可行。令 ,在 上最小化 求导得 ,故真正的欧氏投影是 。它沿着法向量 从暂定点回到总和为一的直线,而不是独立修剪两个坐标。一般约束集的投影可能本身就是一个需要求解的优化问题。
若希望得到每步下降的量化保证,可再假定梯度满足某个 的 Lipschitz 条件,即 。设一步投影后的位移为 ,投影不等式取 给 。光滑性给目标变化的上界,把这两个不等式接起来就是 特别当 时,除非这一步没有移动,函数值会下降。这是函数值下降的条件;收敛到全局最优还要结合凸性、解的存在及迭代论证。
可复算的 Python 实现
代码处理一维闭区间;调用者提供导数函数,返回最后的可行点和各次迭代值。投影只读边界,不改写任何输入对象。
def projected_gradient_interval(grad, left, right, start,
rate, steps):
if left > right or rate <= 0 or steps < 0:
raise ValueError("invalid interval, rate, or step count")
project = lambda z: min(right, max(left, z))
x = project(start)
history = [x]
for _ in range(steps):
x = project(x - rate * grad(x))
history.append(x)
return x, history
if __name__ == "__main__":
point, path = projected_gradient_interval(
lambda x: 2 * (x - 3), 0, 1, 0.5, 0.1, 2
)
assert path == [0.5, 1.0, 1.0]
assert point == 1.0
每一步只求一次导数和一次区间投影,故运行 步用 时间、保存历史用 空间;若只留最终点,额外空间为常数。步长不能任意放大。例如 、、 时,从零出发会依次投影到一、零、一,永远在两端来回;真正最优点是 。多维约束若投影本身难算,每一步的成本也可能比求梯度高,不能只数迭代次数。
参考资料
- MIT 15.084J 非线性规划讲义,含投影方法与约束优化。
- Stanford EE364b《Subgradient Methods》,第5—6节说明投影与投影次梯度法。
- Boyd、Vandenberghe《Convex Optimization》,第9章讨论光滑函数的下降估计与步长。