深度学习中的优化器之SGD with Gradient Projection(带梯度投影的随机梯度下降)算法原理与实现细节
题目描述:
在深度学习中,当模型参数需要满足特定约束条件(如非负性、范数界限等)时,标准SGD无法保证优化后的参数仍落在可行域内。SGD with Gradient Projection通过在参数更新后增加投影步骤,将参数映射回约束集合,确保优化过程始终满足约束条件。该算法广泛应用于稀疏学习、矩阵分解等场景。
解题过程:
-
问题建模
考虑带约束的优化问题:
min f(θ),s.t. θ ∈ C
其中f(θ)是损失函数,C是约束集合(如θ ≥ 0,||θ|| ≤ 1等)。标准SGD更新θ ← θ - η∇f(θ)可能使θ超出C。 -
投影操作定义
定义投影算子P_C:将任意点映射到C中最近的点:
P_C(z) = argmin_{θ∈C} ||θ - z||²
该操作找到C中与z欧氏距离最小的点。 -
算法步骤
a. 初始化参数θ₀ ∈ C
b. 对于每个迭代t=1,2,...:- 采样小批量数据,计算梯度g_t = ∇f_t(θ_{t-1})
- 执行参数更新:θ_t' = θ_{t-1} - η_t g_t
- 执行投影:θ_t = P_C(θ_t')
其中η_t是学习率。
-
投影计算示例
a. 非负约束(C={θ|θ≥0}):
P_C(z) = max(z, 0) # 逐元素取最大值
b. L2球约束(C={θ|||θ||₂≤r}):
P_C(z) = z * min(1, r/||z||₂) # 缩放至球内
c. 简单集合(如区间约束):
P_C(z) = clip(z, a, b) # 裁剪到[a,b]区间 -
收敛性分析
在凸问题中,该算法保持与SGD相同的O(1/√T)收敛速率。关键性质:
||P_C(u) - P_C(v)|| ≤ ||u - v||(非扩张性)
且投影操作不会引入额外误差。 -
实现细节
import torch def projected_sgd(params, lr, constraint_type, constraint_val=None): with torch.no_grad(): for param in params: # SGD更新 param -= lr * param.grad # 投影操作 if constraint_type == "nonneg": param.clamp_(min=0) elif constraint_type == "l2_ball": norm = param.norm() if norm > constraint_val: param *= constraint_val / norm elif constraint_type == "interval": param.clamp_(min=constraint_val[0], max=constraint_val[1]) param.grad.zero_() -
实际应用
- 非负矩阵分解:确保基矩阵和系数矩阵非负
- 稀疏编码:通过L1球约束促进稀疏性
- 物理约束问题:如概率 simplex 约束(所有元素和为1且非负)
该算法通过简单的投影步骤,使SGD能够处理各种约束优化问题,是约束深度学习模型的重要基础工具。