近端优化如何处理不可微正则项
文章从平滑损失与非平滑惩罚项的组合目标出发,解释近端算子如何将难处理部分拆成独立子问题。结合 Lasso 和约束优化,介绍 ISTA、FISTA、ADMM 的使用方式及实践局限。
AI 深度解读
近端方法(Proximal Methods)解决的是一类常见优化问题:损失函数可以求导,稀疏、约束或低秩惩罚却不能处处求导。作者的主张是,保留这些惩罚,分别处理光滑部分和非光滑部分,再把结果组合起来。
这条思路串起了 ISTA、FISTA 和 ADMM。对程序员来说,值得读的地方是理解:为什么把参数压小不等于得到稀疏结果,为什么加动量也有代价,以及一个看起来简单的算法,会把计算成本藏在哪里。
为什么非光滑部分值得单独求解
作者讨论的目标,可以概括为最小化 (f(x)+g(x)):(f) 通常是可求导的数据拟合损失,(g) 是凸的、可能非光滑的正则项。
例如,lasso 用 L1 惩罚鼓励系数变成零,但绝对值函数恰好在零处不可导。这里的麻烦很具体:我们希望参数落到的位置,正是普通梯度不存在的位置。
另一种情况是约束优化。把集合 (C) 的指示函数作为 (g):在集合内取 (0),在集合外取 (\infty),就能把约束写进目标函数。它与稀疏惩罚长得不同,却可以使用同一套近端工具。
次梯度方法能够处理非光滑问题,但作者列出的典型收敛阶为 (O(1/\sqrt{k})),而且通常不能在每次更新中直接得到精确的零或满足约束的点。
近端算子(proximal operator)做的事,是在两种要求之间取平衡:让 (g) 更小,同时别离输入点 (v) 太远。步长 (\tau>0) 越小,越倾向于留在 (v) 附近;越大,越愿意向减小 (g) 的方向移动。所给原文缺失了部分独立公式,但这个定义的含义和后续操作仍然明确。
它与梯度更新的联系也有边界。普通梯度步是 (v-\tau\nabla g(v)),使用当前位置的梯度;近端步则隐式求出新位置。光滑情形下,两者在小步长时接近,并非任意步长下完全相等。
实用性来自几个常见的对应关系:
- (g(x)=\lambda|x|_1) 对应软阈值:每个坐标向零收缩 (\lambda\tau),不足这个幅度的直接归零。
- 凸集合的指示函数对应欧氏投影,把输入点投到集合上。
- (g(x)=\lambda|x|_2) 对应块软阈值,按整个向量进行收缩。
- 核范数对应奇异值软阈值,可用于低秩矩阵补全。
近端方法的优势,是把需要的结构直接落实到更新规则里。
ISTA 和 FISTA 的区别,不只是多加一点动量
近端梯度法先沿 (f) 做梯度更新,再对 (g) 应用近端算子。在稀疏恢复领域,这种方法也叫 ISTA。
对 lasso 来说,就是先走一步最小二乘梯度,再做软阈值。它能产生真正为零的系数,因此不必另外设一个「足够接近零」的判断阈值。
下面这段原始实现,展示了这两个步骤如何接起来:
import numpy as np
def soft_threshold(v, threshold):
return np.sign(v) * np.maximum(np.abs(v) - threshold, 0.0)
def ista(A, b, lam, steps=200):
# Step size 1 / L, where L is the largest eigenvalue of A^T A.
L = np.linalg.eigvalsh(A.T @ A)[-1]
x = np.zeros(A.shape[1])
for _ in range(steps):
grad = A.T @ (A @ x - b)
x = soft_threshold(x - grad / L, lam / L)
return x
要看的是 x = soft_threshold(x - grad / L, lam / L):梯度步长和阈值共用 (1/L),惩罚强度由 lam 控制。
在凸性等前提成立、(f) 的梯度满足 (L)-Lipschitz 连续且取 (\tau=1/L) 时,ISTA 的目标函数差距按 (O(1/k)) 收敛。这里衡量的是当前目标值与最优目标值的距离,不能直接理解成参数误差或预测误差。
FISTA 加入辅助序列 (y^k) 和按特定规律变化的动量系数,把目标函数差距的理论阶改善到 (O(1/k^2))。动量系数逐渐趋近于 (1),并非凭感觉固定一个数,就能获得同样保证。
但 FISTA 的目标值可能在某次迭代后升高。作者建议,在目标值上涨时重启动量,往往能改善实际表现。加速目标值收敛,也不保证参数序列以相同速度稳定下来;梯度由随机采样估计时,动量还可能放大噪声。作者因此把带平均处理的普通近端梯度,视为随机问题中更稳妥的选择。
这些是理论性质和实践建议。原文没有给出计时实验,不能据此断言 FISTA 在某个项目中一定更快。
什么时候还要继续拆,交给 ADMM
近端梯度法要求有一个可求导的 (f),以及一个容易计算近端算子的 (g)。如果存在两个非光滑项,或者惩罚项与线性算子复合,一次拆分可能还不够。
原文举了总变差去噪,以及同时带稀疏要求和线性约束的问题。ADMM,即交替方向乘子法,通过引入两组变量、对偶变量和增广拉格朗日,把求解分成三个动作:固定 (z) 更新 (x),固定 (x) 更新 (z),最后根据约束残差更新对偶变量。
可以把约束残差理解为:两组变量目前配合得还不够好,下一轮要据此调整。
这种拆分方便组织不同变量块,也可能用于客户端、传感器或变量块之间的并行计算。但这不代表三个动作能无条件同时执行;更新之间仍有依赖,是否能并行取决于具体结构。
作者也给出了 ADMM 的代价:追求高精度时可能收敛缓慢,速度还明显受增广拉格朗日中惩罚参数的影响。先用 ADMM 达到中等精度,再切换专用求解器,是原文提出的一种实践策略,并无对照数据证明它普遍更优。
这里还有一个共同前提:拆出来的子问题必须便宜。核范数的近端操作虽然形式明确,仍需要处理奇异值;某些近端算子如果还要运行内部迭代,外层每走一步,都得支付这笔费用。
我的判断
我认同作者强调的取舍:如果稀疏、可行性或低秩正是建模目标,就应优先检查是否存在合适的近端操作。与把非光滑项平滑化相比,这能保留原先希望表达的结构,也少引入一套平滑近似的选择。
但「精确处理惩罚项」只是在求解给定模型。lasso 得到零系数,不代表这些特征在真实业务中一定无用。优化结果与建模是否合理,是两件需要分别验证的事。
原文有两处表述还应收紧。第一,(\tau=1/L) 是文中采用的标准安全选择;超过 (1/L) 可能出问题,但不能理解为一超过就必然发散。第二,回溯线搜索确实要额外评估 (f),但调整步长后,通常也要重新计算对应的近端候选点。「不增加近端计算」不宜作为通用成本保证。
代码也更适合作为教学示例:steps=200 是固定迭代次数,没有收敛判据;显式构造 A.T @ A 并求特征值,在大问题上也可能昂贵。原文未提供数据规模、耗时或与专用求解器的比较,因此关于实际速度和算法切换的建议,应按经验之谈看待。
最后,(O(1/k)) 和 (O(1/k^2)) 的保证依赖凸性。把方法用于非凸惩罚或神经网络结构正则化后,不能继续沿用全局最优的结论;原文给出的期待也只是至多收敛到驻点。
能拿来做什么
- 在处理稀疏回归或相关数据分析任务时,可以用这段 NumPy 实现理解「梯度更新加软阈值」;进入实际项目后,再补充停止条件,并检查计算 (L) 的成本。
- 给优化任务加入约束前,可以先判断集合是否凸、投影是否便宜;满足条件时,投影近端步能直接维护可行性。
- 用 AI 编程助手生成优化代码时,应要求它说明目标函数、凸性、步长依据和近端算子成本,并区分目标值收敛与参数收敛,避免只返回一个能运行的循环。
- 在 ISTA、FISTA 和 ADMM 之间选择时,应围绕目标精度、梯度噪声和每步成本做比较;只有确实需要继续拆分变量或约束时,再承担 ADMM 的额外参数与求解复杂度。