基于DeepONet的微分方程自动识别:从算子学习到方程提取

发布时间:2026/10/26 13:25:21
基于DeepONet的微分方程自动识别:从算子学习到方程提取

微分方程建模这件事,做过工程仿真或者物理系统辨识的人都清楚,最磨人的往往不是推导公式,而是拿到一堆观测数据之后,怎么把方程里那些未知的项、未知的系数给“反推”出来。传统做法要么靠领域经验手动试凑,要么用稀疏回归一类的方法在候选函数库里做筛选,前者吃经验,后者吃候选库的设计质量。这次要聊的这篇工作,思路换了个方向:把微分方程右端那个未知的算子,直接用一个神经网络去学,学出来之后再从网络里把方程“读”出来。它用的骨架是 DeepONet,也就是深度算子网络。整套东西解决的核心问题是——给定系统的观测轨迹,能不能自动识别出支配它的微分方程形式,而不是只拟合出一条曲线。

我把这篇文献反复啃了几遍,又自己动手复现了其中的关键环节,下面就把这套方法的来龙去脉、核心机制、实操细节和我踩过的坑,按从业者的视角完整拆一遍。适合已经了解神经网络基础、做过一点数值计算、想往科学机器学习方向深入的朋友参考;如果你只是想知道“神经网络能不能解方程”,那看完开头几节也能有个直观判断。

1. 整体思路拆解:为什么用算子学习来做方程识别

1.1 从“拟合函数”到“学习算子”的认知转变

普通神经网络做回归,学的是一个有限维到有限维的映射,比如输入一组坐标输出一个温度值。但微分方程描述的是一个函数到另一个函数的映射:给定初值函数或者边界条件函数,输出整条解曲线。这个映射的输入和输出都是函数,是无穷维空间里的对象。DeepONet 的设计初衷就是干这个的——它把“输入函数”和“输出函数的取值位置”分开处理,用两个子网络分别编码,最后做内积。这个结构不是随便拍的,背后有算子逼近的理论支撑,简单说就是分支网络负责捕捉输入函数在若干采样点上的整体形态,主干网络负责表达输出在某个坐标点上的基函数值,两者内积相当于在这个坐标点上把输入的影响“投影”出来。

放到方程识别这个任务里,思路就变得有意思了。假设我们有一个系统,它的动力学可以写成 $\frac{du}{dt} = N(u)$,其中 $N$ 是某个未知的非线性算子。传统上我们要猜 $N$ 长什么样,现在换个角度:把 $N$ 本身当成学习目标,用 DeepONet 去逼近这个算子。一旦网络训练好了,它就成了 $N$ 的一个可调用代理,我们再想办法从这个代理里把显式的方程形式提取出来。这个“先学算子、再提取方程”的两段式设计,是整篇文献最核心的方法论。

为什么这么设计?我理解有两个层面的考量。第一,直接做符号回归搜索空间太大,尤其当方程含多个非线性项时,候选组合爆炸;先用神经网络把算子学准,等于把搜索范围压缩到一个已经被数据验证过的映射上,后续提取的难度大幅下降。第二,DeepONet 的输入输出都是函数级别的,天然适配“给一条轨迹、预测整段演化”的场景,比逐点拟合的普通网络更贴合微分方程的本质。

1.2 与传统系统辨识方法的对比取舍

传统系统辨识里有一大类方法叫稀疏辨识,典型代表是从候选函数库(多项式、三角函数、指数等)里用稀疏回归挑出真正起作用的项。这类方法可解释性极强,识别出来的就是干干净净的方程。但它有个软肋:候选库得靠人设计,如果真实方程里有一项不在库里,那怎么回归都找不出来。而且当噪声较大、采样稀疏时,稀疏回归的数值稳定性会明显下降。

DeepONet 这条路线的取舍正好相反。它不预设候选库,网络容量足够大就能逼近相当一般的非线性算子,对噪声和稀疏采样的鲁棒性也更好,因为它是从整条轨迹的全局信息里学映射,而不是逐点做导数估计。代价是可解释性——网络本身是个黑箱,你得额外做一步“提取”。文献里这一步通常靠对网络输出做符号回归或者对候选项做系数拟合来完成。所以整套方法的定位很清楚:用神经网络的表达能力换取对未知算子的覆盖范围,再用后处理把可解释性补回来。这个组合在我看来是目前比较务实的路线,既没有放弃物理可解释性,又突破了手工设计候选库的瓶颈。

1.3 方法适用的场景边界

不是所有方程识别问题都适合这套方法。我梳理下来,它比较擅长的场景有这么几类:一是方程形式已知大致框架、但某些非线性项或系数未知,比如知道是反应扩散类型但反应项形式不明;二是观测数据是轨迹而非导数,逐点估导数噪声会被放大,而算子学习直接用轨迹做监督;三是系统维度不高但非线性强,高维问题下 DeepONet 的训练成本和采样需求都会上去。

反过来,如果方程本身就是线性的、候选库也很明确,那老老实实做稀疏回归更省事,没必要上神经网络。还有一种情况要谨慎:如果观测数据只覆盖了很窄的初值范围,学出来的算子只在这个范围内可信,外推能力有限,提取出的方程可能只是局部近似。这一点在实操里特别容易被忽略,后面讲数据准备时我会再展开。

2. DeepONet 的核心结构与方程识别的衔接细节

2.1 分支网络与主干网络的分工逻辑

DeepONet 的结构可以拆成两条腿。分支网络(branch net)吃的是输入函数在固定传感器点上的采样值,输出一个特征向量;主干网络(trunk net)吃的是输出函数的自变量坐标,也输出一个同维特征向量;两者做内积得到该坐标处的预测值。放到方程识别场景,输入函数通常是初始条件 $u_0(x)$ 或者某段历史轨迹,输出是未来某个时刻的解 $u(x,t)$。

这里有个细节值得说清楚:传感器点的选取不是随便的。分支网络的输入维度等于传感器点个数,这些点要能充分刻画输入函数的形态。如果初值函数比较光滑,均匀取几十个点通常够用;如果初值含局部剧烈变化,就得在变化区域加密,否则分支网络看到的输入是“糊”的,学出来的算子精度上不去。主干网络的输入是时空坐标,一般做归一化处理,把物理区间映射到 $[-1,1]$ 或者 $[0,1]$,这一步对训练稳定性影响很大,我实测下来不做归一化收敛会明显变慢。

两个子网络的输出维度要一致,这个维度相当于基函数的个数,是个超参数。维度太小表达力不够,太大容易过拟合且训练变慢。文献里常见的取值在几十到一两百之间,具体要看问题的复杂度和数据量。我的经验是先从 64 或 128 起步,观察训练和验证误差的走势再调。

2.2 算子学习如何转化为方程提取的入口

网络训练完之后,它就是一个“给定初值、预测演化”的代理模型。但我们要的是方程,不是代理。文献里的衔接方式是:利用网络对解的预测能力,在若干时刻、若干空间点上构造出解的样本,然后对这些样本做数值微分或者拟合,反推出 $\frac{du}{dt}$ 和 $u$ 及其各阶空间导数的对应关系,再用稀疏回归或者候选项系数拟合把方程形式定下来。

这个衔接的关键在于,网络预测的解要足够光滑、足够准,否则数值微分会把误差放大成噪声。所以训练阶段对精度的要求比单纯做预测任务更高。我在复现时发现,如果验证集上的相对误差在百分之一量级,提取方程还比较稳;如果到了百分之几,微分之后基本没法用。这就引出一个实操要点:训练时最好把解的导数信息也纳入监督,或者在损失里加一个光滑性正则项,让网络输出的解在微分之后仍然可靠。

2.3 损失函数设计与训练目标的匹配

标准 DeepONet 的损失就是预测解和真实解的均方误差。但用于方程识别时,我建议在损失里做两点增强。第一,加入对时间导数的监督,如果数据里能估出 $\frac{du}{dt}$(哪怕是有限差分估的),把它作为一个辅助监督项,能让网络学到的解在时间方向上更贴合真实动力学。第二,加入对空间导数的平滑约束,比如对解的二阶空间差分做惩罚,抑制高频振荡。

损失权重的搭配需要试。主损失(解的误差)权重设为 1,导数监督项权重从 0.1 到 1 之间调,平滑项权重一般设得很小,0.001 到 0.01 量级,太大反而会把真实的高频结构抹掉。这个搭配没有万能公式,得看具体问题的解有多光滑。我一般先只开主损失训到收敛,看提取效果,不行再逐项加。

3. 从数据到方程的完整实操流程

3.1 数据准备:轨迹采样与传感器点布置

数据是这套方法的地基。你需要的是系统在若干不同初值下的演化轨迹。每条轨迹包含时空网格上的解值。初值的多样性直接决定了学到的算子覆盖范围,我建议初值至少覆盖目标应用场景里可能出现的形态,比如做反应扩散问题,初值里既要有平滑分布,也要有带局部峰值的分布。

传感器点的布置前面提过,要贴合初值函数的特征尺度。一个实用的做法是先对初值集合做统计,看变化最剧烈的区域在哪,在那里加密采样点。传感器点数量我一般取 50 到 200 之间,太少刻画不了形态,太多分支网络输入维度上去、训练变慢且容易过拟合。

时间网格的步长要满足数值微分的精度要求。如果后续要用有限差分估时间导数,步长太大误差高,步长太小又会让相邻时刻的解差异微弱、信噪比低。经验上让每个时间步内解的变化量在解的量级百分之一到十分之一之间比较合适,具体得看系统的特征时间尺度。

注意:数据里的噪声水平要心里有数。如果轨迹本身带观测噪声,训练前最好做轻度平滑,否则网络会把噪声也学进去,提取方程时导数估计会非常不稳。

3.2 网络搭建与关键超参数设定

搭建部分我用的是比较标准的配置:分支网络和主干网络都用多层全连接,激活函数选 tanh 而不是 ReLU。原因很直接,tanh 输出光滑,对后续求导友好;ReLU 分段线性,二阶导几乎处处为零,做方程提取时空间导数信息会丢。层数一般 3 到 5 层,每层宽度 64 到 256。

输出维度(基函数个数)我通常设 64 或 128。优化器用 Adam,学习率从 1e-3 起步,训练中后期降到 1e-4。批大小看数据量,几百到几千都行。训练轮数不是固定值,盯着验证误差,连续若干轮不降就停。

这里有个容易踩的坑:分支网络和主干网络的输出如果直接内积,数值范围可能不好控制,实践中常加一个偏置项,或者对两个输出做归一化。我试过不加偏置,某些问题上收敛会卡住,加上之后顺畅很多。

3.3 训练监控与收敛判据

训练过程中我重点看三个量:训练损失、验证损失、以及一个“物理一致性”指标——用网络预测的解去估时间导数,看它和真实轨迹差分出来的导数是否吻合。前两个是常规监控,第三个是这套方法特有的,因为它直接关系到后续方程提取的质量。

收敛判据不能只看损失降没降。我遇到过损失降得很好但提取方程失败的情况,回头查发现是网络在解的某些局部区域误差偏大,而数值微分恰好放大了这些区域。所以验证时要看误差的空间分布,不能只看平均值。如果误差集中在少数区域,要么加密那里的传感器点,要么在损失里对这些区域加权。

3.4 方程提取:从网络输出到显式形式

提取这一步是整个流程的收口。具体操作是:用训练好的网络在时空网格上生成解,对时间做差分得 $\frac{du}{dt}$,对空间做差分得 $u$ 的各阶空间导数,然后把这些量组织成一个回归问题——$\frac{du}{dt}$ 作为因变量,$u, u_x, u_{xx}, u^2, u u_x$ 等候选项作为自变量,做稀疏回归或者带正则的最小二乘,挑出系数显著非零的项。

候选项的构造可以比传统稀疏辨识更宽松一些,因为网络已经把搜索范围压缩了,候选库大一点问题不大。但也不能无限大,项太多回归会不稳。我一般根据问题的物理背景列十几到几十个候选项,涵盖常见的线性项、低阶非线性项和低阶导数项。

提取出来的方程要回代验证:用识别出的方程做数值积分,和原始轨迹对比。如果吻合,说明提取成功;如果偏差大,要么网络精度不够,要么候选库漏了关键项。这个回代验证是必须做的,不能省。

4. 实操中的典型问题与排查经验

4.1 训练不收敛或收敛到平凡解

最常见的问题是网络输出趋近于零或者趋近于常数,损失看着在降但其实学了个平凡映射。排查顺序我一般是这样的:先看数据归一化做了没有,输入输出的量级差异太大会导致训练困难;再看学习率是不是太大,太大容易震荡或者直接发散;然后看网络宽度和深度是否匹配问题复杂度,太小的网络表达不了算子。

还有一个隐蔽原因:如果初值集合太单一,网络可能学到一个“忽略输入、直接输出平均演化”的映射,损失也能降下去,但算子根本没学到。解决办法是增加初值多样性,或者在损失里强化对输入差异的敏感度。

4.2 提取出的方程系数不稳定

系数不稳定通常指向两个源头。一是网络预测解的导数噪声大,这时候要么提高训练精度,要么在提取前对网络输出做一次平滑滤波。二是候选项之间存在共线性,比如 $u$ 和 $u^2$ 在某些数据区间高度相关,回归系数就会飘。应对办法是检查候选项的相关性矩阵,把高度相关的项做取舍,或者用带更强正则的回归。

我踩过的一个坑是时间步长选得不好,导致差分出来的 $\frac{du}{dt}$ 信噪比低,系数怎么调都不稳。后来把时间步长调到一个中间值,问题就缓解了。这个参数值得多试几组。

4.3 外推能力不足的识别与应对

网络在训练初值范围之外表现变差,这是算子学习的通病。判断方法是留出一部分初值不参与训练,专门做测试。如果测试误差远大于训练误差,说明外推能力不足。应对上,一是扩充训练初值的覆盖范围,二是在网络结构上做约束,比如让分支网络对输入的变化更敏感,三是接受这个局限,在应用时明确声明适用范围。

下面这张表是我整理的问题速查,方便对照排查。

现象可能原因排查与应对
损失不降学习率过大、数据未归一化降学习率、做输入输出归一化
收敛到平凡解初值多样性不足扩充初值集合、加权损失
提取系数不稳导数噪声大、候选项共线平滑输出、剔除高相关候选项
外推误差大训练初值覆盖窄扩充初值范围、约束网络结构
训练慢网络过宽、传感器点过多适度缩减宽度与采样点

4.4 计算资源与训练时间的现实考量

这套方法对算力的要求不算离谱,中等规模的 GPU 就能跑。但训练时间跟问题规模强相关:时空网格越密、传感器点越多、网络越宽,时间越长。我的经验是先用小规模配置快速跑通流程、验证方法可行性,确认提取逻辑没问题之后,再上大规模配置追求精度。一上来就堆大网络,调试周期会拉得很长,得不偿失。

另外,方程提取那一步的稀疏回归是 CPU 上的轻量计算,不构成瓶颈,真正花时间的是网络训练和超参数搜索。超参数搜索建议用粗网格先扫一遍关键参数(输出维度、学习率、损失权重),锁定大致范围后再细调。

5. 这套方法的价值边界与我个人的使用体会

把这篇文献的方法完整走一遍之后,我对它的定位有了更清楚的认识。它的真正价值不在于“替代传统方程发现方法”,而在于把算子学习和方程提取这两件事接了起来,让神经网络不再只是一个预测黑箱,而成为通向显式方程的桥梁。对于那些候选库难以手工设计、非线性又比较强的系统,这条路确实能打开局面。

但它的局限也很实在。网络精度是天花板,提取质量受制于训练质量;外推能力有限,适用范围得靠数据覆盖来保证;整个流程的超参数不少,调试需要耐心。我在实际使用中的体会是,把它当成一个“候选方程生成器”而不是“全自动方程发现机”更合适——它给你一个或几个高度可信的候选形式,最终的形式确认还得结合物理背景和回代验证来判断。

最后分享一个我觉得很实用的小技巧:在训练初期先用较少的传感器点和较窄的网络快速迭代,把数据管线和提取脚本跑通,确认整条链路没有逻辑错误,再逐步加规模。这样即使中间出问题,定位起来也快得多。这套流程我前后调了大概两周才跑顺,前期大部分时间其实花在数据准备和提取脚本的调试上,网络本身反倒不是最耗时的部分。如果你也在做类似的方向,建议把精力优先放在数据质量和提取环节的稳健性上,这两块决定了最终结果的上限。