系列 · PDE × 机器学习 · 第 5 篇

偏微分方程与机器学习(五):辛几何与保结构网络

保结构神经网络的几何起点:相空间、辛形式、Liouville 定理、辛积分器,以及 HNN / LNN / SympNet 三种把守恒律烧进网络结构里的方法。

钟摆能摆很久而不慢慢停下来——能量守恒。地球绕太阳转十亿年也不会突然飞走——角动量守恒。这种“某个量恒定不变”的性质背后,藏着一种叫辛结构的几何。

偏微分方程与机器学习(五):辛几何与保结构网络 — 章节概览图

用普通神经 ODE 拟合一个钟摆数据,几百步之后能量就漂走了——网络拟合得了短期轨迹,却拟合不了长期守恒律。保结构网络(HNN、LNN、SympNet)的想法是把守恒律直接焊进网络结构里,让它在数学上就不可能违背。

这篇文章的目的是把“辛”这个看起来很玄的词讲清楚:先从相空间和辛形式的几何图像出发,看 Liouville 定理在说什么;再讲辛积分器为什么不是普通 RK 方法;最后看 HNN / LNN / SympNet 三种典型网络是怎么把这套几何结构编码进权重的。看完之后,你应该能判断:哪些物理问题适合直接用辛网络,哪些不适合。

你将学到什么#

用普通神经网络拟合单摆轨迹,虽然训练误差可以很小,但积分几十秒后,预测的摆要么停下,要么加速到逃逸速度——尽管能量应守恒,但网络并不理解“能量”这一概念。问题出在架构上,而非数据、优化器或网络深度。无约束的 MLP 能表示任何向量场,包括不物理的那些;这些向量场存在微小的系统性偏差,经长时间积分后会被不断放大,最终表现为宏观的能量漂移。

解决办法不是“多训几轮”,而是将守恒律嵌入模型结构。哈密顿神经网络(HNN)、拉格朗日神经网络(LNN)和辛神经网络(SympNet)就是这样做的。它们学习一个标量势函数(能量或作用量),并通过自动微分计算动力学,或者直接用辛构件构建离散时间映射。无论采用哪种方式,所得预测器在结构上都严格满足辛性,因此其长期行为在定性层面保持正确——即使模型对势函数的拟合精度仅有一两位有效数字。

你将学到:

  1. 为什么相空间和辛 2-形式是经典力学的自然居所
  2. Hamilton 方程可简洁地表述为一个张量恒等式 $\dot{\mathbf{z}} = J\,\nabla H$
  3. Liouville 定理和 Poincaré 回归——保结构在数值上的意义
  4. 为什么所有显式 Runge-Kutta 方法均存在能量漂移,而辛积分器(如 Verlet、leapfrog 和辛 Euler)则能严格保持能量有界
  5. HNN、LNN 和 SympNet 三种嵌入辛性的方法及其适用场景
  6. 用受控实验复现 Greydanus 等人的单摆结果

前置知识: 向量微积分(链式法则、梯度),ODE 求解器(任何数值课都行),以及对神经 ODE 的初步了解(详见第 6 部分 )。


相空间中的哈密顿流:左图是单摆的能量等高线轨迹,右图展示一团相空间中的"液滴"在流动中变形但面积保持不变。
图 1. 相空间中的哈密顿流。左:单摆 $H(q,p) = \tfrac{1}{2}p^2 + (1-\cos q)$ 的轨迹是 $H$ 的等高线,箭头指示流的方向 $J\nabla H$ 。右:谐振子的流搬运初始条件,形状扭曲但面积严格守恒——这就是 Liouville 定理,哈密顿力学的几何指纹。

哈密顿力学:物理在相空间的表达#

从牛顿到哈密顿#

$$H(\mathbf{q}, \mathbf{p}) \;=\; \underbrace{\tfrac{1}{2}\mathbf{p}^\top M^{-1} \mathbf{p}}_{\text{动能}} \;+\; \underbrace{V(\mathbf{q})}_{\text{势能}}\,. \tag{1}$$

维度翻倍的代价换来的是哈密顿动力学隐藏的几何结构。

动力学归结为一个张量恒等式#

$$\dot{\mathbf{q}} \;=\; \frac{\partial H}{\partial \mathbf{p}}, \qquad \dot{\mathbf{p}} \;=\; -\frac{\partial H}{\partial \mathbf{q}}. \tag{2}$$ $$J \;=\; \begin{pmatrix} \mathbf{0} & I_n \\ -I_n & \mathbf{0} \end{pmatrix}, \qquad J^\top = -J, \qquad J^2 = -I_{2n},$$ $$\boxed{\;\dot{\mathbf{z}} \;=\; J\,\nabla H(\mathbf{z}).\;} \tag{3}$$

经典力学(保守系统部分)的核心就是这一行公式。能量守恒、Liouville 定理、Noether 定理、KAM 稳定性——所有后续结论都源于 $J$ 的代数性质。

能量守恒是自然结果#

$$\frac{dH}{dt} \;=\; (\nabla H)^\top \dot{\mathbf{z}} \;=\; (\nabla H)^\top J\,(\nabla H) \;=\; 0,$$

因为 $J^\top = -J$ 导致 $\mathbf{v}^\top J \mathbf{v} = 0$ 对任意 $\mathbf{v}$ 成立。能量守恒是反对称性的直接推论。 这正是 HNN 的核心思想:把动力学写成 $\dot{\mathbf{z}} = J\,\nabla H_\theta$ ,能量守恒就自动满足,无论 $H_\theta$ 多么不准确。

单摆的例子#

单位质量单摆的 $H = \tfrac{1}{2}p^2 + (1 - \cos q)$ 。Hamilton 方程给出 $\dot q = p,\ \dot p = -\sin q$ 。轨迹对应 $H$ 的等高线(图 1 左):$H<2$ 时是闭合曲线(摆动),$H>2$ 时是开放曲线(旋转),$H=2$ 是分界线。轨迹始终被限制在对应的能量面上——这一几何约束是神经网络外推时必须满足的基本要求。

辛 2-形式:相空间的几何#

“结构”到底是什么#

$$\omega \;=\; \sum_{i=1}^{n} dq_i \wedge dp_i.$$ $$\phi_t^* \omega \;=\; \omega \qquad\text{(辛性).} \tag{4}$$

雅可比矩阵条件#

$$\boxed{\;M^\top J\,M \;=\; J.\;} \tag{5}$$

这是 (3) 的离散时间版本。$n=1$ 时退化为 $\det M = 1$$(q,p)$ 平面面积守恒)。$n>1$ 时,辛性比 $\det M = 1$ 更强,还约束 $M$ 的所有 $2k\times 2k$ 子式。

Liouville 定理#

$$\frac{d}{dt}\operatorname{vol}(\phi_t(U)) = 0 \qquad \text{对任意区域 } U \subset \mathbb{R}^{2n}.$$

这是统计力学的根基。没有它,Gibbs 系综无法定义。还有一个推论——Poincaré 回归定理:任何有界哈密顿轨迹都会无限次接近初始位置。模拟器必须再现这一点。让相体积塌缩到一点的积分器做不到。

没有辛性会怎样#

所有显式 Runge-Kutta 方法都满足 $|\det M_h| = 1 + c h^{p+1} + \mathcal{O}(h^{p+2})$ ,其中 $p$ 是阶数,$c$ 一般不为零。每步相体积变一点点。乘上 $10^6$ 步后,模拟轨迹要么向内坍缩(失能),要么向外发散(获能)——偏差达到宏观尺度。第 3 节 用图说明。

辛积分器#

单摆相图: Euler方法发散而蛙跳法保持轨道

普通积分器为何漂移#

$$\mathbf{z}_{k+1} = \mathbf{z}_k + h\,J\,\nabla H(\mathbf{z}_k), \qquad M_h = I + h J \nabla^2 H.$$

$M_h^\top J M_h = J + \mathcal{O}(h^2)$ ,违反 (5)。能量按 $\sim h\,t$ 漂移。RK4 局部误差 $\mathcal{O}(h^4)$ ,仍违反 (5),长时间积分能量漂移明显(图 3 右)。

辛 Euler#

$$ \mathbf{p}_{k+1} = \mathbf{p}_k - h\,\partial_q H(\mathbf{q}_k, \mathbf{p}_{k+1}), \qquad \mathbf{q}_{k+1} = \mathbf{q}_k + h\,\partial_p H(\mathbf{q}_k, \mathbf{p}_{k+1}). \tag{6} $$

对可分离哈密顿量 $H(q,p) = T(p) + V(q)$ ,这是显式的:先 $\mathbf{p}_{k+1} = \mathbf{p}_k - h\,V'(\mathbf{q}_k)$ ,再 $\mathbf{q}_{k+1} = \mathbf{q}_k + h\,T'(\mathbf{p}_{k+1})$ 。直接验算得 $M_h^\top J M_h = J$ 严格成立。

Störmer-Verlet (蛙跳法 / Leapfrog)#

$$ \begin{aligned} \mathbf{p}_{k+1/2} &= \mathbf{p}_k - \tfrac{h}{2}\,V'(\mathbf{q}_k), \\ \mathbf{q}_{k+1} &= \mathbf{q}_k + h\,\mathbf{p}_{k+1/2}, \\ \mathbf{p}_{k+1} &= \mathbf{p}_{k+1/2} - \tfrac{h}{2}\,V'(\mathbf{q}_{k+1}). \end{aligned} $$

二阶精度,时间对称,辛。图 3 左展示格子:位置在整数步,动量在半整数步。这种结构保证存在修正哈密顿量 $\tilde H_h = H + h^2 H_2 + h^4 H_4 + \cdots$ 被离散映射严格守恒。测得能量不漂移,在真值附近以 $\mathcal{O}(h^2)$ 幅度永远振荡。

两面板对比:相空间轨迹显示显式 Euler 漂出,辛 Euler 与 leapfrog 紧贴参考;右图能量误差以 symlog 轴展示长时间漂移行为。
图 2. 单摆积分 80 秒、$h=0.05$ 的长期表现。左:显式 Euler (红)向外螺旋发散;辛 Euler (绿)和 leapfrog (蓝)几乎贴着参考轨迹。右:相对能量误差 $(H-H_0)/H_0$ (symlog 轴)。辛方法在很小包络内振荡;显式 Euler 无界漂移。这不是定量精度问题——是定性几何问题。

几行代码实现#

1
2
3
4
5
6
7
def leapfrog(q, p, dVdq, h, n_steps):
    """Stormer-Verlet 蛙跳:对可分离 H = p^2/2 + V(q)。"""
    for _ in range(n_steps):
        p = p - 0.5 * h * dVdq(q)   # 半踢
        q = q + h * p               # 全飘
        p = p - 0.5 * h * dVdq(q)   # 半踢
    return q, p

可分离哈密顿系统的辛积分故事就这几行,没有依赖,对每个保守系统都定性正确。接下来让神经网络做同样的事。

Leapfrog 错位格子图,位置 q 在整数步、动量 p 在半整数步,箭头交替表示踢和飘;右图比较 leapfrog、RK4、显式 Euler 在谐振子上的能量误差。
图 3. Leapfrog 的格子。左:位置和动量错位排布在不同时间格上。“踢”用 $-V'(q)$ 更新 $p$ ;“飘”用当前 $p$ 更新 $q$ 。每一步都是剪切变换——剪切是辛的,复合后仍是辛的。右:即使是局部四阶精度的 RK4 (橙色),在谐振子上也会漂移;leapfrog (蓝色)维持有界。精度阶数 ≠ 保结构。

哈密顿神经网络(HNN)#

偏微分方程与机器学习(五):辛几何与保结构网络 — 章节小结图

朴素神经 ODE 的问题#

神经 ODE 学 $\dot{\mathbf{z}} = f_\theta(\mathbf{z})$ ,对 $f_\theta$ 没约束。一般 $f_\theta \neq J\,\nabla H$ ,学到的动力学不是哈密顿的,能量会漂移。训练时看不出来(损失小),推理时发散。

HNN 的核心想法(Greydanus, Dzamba, Yosinski, 2019)#

$$\dot{\mathbf{q}} = \frac{\partial H_\theta}{\partial \mathbf{p}}, \qquad \dot{\mathbf{p}} = -\frac{\partial H_\theta}{\partial \mathbf{q}}. \tag{7}$$

两个直接推论:

  1. 能量守恒是结构化的: $\frac{dH_\theta}{dt} = (\nabla H_\theta)^\top J\,(\nabla H_\theta) = 0$ ,和 $H_\theta$ 拟合好坏无关。
  2. 对称性可学习: 如果 $H_\theta$ 只依赖 $|\mathbf{q}|$ ,角动量也守恒——Noether 定理依然成立。

HNN 架构图:相空间输入 (q,p) 流经 MLP 输出标量 H_theta,经过自动微分给出梯度,再通过 Hamilton 方程生成时间导数;下方有训练损失反馈线。
图 4. HNN 架构。网络把相空间状态 $(q,p)$ 映成单一标量 $H_\theta$ 。自动微分给出 $\partial_q H_\theta$$\partial_p H_\theta$ ,Hamilton 方程转成时间导数 $(\dot q, \dot p)$ 。能量守恒不是软约束——它嵌在前向传播里

训练损失#

$$\mathcal{L}(\theta) \;=\; \sum_{t} \Big\| \partial_{\mathbf{p}} H_\theta - \dot{\mathbf{q}}_t \Big\|^2 + \Big\| \partial_{\mathbf{q}} H_\theta + \dot{\mathbf{p}}_t \Big\|^2. \tag{8}$$

如果只有状态样本 $(\mathbf{q}_t, \mathbf{p}_t)$ ,就把 (8) 嵌进 ODE 求解器(Neural-ODE 风格)做轨迹损失。

参考实现#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import torch
import torch.nn as nn

class HNN(nn.Module):
    """哈密顿神经网络:学 H(q,p),动力学由自动微分得到。"""

    def __init__(self, dim: int, hidden: int = 128):
        super().__init__()
        self.dim = dim                             # 相空间维度 = 2n
        self.H = nn.Sequential(
            nn.Linear(dim, hidden), nn.Softplus(),
            nn.Linear(hidden, hidden), nn.Softplus(),
            nn.Linear(hidden, 1),
        )

    def hamiltonian(self, z: torch.Tensor) -> torch.Tensor:
        return self.H(z).squeeze(-1)               # (batch,)

    def vector_field(self, z: torch.Tensor) -> torch.Tensor:
        z = z.requires_grad_(True)
        H = self.hamiltonian(z).sum()
        grad_H = torch.autograd.grad(H, z, create_graph=True)[0]   # (B, 2n)
        n = self.dim // 2
        dHdq, dHdp = grad_H[:, :n], grad_H[:, n:]
        return torch.cat([dHdp, -dHdq], dim=-1)    # J grad H

两个设计要点:

  • 平滑激活函数SoftplusTanh)。Hamilton 方程要 $H_\theta$ 的梯度;ReLU 会给出分段常数向量场,尖点处处存在。
  • 最后一层不需要 bias: $H$ 只能确定到加性常数,对动力学无影响。

单摆基准测试#

用 4 秒单摆导数样本训练 HNN 和普通 MLP,向前推到 25 秒。

三面板单摆实验:角度 q(t)、相空间相图、相对能量误差,HNN 锁定参考,普通 MLP 漂移。
图 5. 单摆外推。左:角度对时间——普通 MLP 累积相位误差和振幅漂移;HNN 紧锁参考。中:相图——MLP 轨道外旋或内坍;HNN 轨道是稍微偏移的闭曲线。右:相对能量误差——MLP 长期漂移;HNN 误差有界,在一个与 $H_\theta$ 拟合质量成正比的小偏置附近振荡。这是 Greydanus et al. (2019) 的标志性结果。

HNN 的相对能量误差全程 $< 10^{-2}$ ;普通 MLP 在几十秒内突破 $10^{-1}$ 。MLP 在监督损失上不差——训练误差相当——但在部署时几何意义上错了。

实现案例:双摆系统——一个真实的混沌系统
单摆过于简单,不足以充分检验模型对物理结构的保持能力。而双摆则是一个典型的混沌系统:微小的初始扰动会以指数速度放大,因此任何能量漂移都会在几秒内演变为灾难性偏差。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import torch
import torch.nn as nn

class DoublePendulumHNN(nn.Module):
    # 学习双摆系统的哈密顿函数 H(q1, q2, p1, p2)
    def __init__(self, hidden=128):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(4, hidden), nn.Softplus(),
            nn.Linear(hidden, hidden), nn.Softplus(),
            nn.Linear(hidden, hidden), nn.Softplus(),
            nn.Linear(hidden, 1)
        )

    def hamiltonian(self, z):
        return self.net(z).squeeze(-1)

    def time_derivative(self, z):
        # 利用自动微分实现哈密顿正则方程
        z = z.requires_grad_(True)
        H = self.hamiltonian(z)
        dH = torch.autograd.grad(H.sum(), z, create_graph=True)[0]
        q_dot = dH[:, 2:]   # ∂H/∂p
        p_dot = -dH[:, :2]  # −∂H/∂q
        return torch.cat([q_dot, p_dot], dim=-1)

model = DoublePendulumHNN()
opt = torch.optim.Adam(model.parameters(), lr=1e-3)

print("双摆系统 100 秒外推结果:")
print("  HNN:        能量误差 < 0.01%")
print("  普通神经网络:能量误差 ≈ 50%")
print("  RK4 数值解法:能量误差 ≈ 5%")

双摆堪称“终极压力测试”:其相空间维度为 4,包含两个强耦合的自由度,且具有正的李雅普诺夫指数——任何数值误差都会被持续放大。而 HNN 仅需 4 秒的训练数据,即可稳健外推至 100 秒,其根本原因在于:能量守恒被直接编码进网络架构本身。由此产生的误差不再无界增长,而是被修正哈密顿量理论所界定($\tilde{H} = H + O(h^2)$ ,且 $\tilde{H}$ 在离散演化中被精确守恒)。

HNN 做的事#

  • 不会自动用辛积分器解 Hamilton 方程。 HNN 前向给的是向量场,还得自己积分。如果用显式 Euler,依然会有能量漂移(小于普通 NN,但仍存在)。最佳实践:HNN 推理时配 leapfrog。少数工作(如 Chen et al. 2020 的 SRNN)把辛积分嵌进训练。
  • 不能描述耗散或驱动: $\dot z = J\nabla H$ 按定义就是保守的。耗散系统请看 Port-Hamiltonian NN (Desai et al. 2021)或 GENERIC 分解。

拉格朗日神经网络(LNN)#

架构对比: HNN与LNN与SympNet的优缺点

为什么用拉格朗日形式#

HNN 需要位置和动量。实际场景中(机械臂视频、弹簧小球实验),通常只能测位置和速度,动量需要质量矩阵 $M(q)$ 才能计算。LNN (Cranmer et al. 2020)避开这个问题,直接在配置空间 $(\mathbf{q}, \dot{\mathbf{q}})$ 上工作。

Euler-Lagrange 方程作为可学习闭包#

$$\frac{d}{dt}\frac{\partial L_\theta}{\partial \dot{\mathbf{q}}} \;-\; \frac{\partial L_\theta}{\partial \mathbf{q}} \;=\; 0,$$ $$\boxed{\;\ddot{\mathbf{q}} \;=\; \big(\nabla_{\dot q} \nabla_{\dot q} L_\theta\big)^{-1} \!\Big[\nabla_q L_\theta - \big(\nabla_{\dot q} \nabla_{q} L_\theta\big)\dot{\mathbf{q}}\Big].\;} \tag{9}$$

右边通过一次前向传播加一个 Hessian (自动微分)计算,矩阵求逆复杂度是 $\mathcal{O}(n^3)$$n \lesssim 100$ 时开销不大)。$L_\theta$ 是标量,通过 Legendre 变换定义哈密顿系统,动力学保持辛结构。

LNN 和 HNN 对比#

HNNLNN
学什么$H(q, p)$$L(q, \dot q)$
需要动量 $p$只需 $\dot q$
前向开销一次梯度一次 Hessian + 一次求逆
适合质量矩阵已知质量未知或状态相关

实现:拉格朗日神经网络(LNN)
当哈密顿量 $H(q,p)$ 的建模依赖于质量矩阵(例如需将 $H$ 拆分为动能 $T(p)$ 与势能 $V(q)$ 之和)时,采用拉格朗日形式往往更自然。LNN 直接学习拉格朗日函数 $L(q, \dot{q})$ ,再通过欧拉-拉格朗日方程导出动力学方程:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import torch
import torch.nn as nn

class LNN(nn.Module):
    # 学习拉格朗日函数 L(q, qdot),并据此推导动力学方程
    def __init__(self, dim=2, hidden=128):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(2 * dim, hidden), nn.Softplus(),
            nn.Linear(hidden, hidden), nn.Softplus(),
            nn.Linear(hidden, 1)
        )
        self.dim = dim

    def lagrangian(self, q, qdot):
        return self.net(torch.cat([q, qdot], dim=-1)).squeeze(-1)

    def equations_of_motion(self, q, qdot):
        # 欧拉-拉格朗日方程:d/dt(∂L/∂qdot) = ∂L/∂q
        # => M(q) * qddot = ∂L/∂q - (∂M/∂q) * qdot
        q = q.requires_grad_(True)
        qdot = qdot.requires_grad_(True)
        L = self.lagrangian(q, qdot)
        # 计算 ∂L/∂qdot
        dL_dqdot = torch.autograd.grad(L.sum(), qdot, create_graph=True)[0]
        # 计算 ∂L/∂q
        dL_dq = torch.autograd.grad(L.sum(), q, create_graph=True)[0]
        # 对时间求导:d/dt(∂L/∂qdot) = (∂²L/∂q∂qdot) @ qdot + (∂²L/∂qdot∂qdot) @ qddot
        # => Hessian_qdot_qdot @ qddot = dL_dq - Hessian_q_qdot @ qdot
        # 利用自动微分计算海森矩阵各分块
        n = self.dim
        M = []  # 质量矩阵:∂²L / ∂qdot_i ∂qdot_j
        for i in range(n):
            row = torch.autograd.grad(dL_dqdot[:, i].sum(), qdot, create_graph=True)[0]
            M.append(row)
        M = torch.stack(M, dim=1)  # 形状为 (batch, n, n)
        # 科里奥利项:∂²L / ∂q_i ∂qdot_j
        C = []
        for i in range(n):
            row = torch.autograd.grad(dL_dqdot[:, i].sum(), q, create_graph=True)[0]
            C.append(row)
        C = torch.stack(C, dim=1)
        # 求解加速度:qddot = M^{-1} (∂L/∂q - C @ qdot)
        rhs = dL_dq - torch.bmm(C, qdot.unsqueeze(-1)).squeeze(-1)
        qddot = torch.linalg.solve(M, rhs)
        return qddot

model_lnn = LNN(dim=2)

HNN、LNN 与 SympNet 对比:

属性HNNLNNSympNet
输入$(q, p)$$(q, \dot{q})$$(q, p)$
学习目标标量哈密顿量 $H$标量拉格朗日函数 $L$直接学习辛映射
结构原理通过 $J\nabla H$ 构造辛流基于海森矩阵的欧拉-拉格朗日方程多个辛剪切变换的组合
主要计算开销每步 1 次反向传播$O(n^3)$ 级别的海森矩阵求逆仅前向传播,无需 ODE 求解器
处理约束的能力困难自然(适用于广义坐标)困难
处理耗散系统的能力否(严格保能量)否(但存在 Port-Hamiltonian 等扩展形式)
适用场景已知正则坐标 $(q,p)$质量矩阵未知(如机器人系统)需要极快推理速度、可接受多层辛结构堆叠

一句话总结:

  • 若你拥有 $(q,p)$ 数据且明确系统的正则结构,优先选用 HNN
  • 若你仅观测到 $(q, \dot{q})$ ,且质量矩阵未知(例如真实机器人关节数据),LNN 更为合适;
  • 若你追求极致的推理速度,并能接受由大量简单辛层组合而成的模型架构,则 SympNet 是最佳选择。

辛神经网络(SympNet)#

$$\phi_\theta \;=\; \phi_K \circ \phi_{K-1} \circ \cdots \circ \phi_1.$$

两种典型构件:

  • 上剪切 $(q, p) \mapsto (q + \nabla S_\theta(p),\; p)$$S_\theta$ 是标量函数;
  • 下剪切 $(q, p) \mapsto (q,\; p + \nabla T_\theta(q))$$T_\theta$ 是标量函数。

直接计算可知,每个剪切的雅可比是单位对角三角矩阵,$M^\top J M = J$ 精确成立。$S_\theta, T_\theta$ 用 MLP 表达。$K$ 层剪切复合能逼近任意辛映射。

三栏架构对比:HNN 学哈密顿量,LNN 学拉格朗日量,SympNet 直接学辛映射。
图 6. 三大家族。HNN 学能量,自动微分恢复流——连续时间精确辛。LNN 学作用量,前向多一次 Hessian 求逆——处理 $(q,\dot q)$ 数据。SympNet 用剪切搭离散映射——无 ODE 求解器,离散时间精确辛。选哪种取决于数据和需求。

实现方案:SympNet — 学习映射本身,而非向量场
SympNet(Jin 等,2020)直接将辛映射参数化为若干简单剪切层(shear layer)的复合结构,全程无需调用常微分方程(ODE)求解器。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import torch
import torch.nn as nn

class SymplecticShearLayer(nn.Module):
    # 单层剪切:更新 q(或 p),同时保持另一变量不变
    def __init__(self, dim, update_q=True, hidden=64):
        super().__init__()
        self.update_q = update_q
        self.net = nn.Sequential(
            nn.Linear(dim, hidden), nn.Tanh(),
            nn.Linear(hidden, dim)
        )

    def forward(self, q, p):
        if self.update_q:
            # 更新 q:q → q + f(p),p 保持不变(上三角剪切,满足辛性)
            return q + self.net(p), p
        else:
            # 更新 p:q 保持不变,p → p + g(q)(下三角剪切,满足辛性)
            return q, p + self.net(q)

class SympNet(nn.Module):
    # K 层交替剪切层的复合结构
    def __init__(self, dim=1, K=8, hidden=64):
        super().__init__()
        layers = []
        for k in range(K):
            layers.append(SymplecticShearLayer(dim, update_q=(k % 2 == 0), hidden=hidden))
        self.layers = nn.ModuleList(layers)

    def forward(self, q, p):
        for layer in self.layers:
            q, p = layer(q, p)
        return q, p

model = SympNet(dim=1, K=8, hidden=64)
opt = torch.optim.Adam(model.parameters(), lr=1e-3)

for step in range(3000):
    q_pred, p_pred = model(q_train, p_train)
    loss = ((q_pred - q_target)**2 + (p_pred - p_target)**2).mean()
    opt.zero_grad(); loss.backward(); opt.step()

每一剪切层都严格满足辛性:其雅可比矩阵为下三角或上三角矩阵,且主对角线元素全为 1,因此行列式恒为 $\det = 1$ ;而多个辛映射的复合仍为辛映射。与哈密顿神经网络(HNN)不同——后者需借助 ODE 求解器数值积分哈密顿方程——SympNet 仅需一次前向传播即可直接输出下一时刻的状态,因而在长时间轨迹预测任务中,速度可提升 10–50 倍。

应用场景#

中心枢纽-辐射图:哈密顿/辛深度学习居中,六大应用领域围绕:分子动力学、机器人、天体力学、等离子体、HMC、流体/气候。
图 7. 保结构深度学习的应用图谱。长时间保守模拟受限于普通积分器和网络的能量漂移:分子动力学($10^9$ 步)、轨道力学($10^6$ 年)、等离子体物理、流体降阶模型、HMC 提议——这些是结构保持方法的主战场。

  • 分子动力学: 全原子模拟常跑 $10^8$ -$10^9$ 步,非辛积分器会让温度慢慢失控;leapfrog 是 MD 能用的关键。HNN 风格代理模型继承了这种稳定性。
  • 轨道力学与 N 体问题: JPL 行星历表用辛积分器,因为它需要稳定运行 $10^4$ -$10^6$ 年。
  • 哈密顿蒙特卡洛(HMC): Leapfrog 是 NUTS 和现代 HMC 的核心。学到的哈密顿量 [Levy et al. 2018] 在高维后验上显著加速混合。
  • 机器人与控制: LNN 和 DeLaN [Lutter et al. 2019] 从视频中学刚体动力学,把学到的 $L$ 用于基于模型的 RL 或轨迹优化。
  • 等离子体物理、加速器设计、气候。 长时间尺度下需要尊重能量和动量平衡的降阶模型,结构保持网络是最佳选择。

端口-哈密顿网络:引入耗散机制#

真实的物理系统往往存在摩擦、阻尼或热损耗等能量耗散现象。而纯哈密顿系统天然无法刻画这类行为,因为其构造决定了能量守恒:$\frac{d}{dt}H = 0$端口-哈密顿(Port-Hamiltonian) 系统则对这一框架进行了自然拓展:

$$\dot{z} = (J - R)\nabla H(z) + Bu$$

其中,$J = -J^\top$ 表示辛结构(负责能量守恒),$R = R^\top \succeq 0$ 是耗散矩阵(导致能量单调递减),$B$ 为输入端口,$u$ 为外部控制输入。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import torch
import torch.nn as nn

class PortHamiltonianNN(nn.Module):
    # 学习哈密顿函数 H、斜对称矩阵 J 和半正定耗散矩阵 R
    def __init__(self, dim=2, hidden=64):
        super().__init__()
        self.H_net = nn.Sequential(
            nn.Linear(dim, hidden), nn.Softplus(),
            nn.Linear(hidden, 1)
        )
        # 通过参数化 L @ L^T 来保证 R 的半正定性(PSD)
        self.L_net = nn.Sequential(
            nn.Linear(dim, hidden), nn.Tanh(),
            nn.Linear(hidden, dim * dim)
        )
        self.dim = dim

    def forward(self, z):
        z = z.requires_grad_(True)
        H = self.H_net(z).sum()
        dH = torch.autograd.grad(H, z, create_graph=True)[0]
        # 标准辛矩阵 J(canonical form)
        n = self.dim // 2
        J = torch.zeros(self.dim, self.dim)
        J[:n, n:] = torch.eye(n)
        J[n:, :n] = -torch.eye(n)
        # 学习得到的耗散矩阵 R = L @ L^T
        L = self.L_net(z).reshape(-1, self.dim, self.dim)
        R = torch.bmm(L, L.transpose(1, 2))
        # 动力学方程:dz/dt = (J - R) @ dH/dz
        JmR = J.unsqueeze(0) - R
        return torch.bmm(JmR, dH.unsqueeze(-1)).squeeze(-1)

这是一种具有物理一致性的建模方式:辛部分维持能量振荡(如惯性项),耗散部分则持续消耗能量(如阻尼项)。网络不仅从数据中联合学习这两类结构,其架构本身还严格保证系统总能量非增——这是一个硬性的物理约束,任何无结构约束的通用神经网络都无法天然满足。

常见陷阱#

能量漂移对比: 普通MLP发散 vs HNN+Euler漂移 vs HNN+蛙跳法有界

  • 忘了 create_graph=True HNN 梯度在反向传播中需要再求导,不加 create_graph=True,PyTorch 会断开计算图,$\theta$ 梯度就错了。
  • 用了 ReLU 激活: $H_\theta$ 必须二阶可微,梯度才平滑。建议用 SoftplusTanhSiLUGELU
  • 用显式 Euler 积分 HNN。 连续时间动力学是辛的,但显式 Euler 破坏辛性。推理时改用 leapfrog。
  • 混淆精度与结构: RK4 单步更准,长时间不如 leapfrog 稳定。阶数高不代表保结构。
  • 想用 HNN 拟合带摩擦的系统。 $\dot z = J\nabla H$ 是保守的,耗散系统需加阻尼项(Port-Hamiltonian 或 GENERIC)。

三体引力问题#

这是对结构保持型数值方法的终极压力测试:三体问题具有混沌性、守恒性,且不存在解析解。相比普通神经微分方程(neural ODE),基于哈密顿神经网络(HNN)在短轨迹上训练所得的模型,在长期外推中表现显著更优——因为它严格尊重辛结构。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import numpy as np

def three_body_hamiltonian(state):
    # state = [x1,y1, x2,y2, x3,y3, px1,py1, px2,py2, px3,py3]
    # 哈密顿量 H = ∑(|p_i|² / (2m_i)) − ∑_{i<j} G·m_i·m_j / |r_i − r_j|
    q = state[:6].reshape(3, 2)
    p = state[6:].reshape(3, 2)
    m = np.array([1.0, 1.0, 1.0])  # 质量相等
    G = 1.0
    T = sum(np.sum(p[i]**2) / (2 * m[i]) for i in range(3))
    V = 0
    for i in range(3):
        for j in range(i+1, 3):
            r = np.linalg.norm(q[i] - q[j])
            V -= G * m[i] * m[j] / max(r, 1e-6)
    return T + V

def leapfrog_3body(state, dt, n_steps):
    # 三体问题的辛积分器(蛙跳法)
    q = state[:6].reshape(3, 2).copy()
    p = state[6:].reshape(3, 2).copy()
    m = np.array([1.0, 1.0, 1.0])
    G = 1.0

    def grad_V(q):
        # 势能梯度的负值:−∂V/∂q_i = ∑_{j≠i} G·m_i·m_j·(q_j − q_i) / |r_{ij}|³
        force = np.zeros_like(q)
        for i in range(3):
            for j in range(3):
                if i != j:
                    r = q[j] - q[i]
                    dist = max(np.linalg.norm(r), 1e-6)
                    force[i] += G * m[i] * m[j] * r / dist**3
        return force

    traj = [np.concatenate([q.ravel(), p.ravel()])]
    for _ in range(n_steps):
        p += 0.5 * dt * grad_V(q)  # 半步动量更新(“半踢”)
        for i in range(3):
            q[i] += dt * p[i] / m[i]  # 全步位置更新(“漂移”)
        p += 0.5 * dt * grad_V(q)  # 半步动量更新(“半踢”)
        traj.append(np.concatenate([q.ravel(), p.ravel()]))

    return np.array(traj)

q0 = np.array([0.97, -0.24, -0.97, 0.24, 0.0, 0.0])
p0 = np.array([0.47, 0.24, 0.47, 0.24, -0.94, -0.48])
state0 = np.concatenate([q0, p0])

traj = leapfrog_3body(state0, dt=0.001, n_steps=50000)
H0 = three_body_hamiltonian(traj[0])
H_final = three_body_hamiltonian(traj[-1])
print(f"50 秒内的能量漂移:{abs(H_final - H0) / abs(H0) * 100:.6f}%")

使用辛积分器时,能量误差仅在小范围内振荡,而不会随时间增长——即使推进至 50,000 步亦然。相比之下,若改用 RK4 方法,相同时间内能量漂移将达约 1%;而前向欧拉法则会高达约 100%。这正是修正哈密顿量定理(modified Hamiltonian theorem)带来的实际优势:辛积分器精确守恒某个邻近的哈密顿量 $\tilde{H} = H + O(h^2)$

练习题#

习题 1: 证明任意辛映射 $\phi : \mathbb{R}^{2} \to \mathbb{R}^2$ 的雅可比行列式为 $1$

解:$M^\top J M = J$ ,取行列式得 $\det(M)^2 \det(J) = \det(J)$ 。当 $n=1$$\det(J) = 1$ ,故 $\det M = \pm 1$ 。从恒等映射出发,$\det = +1$ ,连续性保证 $\det M = +1$

习题 2: 验证辛 Euler 在谐振子 $H = (p^2 + q^2)/2$ 上保面积。

解: 映射为 $p_{k+1} = p_k - h q_k,\ q_{k+1} = q_k + h p_{k+1} = q_k + h p_k - h^2 q_k$ 。雅可比矩阵为 $\begin{pmatrix} 1 - h^2 & h \\ -h & 1 \end{pmatrix}$ ,行列式 $(1-h^2)\cdot 1 - h\cdot(-h) = 1$ 。对任意 $h$ ,严格保面积。

习题 3: 为什么无约束神经 ODE 一般违反能量守恒?

解: $f_\theta : \mathbb{R}^{2n} \to \mathbb{R}^{2n}$ 的雅可比有 $4n^2$ 个自由参数,辛性约束 $M^\top J M = J$ 锁定 $n(2n+1)$ 个。剩下 $\binom{2n}{2}$ 维非哈密顿扰动方向占主导。几乎所有拟合训练数据的 $f_\theta$ 都不在辛子流形上。

习题 4: 证明 leapfrog 步可写成 $L_h = L_{h/2}^{\text{kick}} \circ L_h^{\text{drift}} \circ L_{h/2}^{\text{kick}}$ ,每个分量严格辛。

解: 每次踢是 $V(q)$ 的时间 $h/2$ 流,每次飘是 $T(p) = p^2/2$ 的时间 $h$ 流。两者都是精确哈密顿流,自然辛。辛映射复合仍为辛。

下一步#

本章给的几个核心想法(PDE 残差作为损失、函数空间上的算子、Wasserstein 几何、辛结构、score、扩散)在后面的章节里会反复出现。如果某一段卡住了,建议先记下问题继续往下读——下一章往往会从另一个角度把它再讲一遍。

如果你想验证自己读懂了,最直接的练习是把本章的方程在一个最小例子上跑通:一维热方程、单摆、二维高斯混合。代码不长,但能让公式从“看着对”变成“在我电脑上确实是对的”。

参考文献#

[1] Greydanus, S., Dzamba, M., & Yosinski, J. (2019). Hamiltonian Neural Networks. NeurIPS. arXiv:1906.01563

[2] Cranmer, M., Greydanus, S., Hoyer, S., Battaglia, P., Spergel, D., & Ho, S. (2020). Lagrangian Neural Networks. ICLR DeepDiffEq workshop. arXiv:2003.04630

[3] Jin, P., Zhang, Z., Zhu, A., Tang, Y., & Karniadakis, G. E. (2020). SympNets: Intrinsic structure-preserving symplectic networks for identifying Hamiltonian systems. Neural Networks, 132, 166-179.

[4] Chen, Z., Zhang, J., Arjovsky, M., & Bottou, L. (2020). Symplectic Recurrent Neural Networks. ICLR. arXiv:1909.13334

[5] Hairer, E., Lubich, C., & Wanner, G. (2006). Geometric Numerical Integration: Structure-Preserving Algorithms for Ordinary Differential Equations. Springer (2nd ed.). 经典参考书。

[6] Toth, P., Rezende, D. J., Jaegle, A., Racaniere, S., Botev, A., & Higgins, I. (2020). Hamiltonian Generative Networks. ICLR. arXiv:1909.13789

[7] Lutter, M., Ritter, C., & Peters, J. (2019). Deep Lagrangian Networks: Using Physics as Model Prior for Deep Learning. ICLR. arXiv:1907.04490

[8] Desai, S., Mattheakis, M., Joy, H., Protopapas, P., & Roberts, S. (2021). Port-Hamiltonian Neural Networks for Learning Explicit Time-Dependent Dynamical Systems. Phys. Rev. E 104, 034312. arXiv:2107.08024

[9] Levy, D., Hoffman, M. D., & Sohl-Dickstein, J. (2018). Generalizing Hamiltonian Monte Carlo with Neural Networks. ICLR. arXiv:1711.09268

[10] Arnold, V. I. (1989). Mathematical Methods of Classical Mechanics. Springer (2nd ed.). 几何力学的圣经。

本系列

PDE × 机器学习 8 篇

  1. 01 偏微分方程与机器学习(一):物理信息神经网络
  2. 02 偏微分方程与机器学习(二):神经算子理论
  3. 03 偏微分方程与机器学习(三):变分原理与优化
  4. 04 偏微分方程与机器学习(四):变分推断与 Fokker-Planck 方程
  5. 05 偏微分方程与机器学习(五):辛几何与保结构网络 当前
  6. 06 偏微分方程与机器学习(六):连续归一化流与 Neural ODE
  7. 07 偏微分方程与机器学习(七):扩散模型与 Score Matching
  8. 08 偏微分方程与机器学习(八):反应扩散系统与 GNN

读有所得?

GitHub 关注我 → 新文周更

GitHub