非线性规划中的序列随机拟牛顿法 (Sequential Stochastic Quasi-Newton Method) 基础题
题目描述
考虑一个大规模的无约束非线性规划问题:
\[\min_{x \in \mathbb{R}^n} f(x) \]
其中,目标函数 \(f(x)\) 是连续可微的,但具有以下特点:
- 高维度:变量 \(n\) 很大(例如, \(n \geq 10^4\) )。
- 大数据/随机性:目标函数可以表示为大量子函数之和:\(f(x) = \frac{1}{N} \sum_{i=1}^{N} f_i(x)\),其中 \(N\) 非常大(例如, \(N \geq 10^6\) )。
- 计算瓶颈:在每次迭代中,计算完整的梯度 \(\nabla f(x) = \frac{1}{N} \sum_{i=1}^{N} \nabla f_i(x)\) 的计算代价极高,而计算单个子函数的梯度 \(\nabla f_i(x)\) 则相对廉价。
你的任务是:设计并实现一个序列随机拟牛顿法来解决此问题。该方法需结合随机梯度下降(SGD)的低计算成本和拟牛顿法利用曲率信息加速收敛的优点,通过迭代更新一个近似的Hessian逆矩阵 \(H_k\),来生成搜索方向 \(d_k = -H_k g_k\),其中 \(g_k\) 是当前点的随机梯度估计。
要求最终算法能有效处理大规模数据,并在合理的迭代次数内收敛到一个稳定点(近似驻点)。
解题过程循序渐进讲解
第一步:理解问题核心与挑战
面对大规模求和形式的目标函数,传统拟牛顿法(如BFGS)需要计算完整梯度,这在每步迭代的代价是 \(O(Nn)\),对于大数据集是不可行的。随机梯度下降(SGD)只使用单个或一小批数据的梯度,代价为 \(O(bn)\)(\(b\) 为批次大小),但收敛慢,因为它忽略了目标函数的曲率信息。
序列随机拟牛顿法的核心思想是:在SGD的框架下,增量式地构建并更新一个对Hessian逆矩阵的近似 \(H_k\),从而得到比纯SGD更优的搜索方向。
主要挑战:
- 如何用随机(有噪声)的梯度信息稳定地更新 \(H_k\)?
- 如何保证 \(H_k\) 始终保持正定(以保证下降方向)?
- 如何设计步长 \(\alpha_k\) 以适应随机噪声和曲率估计的不确定性?
第二步:算法框架设计
我们设计一个序列(在线) 的算法。在每一步 \(k\):
- 随机采样:从 \(\{1, ..., N\}\) 中均匀随机抽取一个索引 \(i_k\)(或一个小批量索引集 \(\mathcal{B}_k\))。
- 计算随机梯度:\(g_k = \nabla f_{i_k}(x_k)\)(或 \(g_k = \frac{1}{|\mathcal{B}_k|} \sum_{i \in \mathcal{B}_k} \nabla f_i(x_k)\))。
- 计算搜索方向:\(d_k = -H_k g_k\)。
- 执行更新:\(x_{k+1} = x_k + \alpha_k d_k\)。
- 更新Hessian逆近似:利用新得到的信息对 \(H_k\) 进行更新,得到 \(H_{k+1}\)。
关键就在于第5步的更新规则。
第三步:确定更新规则(核心)
我们采用随机版本的BFGS更新(oBFGS或rescaled BFGS)。标准BFGS更新公式(对于确定性问题)为:
令 \(s_k = x_{k+1} - x_k\), \(y_k = \nabla f(x_{k+1}) - \nabla f(x_k)\)。
BFGS更新公式为:
\[H_{k+1} = \left(I - \rho_k s_k y_k^T \right) H_k \left(I - \rho_k y_k s_k^T \right) + \rho_k s_k s_k^T, \quad \rho_k = \frac{1}{y_k^T s_k} \]
条件是 \(y_k^T s_k > 0\)(曲率条件),以保证 \(H_{k+1}\) 正定。
在随机环境下,我们用随机梯度差 \(\tilde{y}_k\) 代替真实的梯度差 \(y_k\):
\[\tilde{y}_k = \nabla f_{i_k}(x_{k+1}) - \nabla f_{i_k}(x_k) \]
这里用同一个数据样本(或同一个小批量) 计算新旧两点的梯度差。这样做是为了保证更新满足随机曲率条件 \(\mathbb{E}[\tilde{y}_k^T s_k] > 0\) 的期望,尽管单次采样可能有噪声。
然而,直接使用 \(\tilde{y}_k\) 可能导致 \(\tilde{y}_k^T s_k\) 为负或很小,破坏 \(H_k\) 的正定性。一个经典的稳定化技巧是进行重缩放(Rescaling):
\[y_k^{resc} = \theta_k \tilde{y}_k + (1-\theta_k) B_k^{0} s_k \]
其中 \(B_k^0\) 是一个正定标度矩阵(常取 \(B_k^0 = \delta_k I\), \(\delta_k = \frac{\tilde{y}_k^T \tilde{y}_k}{\tilde{y}_k^T s_k}\) 或一个固定常数), \(\theta_k \in [0, 1]\) 是一个调节参数。当 \(\tilde{y}_k^T s_k\) 足够大且为正时, \(\theta_k \approx 1\);否则 \(\theta_k\) 减小,使 \(y_k^{resc}\) 更接近 \(B_k^0 s_k\),从而保证 \((y_k^{resc})^T s_k > 0\)。
为简化,在基础题中,我们可以采用一个更直接的稳定策略:仅当 \(\tilde{y}_k^T s_k\) 大于一个正阈值 \(\epsilon\) 时才执行BFGS更新,否则跳过更新,保持 \(H_{k+1} = H_k\)。
第四步:算法步骤详细分解
-
初始化:
- 选择初始点 \(x_0 \in \mathbb{R}^n\)。
- 初始化Hessian逆近似 \(H_0 = \gamma I\),其中 \(\gamma > 0\) 是一个小的正数(例如 \(\gamma = 0.001\))或设置为 \(1\)。
- 选择初始步长 \(\alpha_0\)(如0.01),衰减率 \(\beta\)(如0.999),最小值 \(\alpha_{min}\)。
- 设置最大迭代次数 \(K\),曲率阈值 \(\epsilon > 0\)。
-
主迭代循环(对于 \(k = 0, 1, 2, ..., K-1\)):
a. 随机采样:随机选取一个样本索引 \(i_k\)(或一个小批量 \(\mathcal{B}_k\))。
b. 计算随机梯度:\(g_k = \nabla f_{i_k}(x_k)\)。
c. 计算搜索方向:\(d_k = -H_k g_k\)。
d. 更新迭代点:\(x_{k+1} = x_k + \alpha_k d_k\)。
e. 准备更新信息:
* 计算位移:\(s_k = x_{k+1} - x_k\)。
* 用同一个样本 \(i_k\) 计算随机梯度差:\(\tilde{y}_k = \nabla f_{i_k}(x_{k+1}) - \nabla f_{i_k}(x_k)\)。
f. 检查曲率条件:计算 \(\rho_k = \tilde{y}_k^T s_k\)。
* 如果 \(\rho_k > \epsilon\),则执行BFGS更新:
* 计算 \(\rho_k = 1 / \rho_k\)。
* 计算中间向量 \(v_k = I - \rho_k \tilde{y}_k s_k^T\)。
* 更新:\(H_{k+1} = v_k H_k v_k^T + \rho_k s_k s_k^T\)。
* 否则,跳过更新:\(H_{k+1} = H_k\)。
g. 衰减步长:\(\alpha_{k+1} = \max(\alpha_{min}, \beta \cdot \alpha_k)\)。这是为了在后期抑制随机噪声的影响。 -
终止:达到最大迭代次数 \(K\) 后,输出 \(x_K\) 作为近似最优解。
第五步:关键点与注意事项
- 同一样本梯度差:步骤(e)中使用同一个样本 \(i_k\) 计算 \(x_k\) 和 \(x_{k+1}\) 处的梯度至关重要。这确保了 \(\mathbb{E}[\tilde{y}_k] \approx \nabla f(x_{k+1}) - \nabla f(x_k)\),且 \(\tilde{y}_k^T s_k\) 的期望为正(如果函数是凸的或接近最优点时),满足BFGS更新的内在要求。
- 条件更新:曲率条件检查( \(\rho_k > \epsilon\) )是算法的安全阀,防止因噪声导致 \(H_k\) 变得不正定或数值不稳定。
- 步长衰减:使用衰减步长(如 \(\alpha_k = \alpha_0 / (1 + \beta k)\) 或几何衰减)对于理论收敛至关重要。在随机优化中,通常需要满足 Robbins-Monro 条件:\(\sum \alpha_k = \infty\), \(\sum \alpha_k^2 < \infty\)。
- 内存与计算:直接存储和更新 \(n \times n\) 的矩阵 \(H_k\) 在大规模(n很大)时不可行。因此,在实际的高维实现中,常采用有限内存L-BFGS的随机版本,即只存储最近的 \(m\) 对 \((s, y)\) 向量,动态计算 \(H_k g_k\),将空间复杂度从 \(O(n^2)\) 降至 \(O(mn)\)。本题为基础题,我们暂不涉及有限内存技巧。
第六步:简单示例(概念验证)
考虑一个简单的二次函数:\(f(x) = \frac{1}{2} x^T A x\),其中 \(A\) 是正定矩阵。我们可以将其分解为 \(f(x) = \frac{1}{N} \sum_{i=1}^{N} \frac{1}{2} x^T A_i x\),其中 \(A_i\) 是 \(A\) 的某种分解(例如,外积形式)。用上述算法求解,可以观察到:
- 初期,由于随机梯度的噪声,收敛路径有波动。
- 随着迭代进行,步长衰减,且 \(H_k\) 逐渐逼近 \(A^{-1}\),搜索方向 \(-H_k g_k\) 越来越接近牛顿方向 \(-A^{-1} \nabla f(x_k)\)。
- 最终,\(x_k\) 会收敛到最优点 \(x^* = 0\) 附近的一个邻域内,其大小由步长和噪声决定。
通过这个循序渐进的过程,你应该能够理解序列随机拟牛顿法的动机、核心思想、具体步骤以及实现时的关键考量。它巧妙地在随机优化中引入了二阶信息,旨在达到比SGD更快的收敛速度,同时保持每步较低的计算成本。