在优化理论中,Hessian矩阵提供了目标函数的二阶信息,是理解函数局部几何结构的关键。然而,对于大规模问题,直接计算和存储完整的Hessian矩阵往往是不现实的——一个包含百万参数的模型需要存储10^12个元素的Hessian矩阵。本章深入探讨各种Hessian近似技术,这些方法在保持计算效率的同时,巧妙地利用了Hessian的结构特性。我们将学习如何在内存限制下构建有效的二阶优化算法,如何高效计算Hessian-向量乘积,以及如何处理非凸优化中的负曲率问题。
BFGS (Broyden-Fletcher-Goldfarb-Shanno) 算法是拟牛顿方法中最成功的代表。其核心思想是通过迭代更新来构建Hessian矩阵(或其逆)的近似,而无需显式计算二阶导数。
设 $\mathbf{B}_k$ 为第 $k$ 步的Hessian近似,BFGS更新满足拟牛顿条件(secant equation): \(\mathbf{B}_{k+1} \mathbf{s}_k = \mathbf{y}_k\)
其中 $\mathbf{s}k = \mathbf{x}{k+1} - \mathbf{x}k$ 是步长向量,$\mathbf{y}_k = \nabla f(\mathbf{x}{k+1}) - \nabla f(\mathbf{x}_k)$ 是梯度差。
BFGS更新公式为: \(\mathbf{B}_{k+1} = \mathbf{B}_k - \frac{\mathbf{B}_k \mathbf{s}_k \mathbf{s}_k^T \mathbf{B}_k}{\mathbf{s}_k^T \mathbf{B}_k \mathbf{s}_k} + \frac{\mathbf{y}_k \mathbf{y}_k^T}{\mathbf{y}_k^T \mathbf{s}_k}\)
几何直觉:BFGS更新可以理解为对当前Hessian近似进行秩-2修正,使其在新的方向 $\mathbf{s}_k$ 上满足曲率信息。第一项去除了旧的信息,第二项加入了新的曲率信息。
关键洞察:BFGS保持了近似矩阵的正定性,这在 $\mathbf{y}_k^T \mathbf{s}_k > 0$ (Wolfe条件)下自动满足。
实践中,我们通常需要Hessian逆矩阵的近似 $\mathbf{H}_k \approx \mathbf{B}_k^{-1}$。Sherman-Morrison-Woodbury (SMW) 公式允许我们直接更新逆矩阵:
\[(\mathbf{A} + \mathbf{U}\mathbf{V}^T)^{-1} = \mathbf{A}^{-1} - \mathbf{A}^{-1}\mathbf{U}(\mathbf{I} + \mathbf{V}^T\mathbf{A}^{-1}\mathbf{U})^{-1}\mathbf{V}^T\mathbf{A}^{-1}\]应用SMW公式,我们得到BFGS的逆更新公式: \(\mathbf{H}_{k+1} = \left(\mathbf{I} - \rho_k \mathbf{s}_k \mathbf{y}_k^T\right) \mathbf{H}_k \left(\mathbf{I} - \rho_k \mathbf{y}_k \mathbf{s}_k^T\right) + \rho_k \mathbf{s}_k \mathbf{s}_k^T\)
其中 $\rho_k = 1/(\mathbf{y}_k^T \mathbf{s}_k)$。
计算技巧:这个公式避免了矩阵求逆,只需要矩阵-向量乘法,计算复杂度从 $O(n^3)$ 降到 $O(n^2)$。
L-BFGS (Limited-memory BFGS) 是BFGS的内存高效版本,它只存储最近 $m$ 个向量对 ${(\mathbf{s}_i, \mathbf{y}_i)}$,而不是完整的 $n \times n$ 矩阵。
核心算法:L-BFGS双循环
输入:梯度 g, 历史向量对 {(s_i, y_i)}_{i=k-m}^{k-1}, 初始Hessian逆近似 H_0
输出:搜索方向 d = H_k g
// 第一个循环:从最新到最旧
q = g
for i = k-1, k-2, ..., k-m:
ρ_i = 1/(y_i^T s_i)
α_i = ρ_i s_i^T q
q = q - α_i y_i
// 应用初始Hessian逆
r = H_0 q
// 第二个循环:从最旧到最新
for i = k-m, k-m+1, ..., k-1:
β = ρ_i y_i^T r
r = r + s_i (α_i - β)
return d = r
内存复杂度:$O(mn)$,其中 $m$ 通常选择3-20。
数学本质:L-BFGS隐式地构建了 $\mathbf{H}_k$ 的紧凑表示: \(\mathbf{H}_k = \mathbf{H}_0 + \mathbf{V}_k \mathbf{R}_k^{-1} \mathbf{V}_k^T\) 其中 $\mathbf{V}_k$ 和 $\mathbf{R}_k$ 由历史向量对构成。
算法的深层理解:双循环算法实际上是在执行一系列投影操作。第一个循环将梯度投影到历史信息的零空间,第二个循环则重建出完整的拟牛顿方向。这种结构使得算法具有天然的数值稳定性。
高级实现技巧:
并行化潜力:虽然双循环看似串行,但内积计算 $s_i^T q$ 和向量更新 $q - \alpha_i y_i$ 都可以并行化。现代实现利用BLAS Level 1操作获得显著加速。
选择历史长度 $m$ 涉及内存与性能的权衡:
理论结果:在强凸函数上,L-BFGS的收敛率为: \(\|\mathbf{x}_k - \mathbf{x}^*\| \leq C \cdot r^k\) 其中 $r < 1$ 依赖于 $m$ 和问题的条件数。
实践建议:
深度学习带来了独特的挑战:
1. 随机性处理:
2. 非凸性适应:
3. 分布式实现:
4. 自适应初始化: \(\mathbf{H}_0^{(k)} = \frac{\mathbf{s}_{k-1}^T \mathbf{y}_{k-1}}{\mathbf{y}_{k-1}^T \mathbf{y}_{k-1}} \mathbf{I}\) 这个选择基于最新的曲率信息,往往比固定的 $\mathbf{H}_0 = \mathbf{I}$ 更有效。
研究前沿:
深度学习特有的挑战:
批量归一化的影响:BatchNorm层改变了损失景观的几何结构,使得传统的L-BFGS假设不再成立。研究表明,需要特殊处理这些层的参数更新。
梯度爆炸/消失的处理:
内存效率优化:
与现代优化器的协同:
实证观察:
大规模问题往往具有特殊结构,利用这些结构可以显著提升L-BFGS的效率:
1. 分块L-BFGS (Block L-BFGS): 当参数具有自然分组时(如神经网络的不同层),可以对每组维护独立的L-BFGS近似:
\[\mathbf{H} = \begin{bmatrix} \mathbf{H}_1 & & \\ & \mathbf{H}_2 & \\ & & \ddots \end{bmatrix}\]优势:
实现考虑:
2. 结构化BFGS (Structured BFGS): 利用问题的特定结构设计更新:
Kronecker结构: 对于形如 $\mathbf{H} = \mathbf{A} \otimes \mathbf{B}$ 的问题:
低秩加对角结构: \(\mathbf{H}^{-1} \approx \mathbf{D}^{-1} + \mathbf{U}\mathbf{V}^T\)
3. 压缩L-BFGS (Compact L-BFGS): 将L-BFGS表示为紧凑形式: \(\mathbf{H}_k = \mathbf{H}_0 + [\mathbf{S}_k \quad \mathbf{H}_0\mathbf{Y}_k] \begin{bmatrix} \mathbf{D}_k & \mathbf{L}_k^T \\ \mathbf{L}_k & -\mathbf{H}_0 \end{bmatrix}^{-1} \begin{bmatrix} \mathbf{S}_k^T \\ \mathbf{Y}_k^T\mathbf{H}_0 \end{bmatrix}\)
其中:
这种表示便于:
理解L-BFGS的理论性质对于算法调优和问题诊断至关重要:
1. 收敛速率分析:
强凸情况: 对于 $\mu$-强凸、$L$-光滑的函数,L-BFGS的收敛率为: \(f(\mathbf{x}_k) - f^* \leq \left(1 - \frac{2\mu\gamma}{L + \mu\gamma}\right)^k (f(\mathbf{x}_0) - f^*)\) 其中 $\gamma$ 依赖于L-BFGS近似质量。
一般凸情况: \(f(\mathbf{x}_k) - f^* \leq \frac{C}{k}\) 其中常数 $C$ 依赖于初始点和Hessian近似质量。
非凸情况: 在适当的正则性条件下: \(\min_{i \leq k} \|\nabla f(\mathbf{x}_i)\|^2 \leq \frac{2(f(\mathbf{x}_0) - f^*)}{k\eta}\)
2. 近似质量的量化:
Dennis-Moré条件: 超线性收敛的充要条件: \(\lim_{k \to \infty} \frac{\|(\mathbf{H}_k - \mathbf{H}(\mathbf{x}^*))\mathbf{s}_k\|}{\|\mathbf{s}_k\|} = 0\)
谱条件数界: 理想情况下,希望: \(\kappa(\mathbf{H}_k^{-1}\mathbf{H}) \approx 1\)
实践中,监控: \(\rho_k = \frac{\|\mathbf{H}_k\mathbf{g}_k\|}{\|\mathbf{g}_k\|} \cdot \frac{\|\nabla^2 f(\mathbf{x}_k)^{-1}\mathbf{g}_k\|}{\|\nabla^2 f(\mathbf{x}_k)^{-1}\mathbf{g}_k\|}\)
3. 内存限制的影响:
理论结果:
实用指导:
1. 向量化与SIMD优化: 利用现代CPU的向量指令集:
// 向量化的内积计算
float dot_product_simd(float* a, float* b, int n) {
// 使用AVX/SSE指令集
// 一次处理多个元素
}
关键优化点:
2. 缓存优化策略:
循环展开: 减少循环开销,提高指令级并行:
// 展开因子4的示例
for (i = 0; i < n-3; i += 4) {
sum += a[i] * b[i];
sum += a[i+1] * b[i+1];
sum += a[i+2] * b[i+2];
sum += a[i+3] * b[i+3];
}
数据布局优化:
3. 数值稳定性增强:
Kahan求和在L-BFGS中的应用:
// 高精度累加alpha值
kahan_sum = 0.0
compensation = 0.0
for i in range(m):
y = alpha[i] - compensation
t = kahan_sum + y
compensation = (t - kahan_sum) - y
kahan_sum = t
缩放技术:
4. 自适应历史管理:
动态历史长度: 根据问题特性动态调整 $m$:
选择性更新: 不是所有的 $(\mathbf{s}_k, \mathbf{y}_k)$ 对都有同等价值:
1. L-BFGS与动量方法的结合:
L-BFGS-B with Momentum: 结合L-BFGS的二阶信息和动量的加速效果: \(\mathbf{v}_{k+1} = \beta \mathbf{v}_k + (1-\beta) \mathbf{H}_k \mathbf{g}_k\) \(\mathbf{x}_{k+1} = \mathbf{x}_k - \alpha \mathbf{v}_{k+1}\)
优势:
2. 自适应学习率集成:
L-BFGS-Adam混合:
实现框架:
if phase == "exploration":
use Adam with large learning rate
elif phase == "refinement":
use L-BFGS for fast local convergence
else: # phase == "hybrid"
direction = L-BFGS.compute_direction()
step_size = Adam.compute_step_size()
update = step_size * direction
3. 正则化与L-BFGS:
隐式正则化效应: L-BFGS的有限内存特性产生隐式正则化:
显式正则化的处理: 对于 $f(\mathbf{x}) + \lambda R(\mathbf{x})$ 形式的问题:
高维分析视角:
随机矩阵理论的应用: 当 $n \to \infty$ 时,L-BFGS的更新矩阵具有特殊的谱性质:
信息几何解释: L-BFGS可以视为在参数空间的Riemannian流形上的测地线逼近:
与深度学习理论的联系:
神经切线核(NTK)视角: 在无限宽度极限下,L-BFGS近似的是NTK的逆: \(\mathbf{H}_\infty \approx \mathbf{K}_{NTK}^{-1}\) 这提供了理解L-BFGS在过参数化网络中行为的新视角。
损失景观的含义:
最新研究方向:
开放问题:
在许多二阶优化算法中,我们并不需要完整的Hessian矩阵,而只需要计算Hessian与向量的乘积 $\mathbf{H}\mathbf{v}$。这个观察导致了一类”matrix-free”的方法,它们能够在 $O(n)$ 的内存和 $O(n)$ 的时间内完成计算。
自动微分(AD)不仅可以高效计算梯度,还可以扩展到二阶导数。关键洞察是: \(\mathbf{H}\mathbf{v} = \nabla(\nabla f^T \mathbf{v}) = \nabla(g^T \mathbf{v})\)
其中 $g = \nabla f$ 是梯度。这将Hessian-向量乘积转化为标量函数 $g^T \mathbf{v}$ 的梯度计算。
前向模式AD:计算方向导数 \(\frac{d}{dt} f(\mathbf{x} + t\mathbf{v})\big|_{t=0} = \nabla f(\mathbf{x})^T \mathbf{v}\)
反向模式AD:计算梯度的梯度 \(\mathbf{H}\mathbf{v} = \frac{d}{dt} \nabla f(\mathbf{x} + t\mathbf{v})\big|_{t=0}\)
计算复杂度:两次反向传播的成本,约为梯度计算的2-3倍。
Pearlmutter提出了一种优雅的方法,通过修改反向传播来直接计算 $\mathbf{H}\mathbf{v}$:
核心思想:在计算图中同时传播两个量:
| 方向导数 $\dot{\mathbf{w}} = \frac{\partial \mathbf{w}}{\partial t}\big | _{t=0}$ 当 $\mathbf{w}(t) = \mathbf{w}_0 + t\mathbf{v}$ |
传播规则:对于操作 $\mathbf{y} = f(\mathbf{x})$:
实现细节:
在自动微分框架中,有两种计算Hessian-向量乘积的算子:
R-operator (Right multiplication):计算 $\mathbf{H}\mathbf{v}$
def R_op(f, x, v):
# 创建dual number: x + ε*v
# 计算 f(x + ε*v) 并提取 ε 的系数
g = grad(f, x)
return grad(lambda x: dot(g(x), v), x)
L-operator (Left multiplication):计算 $\mathbf{v}^T\mathbf{H}$
def L_op(f, x, v):
# 使用向量-Jacobian乘积
g = grad(f, x)
return vjp(g, x, v)
关系:由于Hessian的对称性,$\mathbf{v}^T\mathbf{H} = (\mathbf{H}\mathbf{v})^T$
优化技巧:
共轭梯度(CG)法是求解线性系统 $\mathbf{H}\mathbf{x} = \mathbf{b}$ 的迭代方法,特别适合大规模问题:
算法框架:
初始化:r_0 = b - H*x_0, p_0 = r_0
for k = 0, 1, 2, ...:
α_k = (r_k^T r_k) / (p_k^T H p_k) # 需要计算 H*p_k
x_{k+1} = x_k + α_k p_k
r_{k+1} = r_k - α_k H p_k
β_k = (r_{k+1}^T r_{k+1}) / (r_k^T r_k)
p_{k+1} = r_{k+1} + β_k p_k
Newton-CG方法:
预条件CG (PCG):
收敛分析: CG的误差满足: \(\|\mathbf{x}_k - \mathbf{x}^*\|_{\mathbf{H}} \leq 2\left(\frac{\sqrt{\kappa}-1}{\sqrt{\kappa}+1}\right)^k \|\mathbf{x}_0 - \mathbf{x}^*\|_{\mathbf{H}}\)
其中 $\kappa = \lambda_{max}/\lambda_{min}$ 是条件数。
大规模Hessian-向量乘积的高效实现需要考虑现代硬件架构:
1. 数据并行:
2. 模型并行:
3. 内存优化技术:
Checkpointing:
混合精度计算:
4. 通信优化:
5. 批量Hessian-向量乘积: 计算 $\mathbf{H}[\mathbf{v}_1, \mathbf{v}_2, …, \mathbf{v}_k]$ 比单独计算每个更高效:
实践建议:
许多实际问题的Hessian具有特殊结构,利用这些结构可以大幅提升效率:
1. 带状Hessian: 当变量间的依赖关系局部化时,Hessian呈现带状结构: $$\mathbf{H} = \begin{bmatrix}
高效计算策略:
2. 分块Hessian: 对于多任务学习或分层模型: \(\mathbf{H} = \begin{bmatrix} \mathbf{H}_{11} & \mathbf{H}_{12} & \cdots \\ \mathbf{H}_{21} & \mathbf{H}_{22} & \cdots \\ \vdots & \vdots & \ddots \end{bmatrix}\)
优化技术:
3. 低秩扰动结构: \(\mathbf{H} = \mathbf{D} + \mathbf{U}\mathbf{V}^T\) 其中 $\mathbf{D}$ 是对角矩阵,$\mathbf{U}, \mathbf{V} \in \mathbb{R}^{n \times r}$,$r \ll n$。
高效计算: \(\mathbf{H}\mathbf{v} = \mathbf{D}\mathbf{v} + \mathbf{U}(\mathbf{V}^T\mathbf{v})\)
4. Kronecker积结构: 对于张量化模型或多线性问题: \(\mathbf{H} = \mathbf{A}_1 \otimes \mathbf{A}_2 \otimes \cdots \otimes \mathbf{A}_d\)
利用Kronecker积性质: \((\mathbf{A} \otimes \mathbf{B})\text{vec}(\mathbf{X}) = \text{vec}(\mathbf{B}\mathbf{X}\mathbf{A}^T)\)
这将 $O(n^2)$ 的操作降至 $O(dn^{2/d})$。
5. 隐式定义的Hessian结构:
Gauss-Newton近似: 对于最小二乘问题 $f(\mathbf{x}) = \frac{1}{2}|\mathbf{r}(\mathbf{x})|^2$: \(\mathbf{H} \approx \mathbf{J}^T\mathbf{J}\) 其中 $\mathbf{J}$ 是残差的Jacobian。计算 $\mathbf{H}\mathbf{v}$ 只需:
Fisher信息矩阵: 对于概率模型 $p(y|x;\theta)$: \(\mathbf{F} = \mathbb{E}_{y \sim p}[\nabla_\theta \log p(y|x;\theta) \nabla_\theta \log p(y|x;\theta)^T]\) 计算 $\mathbf{F}\mathbf{v}$ 可以通过采样近似,避免存储完整矩阵。
6. 图结构诱导的稀疏性:
对于图神经网络或马尔可夫随机场:
高级技巧:稀疏性探测: 当Hessian稀疏模式未知时:
混合结构的处理: 实际问题常具有多种结构的组合: \(\mathbf{H} = \mathbf{H}_{sparse} + \mathbf{L}\mathbf{L}^T + \sigma\mathbf{I}\)
对于超大规模问题,即使 $O(n)$ 的计算也可能过于昂贵,随机化方法提供了可行的替代:
1. 子采样方法: 不使用完整数据计算Hessian-向量乘积: \(\mathbf{H}\mathbf{v} \approx \frac{1}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \nabla^2 f_i(\mathbf{x}) \mathbf{v}\)
其中 $\mathcal{B}$ 是随机选择的小批量。
方差缩减技术:
| 使用控制变量:$\tilde{\mathbf{H}}\mathbf{v} = \mathbf{H}_0\mathbf{v} + \frac{1}{ | \mathcal{B} | } \sum_{i \in \mathcal{B}} (\nabla^2 f_i - \mathbf{H}_0)\mathbf{v}$ |
2. 随机投影方法: 使用随机矩阵 $\mathbf{S} \in \mathbb{R}^{n \times k}$ 近似: \(\mathbf{H} \approx \mathbf{H}\mathbf{S}(\mathbf{S}^T\mathbf{H}\mathbf{S})^{-1}\mathbf{S}^T\mathbf{H}\)
常用随机矩阵:
3. 量子启发的采样: 利用量子计算的思想设计经典采样策略:
现代自动微分框架提供了强大的工具来计算Hessian-向量乘积:
1. 高阶自动微分:
# JAX示例
def hvp(f, x, v):
return jax.grad(lambda x: jax.vmap(jax.grad(f))(x) @ v)(x)
# PyTorch示例
def hvp(f, x, v):
grad = torch.autograd.grad(f(x), x, create_graph=True)[0]
return torch.autograd.grad(grad @ v, x)[0]
2. 向量化计算多个HVP: 同时计算多个方向的Hessian-向量乘积:
# 批量HVP计算
def batch_hvp(f, x, V): # V是多个向量组成的矩阵
return jax.vmap(lambda v: hvp(f, x, v), in_axes=1, out_axes=1)(V)
3. 混合模式微分: 结合前向和反向模式获得最佳效率:
4. 自定义VJP规则: 为特殊操作定义高效的向量-Jacobian乘积:
@jax.custom_vjp
def custom_op(x):
# 前向计算
return result
def custom_op_fwd(x):
# 保存前向传播需要的中间结果
return result, saved_values
def custom_op_bwd(saved_values, g):
# 定义高效的反向传播
return vjp_result
custom_op.defvjp(custom_op_fwd, custom_op_bwd)
1. 分子动力学中的Hessian计算: 对于 $N$ 个原子的系统,Hessian是 $3N \times 3N$ 的矩阵:
2. 偏微分方程的离散化: 有限元方法产生的Hessian通常稀疏且结构化:
3. 图神经网络的二阶优化: GNN的Hessian具有图结构诱导的稀疏性:
4. 变分推断中的自然梯度: Fisher信息矩阵的高效计算:
1. 硬件-算法协同设计:
2. 理论界限的改进:
3. 与机器学习的深度结合:
4. 量子-经典混合算法:
与自动混合精度(AMP)的集成:
深度学习框架中的HVP计算需要特别注意数值精度:
精度策略:
if gradient_norm > threshold:
use_high_precision_hvp()
else:
use_mixed_precision_hvp()
分布式HVP的通信优化:
梯度压缩与HVP:
层级通信拓扑:
内存带宽优化:
融合算子设计: 将多个HVP相关操作融合减少内存访问:
fused_hvp_and_update(H, v, x, lr):
hvp = compute_hvp(H, v)
x_new = x - lr * hvp # 融合更新
return x_new, hvp
张量核心(Tensor Core)利用:
泛函分析框架:
将HVP视为线性算子: \(\mathcal{L}_H: \mathcal{V} \to \mathcal{V}, \quad \mathcal{L}_H(v) = Hv\)
算子范数与谱性质:
微分几何视角:
联络与平行传输: HVP可解释为切空间中的平行传输:
流形优化含义:
信息理论解释:
KL散度的Hessian: 对于分布族 $p_\theta$,KL散度的Hessian等于Fisher信息矩阵: \(H_{KL} = \mathbb{E}_{p_\theta}[\nabla_\theta \log p_\theta \nabla_\theta \log p_\theta^T] = F(\theta)\)
这建立了HVP与信息几何的桥梁。
最小描述长度(MDL)原理:
开放研究问题:
在非凸优化中,Hessian矩阵可能有负特征值,对应的特征向量指向负曲率方向。沿着这些方向移动可以帮助算法逃离鞍点,这对深度学习等应用至关重要。
鞍点定义:点 $\mathbf{x}^$ 是鞍点如果 $\nabla f(\mathbf{x}^) = 0$ 且Hessian $\mathbf{H}(\mathbf{x}^*)$ 有至少一个负特征值。
在高维空间的普遍性:
鞍点的类型:
逃逸的必要性:
Lanczos算法是计算大规模对称矩阵极端特征值的有效方法:
算法流程:
输入:对称矩阵 H (通过 H*v 访问), 初始向量 v_0
输出:三对角矩阵 T_k, 正交基 V_k
v_1 = v_0 / ||v_0||
for j = 1 to k:
w = H * v_j
α_j = v_j^T * w
w = w - α_j * v_j - β_{j-1} * v_{j-1} (β_0 = 0)
β_j = ||w||
v_{j+1} = w / β_j
三对角矩阵: \(\mathbf{T}_k = \begin{bmatrix} \alpha_1 & \beta_1 & & \\ \beta_1 & \alpha_2 & \beta_2 & \\ & \beta_2 & \ddots & \beta_{k-1} \\ & & \beta_{k-1} & \alpha_k \end{bmatrix}\)
关键性质:
用于负曲率检测:
数值稳定性考虑:
| 监控正交性:$ | \mathbf{v}_i^T \mathbf{v}_j | < \epsilon$ |
随机化技术可以显著加速鞍点逃逸:
1. 随机扰动方法:
2. 随机化Lanczos:
3. Oja’s算法变体: 在线估计最小特征向量: \(\mathbf{v}_{t+1} = \mathbf{v}_t - \eta_t (\mathbf{H} \mathbf{v}_t + \lambda_t \mathbf{v}_t)\) 其中 $\lambda_t$ 是当前特征值估计。
4. 加速方法: Accelerated Gradient Descent with Negative Curvature (AGD+NC):
实践技巧:
Trust Region方法提供了利用负曲率的原则性框架:
子问题: \(\min_{\|\mathbf{d}\| \leq \Delta} m_k(\mathbf{d}) = f_k + \mathbf{g}_k^T \mathbf{d} + \frac{1}{2} \mathbf{d}^T \mathbf{H}_k \mathbf{d}\)
Moré-Sorensen算法: 精确求解trust region子问题:
负曲率的利用: 当 $\mathbf{H}_k$ 有负特征值时:
两阶段方法:
阶段1:计算Cauchy点
d_c = -α_c g_k, where α_c = argmin_{α} m_k(-α g_k)
阶段2:从Cauchy点出发,寻找更好的解
使用CG或Lanczos在子空间中优化
如果遇到负曲率,沿该方向到边界
收敛性保证:
利用负曲率可以获得更强的理论保证:
1. 二阶必要条件: 局部极小值 $\mathbf{x}^*$ 必须满足:
2. 逃逸鞍点的复杂度:
Cubic Regularization: \(\min_{\mathbf{d}} f_k + \mathbf{g}_k^T \mathbf{d} + \frac{1}{2} \mathbf{d}^T \mathbf{H}_k \mathbf{d} + \frac{\sigma}{3} \|\mathbf{d}\|^3\)
带负曲率的加速方法:
3. 随机算法的保证:
Perturbed GD (PGD):
if ||∇f(x_t)|| ≤ ε:
x_{t+1} = x_t + ξ_t, ξ_t ~ N(0, σ²I)
else:
x_{t+1} = x_t - η∇f(x_t)
4. 景观分析:
严格鞍点性质: 许多机器学习问题满足严格鞍点性质:
Polyak-Łojasiewicz (PL) 条件: \(\|\nabla f(\mathbf{x})\|^2 \geq 2\mu (f(\mathbf{x}) - f^*)\)
研究前沿:
1. Negative Curvature Descent (NCD):
结合梯度下降和负曲率方向的混合算法:
if λ_min(H) < -ε:
d = α_g * (-g) + α_n * v_min # 混合方向
else:
d = -g # 纯梯度方向
其中权重 $\alpha_g, \alpha_n$ 根据曲率强度自适应调整。
理论创新:
2. Hessian-Free Newton with Negative Curvature:
利用CG求解器的早停特性自然检测负曲率:
CG迭代中:
if p^T H p < 0: # 检测到负曲率
沿p方向到trust region边界
提前终止CG
优势:
3. 随机负曲率方法的最新进展:
SGLD with Negative Curvature: 将随机梯度Langevin动力学与负曲率结合: \(x_{t+1} = x_t - \eta_t(\nabla f(x_t) + \epsilon_t) + \sqrt{2\eta_t/\beta}\xi_t - \gamma_t \lambda_{min}v_{min}\)
其中 $\xi_t \sim \mathcal{N}(0, I)$ 是噪声项,最后一项是负曲率校正。
优势:
1. 层级负曲率检测:
不同网络层可能有不同的曲率特性:
for layer in network.layers:
H_layer = compute_layer_hessian()
λ_min, v_min = power_method(H_layer, k=10)
if λ_min < -threshold:
apply_negative_curvature_update(layer, v_min)
发现:
2. 负曲率与泛化的联系:
平坦度感知的负曲率利用:
实证观察:
3. 高效实现技巧:
GPU友好的Lanczos实现:
// 利用cuSPARSE for HVP
// 批量处理多个随机向量
// Warp-level原语优化
cublasHandle_t handle;
cusparseHandle_t sparseHandle;
// ... GPU优化的Lanczos迭代
混合精度考虑:
莫尔斯理论与鞍点:
临界点的拓扑特征:
连通性分析:
动力系统视角:
梯度流的稳定性分析: \(\frac{dx}{dt} = -\nabla f(x)\)
鞍点是不稳定平衡点:
分岔理论应用:
1. 高阶信息的利用:
三阶导数与逃逸速度: 考虑三阶项的影响: \(f(x + d) \approx f(x) + g^Td + \frac{1}{2}d^THd + \frac{1}{6}\sum_{ijk}T_{ijk}d_id_jd_k\)
研究表明三阶信息可以:
2. 分布式负曲率检测:
联邦学习中的挑战:
新方法:
3. 与现代AI的结合:
Transformer架构的特殊性:
生成模型中的应用:
4. 理论突破方向:
开放问题:
新工具开发:
Hessian近似的数值稳定性直接影响优化算法的可靠性和收敛性。本节探讨如何识别和缓解数值问题,设计鲁棒的算法。
条件数定义: \(\kappa(\mathbf{H}) = \frac{\lambda_{max}(\mathbf{H})}{\lambda_{min}(\mathbf{H})} = \|\mathbf{H}\| \cdot \|\mathbf{H}^{-1}\|\)
恶化来源:
1. 问题固有的病态性:
2. 算法引入的病态性:
3. 近似引起的问题:
诊断工具:
条件数估计(不需要完整矩阵):
1. 使用Lanczos估计极端特征值
2. 条件数估计器:CONDEST算法
3. 监控 ||H*v||/||v|| 的变化范围
预警信号:
Levenberg-Marquardt (LM) 方法通过添加阻尼项改善条件数:
基本形式: \((\mathbf{H} + \lambda \mathbf{I}) \mathbf{d} = -\mathbf{g}\)
其中 $\lambda > 0$ 是阻尼参数。
自适应策略:
初始化:λ = λ_0
repeat:
求解 (H + λI)d = -g
计算实际下降 Δf_actual = f(x+d) - f(x)
计算预测下降 Δf_pred = -g^T d - 0.5 d^T H d
比率 ρ = Δf_actual / Δf_pred
if ρ > 0.75: # 很好的近似
λ = λ / 2
elif ρ < 0.25: # 差的近似
λ = λ * 2
理论性质:
变体与扩展:
1. 自适应对角正则化: \((\mathbf{H} + \mathbf{D}) \mathbf{d} = -\mathbf{g}\) 其中 $\mathbf{D} = \text{diag}(\lambda_1, …, \lambda_n)$ 根据参数敏感度调整。
2. Trust Region联系: LM更新等价于求解: \(\min_{\mathbf{d}} \mathbf{g}^T \mathbf{d} + \frac{1}{2} \mathbf{d}^T \mathbf{H} \mathbf{d} \quad \text{s.t.} \quad \|\mathbf{d}\| \leq \Delta\) 其中 $\lambda$ 是Lagrange乘子。
3. 概率解释: 添加 $\lambda \mathbf{I}$ 相当于对参数施加高斯先验 $\mathcal{N}(0, \lambda^{-1} \mathbf{I})$。
预条件子 $\mathbf{M} \approx \mathbf{H}^{-1}$ 可以显著改善迭代方法的收敛性:
预条件系统: \(\mathbf{M}^{-1} \mathbf{H} \mathbf{d} = -\mathbf{M}^{-1} \mathbf{g}\)
设计原则:
常用预条件子:
1. 对角预条件(Jacobi): \(\mathbf{M} = \text{diag}(\mathbf{H})^{-1}\)
2. 不完全Cholesky分解: \(\mathbf{H} \approx \mathbf{L}\mathbf{L}^T, \quad \mathbf{M} = (\mathbf{L}\mathbf{L}^T)^{-1}\)
3. BFGS作为预条件子: 使用L-BFGS近似作为预条件: \(\mathbf{M} = \mathbf{H}_k^{LBFGS}\)
4. 多级预条件:
粗网格校正 + 细网格平滑
M^{-1} = S^T (I - P(P^T H P)^{-1} P^T H) S + P(P^T H P)^{-1} P^T
其中 $\mathbf{P}$ 是限制算子,$\mathbf{S}$ 是平滑算子。
自适应预条件:
理解误差如何在Hessian近似中传播对设计鲁棒算法至关重要:
误差来源:
| 舍入误差:$fl(x \pm y) = (x \pm y)(1 + \delta)$,$ | \delta | \leq \epsilon_{machine}$ |
误差传播分析:
1. 矩阵-向量乘积: \(\|fl(\mathbf{H}\mathbf{v}) - \mathbf{H}\mathbf{v}\| \leq n\epsilon_{machine}\|\mathbf{H}\|\|\mathbf{v}\| + O(\epsilon_{machine}^2)\)
2. BFGS更新误差: 设 $\tilde{\mathbf{H}}_k$ 是计算的近似,$\mathbf{H}_k$ 是精确值: \(\|\tilde{\mathbf{H}}_{k+1} - \mathbf{H}_{k+1}\| \leq \|\tilde{\mathbf{H}}_k - \mathbf{H}_k\| + C\epsilon_{machine}\) 误差可能累积!
3. 求解线性系统: 相对误差界: \(\frac{\|\tilde{\mathbf{x}} - \mathbf{x}\|}{\|\mathbf{x}\|} \leq \kappa(\mathbf{H}) \frac{\|\mathbf{r}\|}{\|\mathbf{b}\|}\) 其中 $\mathbf{r} = \mathbf{b} - \mathbf{H}\tilde{\mathbf{x}}$ 是残差。
稳定性增强技术:
1. 迭代精化:
求解 H x = b:
1. 计算近似解 x_0
2. for k = 0, 1, ...
r_k = b - H x_k
求解 H δ_k = r_k
x_{k+1} = x_k + δ_k
2. 混合精度策略:
3. Kahan求和: 减少浮点数累加误差:
sum = 0, c = 0
for x in values:
y = x - c
t = sum + y
c = (t - sum) - y
sum = t
1. 安全保护措施:
数值检查:
BFGS更新前检查:
if y^T s < ε * ||y|| * ||s||:
跳过更新或使用damped BFGS
if ||H|| > max_norm or cond(H) > max_cond:
重置为 H = I 或其他安全值
2. 修正技术:
Powell’s修正: 确保 $\mathbf{y}^T \mathbf{s} > 0$: \(\tilde{\mathbf{y}} = \theta \mathbf{y} + (1-\theta) \mathbf{B}_k \mathbf{s}\) 其中 $\theta$ 选择使得 $\tilde{\mathbf{y}}^T \mathbf{s} \geq 0.2 \mathbf{s}^T \mathbf{B}_k \mathbf{s}$
3. 自适应精度控制:
4. 重启策略:
实践建议总结:
研究方向:
1. 混合精度训练的稳定性:
动态损失缩放(Dynamic Loss Scaling):
scale = initial_scale
for iteration in training:
scaled_loss = loss * scale
compute_gradients(scaled_loss) # FP16
if gradients_contain_inf_or_nan:
scale *= backoff_factor
skip_update()
else:
unscale_gradients()
if scale < max_scale:
scale *= growth_factor
update_parameters() # FP32
关键洞察:
2. 分布式训练的数值一致性:
确定性并行归约: 不同的归约顺序导致不同的舍入误差:
# 非确定性
sum = parallel_reduce(values) # 顺序不定
# 确定性
sum = tree_reduce(values, deterministic=True)
解决方案:
3. 稀疏化与量化的影响:
梯度稀疏化的误差累积:
sparse_grad = top_k(grad, sparsity=0.99)
error_feedback += grad - sparse_grad
next_grad = compute_grad() + momentum * error_feedback
Hessian近似的修正:
1. 后验误差估计:
可计算的误差界: 对于线性系统 $\mathbf{H}\mathbf{x} = \mathbf{b}$,后验误差估计: \(\|\mathbf{x} - \tilde{\mathbf{x}}\| \leq \frac{\|\mathbf{r}\|}{\sigma_{min}(\mathbf{H})}\) 其中 $\mathbf{r} = \mathbf{b} - \mathbf{H}\tilde{\mathbf{x}}$ 是可计算的残差。
实践应用:
2. 区间算术与验证计算:
区间Hessian: \([\mathbf{H}] = [\mathbf{H}^L, \mathbf{H}^U]\) 保证真实Hessian在区间内。
应用:
3. 随机舍入的利用:
随机舍入定义: \(\text{SR}(x) = \begin{cases} \lfloor x \rfloor & \text{概率} \frac{\lceil x \rceil - x}{\text{ulp}(x)} \\ \lceil x \rceil & \text{概率} \frac{x - \lfloor x \rfloor}{\text{ulp}(x)} \end{cases}\)
优势:
案例1:大规模推荐系统的数值问题:
问题描述:
解决方案:
H_precond = BlockDiagonal([H_user, H_item, H_context])
λ_adaptive = λ_base * (1 + log(condition_number))
效果:
案例2:科学计算中的病态Hessian:
PDE离散化产生的Hessian:
多级方法:
# V-cycle
def v_cycle(A, b, x0):
# 前平滑
x = smooth(A, b, x0, n_pre)
# 限制到粗网格
r = b - A @ x
r_coarse = restrict(r)
# 粗网格求解
e_coarse = solve_coarse(A_coarse, r_coarse)
# 延拓到细网格
e = prolongate(e_coarse)
x = x + e
# 后平滑
x = smooth(A, b, x, n_post)
return x
1. 新硬件架构的挑战:
神经形态计算:
量子-经典混合:
2. 理论突破需求:
开放问题:
3. 软件工具发展:
自动数值稳定性分析:
4. 跨学科融合:
与其他领域的联系:
研究机会:
本章深入探讨了Hessian近似的各种技术,这些方法使得二阶优化在大规模问题上成为可能:
关键概念总结:
重要公式回顾:
练习 2.1:推导BFGS更新公式 证明BFGS更新公式保持对称性和正定性。具体地,如果 $\mathbf{B}k \succ 0$ 且 $\mathbf{y}_k^T \mathbf{s}_k > 0$,证明 $\mathbf{B}{k+1} \succ 0$。
提示:使用谱分解和Cauchy-Schwarz不等式。
练习 2.2:L-BFGS内存复杂度分析 设 $n$ 是问题维度,$m$ 是存储的向量对数。分析L-BFGS算法的时间和空间复杂度,并与完整BFGS比较。
提示:考虑双循环中的操作次数。
练习 2.3:Hessian-向量乘积的有限差分近似 给定函数 $f: \mathbb{R}^n \to \mathbb{R}$ 和向量 $\mathbf{v}$,如何用有限差分近似 $\mathbf{H}\mathbf{v}$?分析截断误差和舍入误差。
提示:考虑 $\nabla f(\mathbf{x} + h\mathbf{v})$ 的Taylor展开。
练习 2.4:块L-BFGS设计 设计一个块L-BFGS算法,同时更新多个方向。分析其优势和实现挑战。
提示:考虑块向量 $\mathbf{S}_k = [\mathbf{s}_1, …, \mathbf{s}_b]$ 和 $\mathbf{Y}_k = [\mathbf{y}_1, …, \mathbf{y}_b]$。
练习 2.5:自适应负曲率检测 设计一个算法,自适应地决定何时进行负曲率检测,平衡计算成本和收敛速度。
提示:监控梯度范数下降率和步长变化。
练习 2.6:混合精度L-BFGS 设计一个混合精度L-BFGS实现,在FP16和FP32之间智能切换。分析精度损失和性能提升的权衡。
提示:关键量(如 $\mathbf{y}_k^T\mathbf{s}_k$)使用高精度。
练习 2.7:分布式Trust Region求解 设计一个分布式算法求解大规模Trust Region子问题,考虑通信成本。
提示:使用Lanczos迭代的分布式版本。
练习 2.8:理论分析题 证明:对于强凸二次函数,使用精确线搜索的BFGS方法在 $n$ 步内收敛到精确解。
提示:利用共轭方向的性质。
detach()或stop_gradient及时释放