深度学习中优化器的SGD with Projected Gradient(带梯度投影的随机梯度下降)算法原理与实现细节
字数 1535 2025-11-08 10:02:38
深度学习中优化器的SGD with Projected Gradient(带梯度投影的随机梯度下降)算法原理与实现细节
题目描述
SGD with Projected Gradient 是一种带约束优化的随机梯度下降变体,核心思想是在参数更新后,将参数投影到可行域(如满足边界约束的集合)中。该算法适用于训练带有显式约束(如非负权重、范数约束)的深度学习模型,例如非负矩阵分解、带约束的强化学习策略等。
解题过程
- 问题定义
- 标准SGD的更新规则为:\(\theta_{t+1} = \theta_t - \eta \nabla L(\theta_t)\),其中 \(\eta\) 是学习率,\(\nabla L(\theta_t)\) 是梯度。
- 若优化问题带有约束(如 \(\theta \in C\),\(C\) 是可行域),直接更新可能违反约束。投影梯度法在SGD步骤后增加投影操作:
\[ \theta_{t+1} = \Pi_C \left( \theta_t - \eta \nabla L(\theta_t) \right) \]
其中 $ \Pi_C $ 是将参数投影到集合 $ C $ 的最近点的算子。
-
投影操作的意义
- 投影定义为:\(\Pi_C(\theta) = \arg\min_{z \in C} \| z - \theta \|^2\),即找到 \(C\) 中与 \(\theta\) 欧氏距离最近的点。
- 例如,若约束为权重非负(\(C = \{ \theta \mid \theta \geq 0 \}\)),则投影操作等价于将负权重置零:\(\Pi_C(\theta) = \max(0, \theta)\)。
-
投影的计算方法(常见可行域)
- 非负约束:对每个参数分量,若 \(\theta_i < 0\),则设 \(\theta_i = 0\)。
- 区间约束(如 \(a \leq \theta \leq b\)):将分量裁剪到区间内。
- L2球约束(如 \(\| \theta \|_2 \leq r\)):若参数范数超过 \(r\),则缩放为 \(\theta \leftarrow r \cdot \theta / \| \theta \|_2\)。
- 复杂约束(如半定规划)需专用优化库(如CVXPY)求解。
-
算法流程
- 输入:初始参数 \(\theta_0\),学习率 \(\eta\),可行域 \(C\)。
- 循环(每步采样小批量数据):
- 计算梯度估计:\(g_t = \nabla L(\theta_t)\)。
- SGD更新:\(\theta_{t+1/2} = \theta_t - \eta g_t\)。
- 投影:\(\theta_{t+1} = \Pi_C(\theta_{t+1/2})\)。
- 输出:满足约束的最终参数 \(\theta_T\)。
-
实际实现示例(非负约束的PyTorch代码)
import torch # 定义带非负约束的线性模型 model = torch.nn.Linear(10, 1) optimizer = torch.optim.SGD(model.parameters(), lr=0.01) for epoch in range(100): # 前向传播与损失计算 loss = ... # 假设已定义 optimizer.zero_grad() loss.backward() optimizer.step() # 标准SGD更新 # 投影步骤:将权重裁剪到非负 with torch.no_grad(): for param in model.parameters(): param.clamp_(min=0) # 等价于非负投影- 注:复杂约束需自定义投影函数替换
clamp_。
- 注:复杂约束需自定义投影函数替换
-
理论保证与注意事项
- 在凸问题中,投影梯度法能收敛到约束下的最优解。
- 非凸问题(如神经网络)中,虽无全局最优保证,但可确保解始终满足约束。
- 学习率需谨慎选择,过大可能导致投影后震荡。
总结
SGD with Projected Gradient 通过简单直接的投影步骤,将约束优化融入随机梯度下降,是处理显式约束问题的实用工具。其效率高度依赖于投影的计算成本,因此在设计约束时应优先选择易投影的可行域(如箱型约束)。