偏微分方程(PDE)求解太慢,在线控制做不了;想上强化学习(RL),又没人愿意给真实系统几千次试错的机会。这不是某一个项目独有的问题,而是很多做仿真、控制和优化的人共同的困境。把 PINN 和 RL 放在一起,恰恰是为了同时解开这两把锁:用物理信息神经网络代替传统求解器,把 PDE 的计算成本降下来;再用强化学习在廉价但物理可信的仿真环境里快速试错,直接学出控制策略。这篇文章就把这条链路拆开讲清楚,适合正在做智能控制、数字孪生或参数优化的工程师和研究者参考。
1. PINN 和 RL 的组合,到底解决的是什么样的问题
1.1 PDE 求解是仿真的底层瓶颈
在工业仿真里,偏微分方程几乎是无处不在的底层语言。设备传热、结构应力、流体流动、电磁场分布,甚至材料微观演化,都可以用 PDE 描述。传统做法是把这些方程交给数值方法去求解,比如有限元(FEM)、有限体积(FVM)、有限差分(FDM)。这套路径很成熟,工程上用了半个多世纪,但它有一个绕不开的问题:重。
首先是网格生成。对一个复杂几何体做高质量的网格剖分,本身就是一件消耗工时的事,尤其遇到异形结构、多尺度特征或者强非线性材料时,网格质量的调优经常要耗去项目里相当长的时间。其次是求解成本,一般一个三维瞬态问题,单次求解从几分钟到几十个小时都很常见,边界条件一改、载荷一变,就得从头再算一遍。于是 PDE 求解器往往只被用在离线分析阶段,很难进入需要实时决策的闭环控制环节。
更头疼的是那些“必须反复求解”的场景。参数优化要遍历成百上千组工况,每个工况都是独立的一次求解;控制策略评估要模拟系统在不同扰动下的响应,扰动一变,又得重新算。实际项目中经常会看到这样的矛盾:模型精度明明够,但求解太慢,导致优化迭代做不起来;或者因为单次求解太慢,工程师只能凭经验挑几个固定方案试试,根本谈不上真正的设计空间探索。这些瓶颈本质上都是“单次求解成本太高”带来的连锁效应。
1.2 RL 的价值与硬伤
强化学习在这类问题上的吸引力很直接:它不需要你预先知道最优控制规律长什么样,只要能把问题表达成“状态—动作—奖励”的形式,它就能在与环境交互的过程中自主学习出策略。相比经典控制方法,RL 在处理非线性强、约束复杂、目标多样的问题时特别有优势。PID 只能处理线性化后的小范围问题,模型预测控制虽然能处理约束,但每一步都要做一次在线优化,对计算要求极高。RL 走的是另外一条路:离线训练时不惜代价,部署时变成一次前向推理,毫秒级出动作。
但 RL 也有一个硬伤,样本需求量极大。几万步交互只能算热身,几十万步很常见。如果每一步交互都要调用一次传统 PDE 求解器,那训练成本就高到了无法接受的程度。我把一个有限元模型包进 RL 环境里做过一次实验,单步求解时间大概 0.5 秒,一个完整回合 40 步,训练 10 万步就等于要跑 400 万个单步,哪怕并行开 8 个环境,也得跑好几天到几周。这个体验基本断送了“直接用数值求解器给 RL 当环境”的想法。
1.3 PINN+RL:用代理模型换训练成本
PINN 的定位恰好填补了 RL 的这个短板。PINN 把 PDE 的残差写进神经网络损失函数,训练完成后,网络前向推理就是一次极廉价的运算,能快速给出整个时空范围内的近似解。这个近似解未必达到有限元级别的精度,但用来给 RL 当训练环境,精度往往绰绰有余。
于是就有了一个非常顺手的组合:PINN 做高速代理模型(surrogate model),给 RL 提供快速试错环境;RL 在这个快环境里大规模探索,学出策略后再回到真实系统做少量微调。仿真、控制、优化三个环节都会在“快”字上受益。仿真用 PINN 快,控制用 RL 学得快,优化则因为一次 PINN 训练能覆盖大量工况而快。
这里要特别澄清一点:PINN 加 RL 并不是要把经典数值方法和传统控制方法彻底取代。它更像是一个面向“需要大量重复求解加决策时序性强”的场景增强方案。经典方法依然在精度校验和可靠交付上发挥作用,只是不再被摆到每一次循环的中心位置。理解了这条定位,后面的技术拆解才有清晰的坐标。
2. PINN 如何把物理定律塞进神经网络
2.1 一个例子看懂 PINN 的损失函数
PINN 的核心思想可以用一句话概括:把网络输出当作 PDE 的近似解,用自动微分算出它关于空间和时间的导数,代入 PDE 方程计算残差,然后把这个残差作为损失项去训练网络。
以最经典的 1D 热传导方程为例:
∂u/∂t = α ∂²u/∂x²
其中 u 是温度,α 是热扩散系数。把网络输出记作 û(x,t),损失函数可以拆成三块:
- 内部残差损失:把 û 代入 PDE 后得到的方程残差
- 初始条件损失:在 t=0 时刻,网络输出与已知初始温度分布的误差
- 边界条件损失:在 x=0 和 x=L 处,网络输出与已知边界条件的误差
写成 Python 伪代码,大概是这样:
import torch def pde_residual(model, x, t, alpha): x.requires_grad_(True) t.requires_grad_(True) u_hat = model(torch.cat([x, t], dim=1)) u_t = torch.autograd.grad( u_hat, t, grad_outputs=torch.ones_like(u_hat), create_graph=True )[0] u_x = torch.autograd.grad( u_hat, x, grad_outputs=torch.ones_like(u_hat), create_graph=True )[0] u_xx = torch.autograd.grad( u_x, x, grad_outputs=torch.ones_like(u_x), create_graph=True )[0] return u_t - alpha * u_xx # 在内部点、边界点、初始点上分别采样,组合出总损失 loss = torch.mean(pde_residual(model, x_in, t_in, alpha) ** 2) loss += torch.mean((model(x_bc, t_bc) - bc_values) ** 2) loss += torch.mean((model(x_ic, t_ic) - ic_values) ** 2)这个思路的好处很明显:不需要生成网格,不需要组装刚度矩阵,不需要求解大规模线性方程组。网络参数通过梯度下降优化,训练完成后,任意一个坐标点上的近似解都能通过一次前向传播拿到。
但这里需要补充一个工程上的真实判断:无网格特性带来的一个代价是精度控制不如传统方法直观。传统数值方法有严格的收敛性分析和误差估计,PINN 则更多依赖训练过程的监控和校验。所以在做有严格精度要求的工程输入时,我会用经典数值方法算出少量高精度数据来辅助训练,或者用分区域 PINN 处理复杂几何。对于控制类问题,这个精度通常足够,因为策略学习对模型误差有天然容忍度,它不需要知道绝对精确的温度值,只需要知道“温度上升还是下降”“变化趋势有多快”这类相对信息。
2.2 与传统数值方法的关键差异
传统数值方法和 PINN 的差异,可以在几个维度上做对比:
| 对比维度 | 传统数值法(FEM/FVM/FDM) | PINN |
|---|---|---|
| 网格依赖 | 高,需要网格生成与剖分 | 低,采样点即可 |
| 单次求解耗时 | 分钟级到小时级 | 毫秒级到秒级 |
| 多参数重用性 | 参数变化需要重新求解 | 参数作为网络输入后可一次覆盖 |
| 精度可控性 | 成熟,收敛性有严格保证 | 依赖训练质量与采样策略 |
| 与深度学习生态结合 | 弱 | 天然适合 |
最值得关注的是“多参数重用性”。把 PDE 中的物理参数,比如导热系数 α、源项强度 q、边界温度值,都作为网络的额外输入,就能训练出一个参数化模型。这样一来,一次训练就能覆盖整个参数空间里的任意组合,预测一个新工况只是换一组输入做一次前向传播。这等于把“每试一次参数就要重新求解一次”变成了“查表推理”。
举个具体的数字例子。某 2D 热传导问题,用传统方法对单一参数组求解需要约 30 秒。PINN 单工况训练大约需要 600 秒,训练完成后对新参数组的预测只需 5 毫秒。如果只需要评估 1 组参数,PINN 毫无优势;但如果要评估 100 组参数,传统方法要 3000 秒,PINN 要 600.5 秒。交叉点非常早,大约在第 20 组参数左右。做设计优化时,要评估的参数组往往远超这个数,所以 PINN 的收益是压倒性的。
2.3 “快”的具体来源
PINN 的快不是训练阶段快,恰恰相反,PINN 训练往往比传统单次求解更慢。真正的快体现在两个时间点上。
第一是训练完成后的推理快。一个几十万参数的 MLP 在 GPU 上做一次前向传播,几毫秒就能完成。这个延迟对实时控制来说完全可接受,甚至比传感器采样周期还短。
第二是参数化复用快。如果网络把 PDE 参数、初始条件、边界条件都编码为输入,那么同一个网络覆盖的是一整个工况族,而不是单个工况。这种“一次训练、到处推理”的模式,对参数优化场景的价值是决定性的。
但也要强调一下时机问题。当项目只是偶尔做一两次仿真,不涉及大量重复求解时,使用 PINN 的收益并不明显,甚至可能亏本。我在项目启动前一定会先算这笔账:如果整个生命周期里待评估的工况数量少于某个阈值,老老实实用传统求解器反而更稳妥。
2.4 训练 PINN 的实用建议
基于实际操作经验,有几个训练 PINN 的细节值得单独拿出来讲。
激活函数的选择。PINN 要求网络输出对输入有足够光滑的导数,我优先使用 tanh 作为隐藏层激活函数,因为它的导数在整个定义域内连续且光滑,非常适合需要计算二阶导数的 PDE 残差。ReLU 类激活函数虽然收敛快,但二阶导数为零,无法直接用于二阶 PDE 的残差计算,强行使用会导致梯度失效。
采样点布局。不要只依赖均匀采样。在边界附近、初始时刻附近,以及可能产生较大梯度的区域,要额外加密采样。我在做热传导问题时,会把边界和初始时段附近的采样密度提高 2 到 3 倍,因为边界和初始条件在损失函数中的权重通常很高,如果采样不足,网络会很容易“优先”满足方程残差而忽略边界条件。
损失权重。不同损失项的尺度可能差几个数量级。比如内部残差的初始值可能是 10 的平方量级,而边界损失的初始值只有 10 的负几次方。如果不做权重调整,训练初期梯度完全被内部残差主导,边界条件几乎学不到。实践中可以对损失项做自适应加权,或者先把所有项归一化到同一量级,再按训练过程中的精度表现动态调整权重。
3. 从 PDE 到策略:RL 是怎么学控制的
3.1 控制问题的状态、动作、奖励
把 PDE 控制问题转化为 RL 问题,第一件要做的事是定义状态、动作和奖励。这一步做得好坏直接决定了训练能不能收敛,也是整个流程中最需要领域直觉的地方。
对于 PDE 描述的分布参数系统,状态通常不能是整个场。一个 2D 温度场的节点可能有几万个,直接把整个场作为 RL 状态,维度太高,策略网络根本吃不消。合理的做法是用低维特征来概括系统状态,比如关键测点的温度值、温度的变化率、系统总能量、环境温度等。这些特征需要根据控制目标来选择,能回答“当前系统处于什么状态”“离目标还有多远”这两个问题就够了。
动作的定义相对直接,就是控制量:加热功率、冷却流量、阀门开度、电流强度等。连续动作空间一般用 Box 空间定义,离散动作则用 Discrete 空间。多数 PDE 控制问题的控制量是连续的物理量,所以优先用连续动作空间。
奖励函数的设计可以分成几层考虑。最基本的做法是:
- 对偏离目标状态给出负奖励
- 对控制能量消耗给出负奖励
- 对快速到达目标状态给出正奖励
关键是要把这几个因素的权重搭配好,让策略学出来的行为真正符合工程需求。
3.2 奖励函数怎么做才不会翻车
奖励函数是 RL 里最容易出问题、也最值得花时间的地方。工程控制场景和游戏场景最大的不同在于:游戏里奖励设计得不好只是游戏体验差,工程里奖励设计得不好可能导致设备损坏或者安全事故。
最常见的问题是把安全约束当成软惩罚项。举个例子,如果温度上限是 100 度,你把超温惩罚写成线性项,策略很可能会学会在 99 度附近游走,偶尔超温,用整体能耗的节省来对冲罚款。这在控制场景里不可接受。还要注意稀疏奖励问题,如果只有到达目标才给一次正奖励,策略在初期几乎收不到任何有效信号,探索效率会非常低。
我在实践中通常用“分层约束”来设计奖励:
- 主奖励:反映核心控制目标,比如温度与目标的偏差,或是能耗
- 硬约束:一旦越界立即终止本回合,并给一个很大的负奖励
- 软约束:接近边界时给一个逐渐增大的惩罚,让策略学会提前避让
这套设计的逻辑是模拟人开车时的行为:目标线是“开到目的地”,车道线是“不能越线”,方向盘抖动是“动作不宜过猛”。策略学出来的行为会因此更接近工程可落地的驾驶风格。
3.3 算法选型与网络结构
RL 算法的选择,多数 PDE 控制场景下我首选 PPO。原因有三个:稳定、对超参数不那么敏感、支持连续动作。PPO 通过裁剪目标函数来限制每次更新的幅度,避免策略因为一次大的梯度更新而崩溃。这个特性在控制场景非常实用,因为控制系统的状态转移往往有较强的物理惯性,策略更新太快会产生剧烈的震荡。
如果任务的动作维度很高,或者需要更强的探索能力,可以尝试 SAC。SAC 的熵正则化让策略在训练过程中保持一定的随机性,探索能力更强,但对超参数也更敏感,调起来不如 PPO 省心。
策略网络本身不需要太大。PID 控制之所以在很多场景下仍然有效,是因为许多被控对象的动力学并不复杂,一个参数不多的小策略网络足以表达有效的控制规律。在 PINN 代理环境里,物理规律已经被编码进了网络前向传播中,策略网络只需要在这些输入之上学会时序决策。两层 256 宽度的 MLP 在很多场景下已经相当够用。把网络做得更大并不会自动带来更好的控制效果,反而会增加训练难度和过拟合风险。
4. 完整实操:用 1D 热传导问题打通全流程
4.1 训练 PINN 代理模型
我用一个足够具体又不失通用性的例子走一遍完整流程。假设有一根长度为 L 的细杆,左端有一个可控热源,右端暴露在恒温环境中。控制目标是:让杆上某个中间点的温度快速达到目标值并保持稳定。控制量是左端热源功率,观测是中间点温度的实时值。
第一步是用 PINN 训练这个系统的代理模型。这里使用 DeepXDE 这样的库会方便很多,它把 PINN 的常见组件都封装好了:
import deepxde as dde import numpy as np def pde(x, u): # x 的第一列是空间坐标,第二列是时间 du_t = dde.grad.jacobian(u, x, i=0, j=1) du_xx = dde.grad.hessian(u, x, i=0, j=0) return du_t - alpha * du_xx geom = dde.geometry.Interval(0, L) timedomain = dde.geometry.TimeDomain(0, T) geomtime = dde.geometry.GeometryXTime(geom, timedomain) bc = dde.icbc.DirichletBC( geomtime, lambda x: T_right, lambda _, on_boundary: on_boundary and x[0] == L ) ic = dde.icbc.IC( geomtime, lambda x: T_initial, lambda _, on_initial: on_initial ) data = dde.data.TimePDE( geomtime, pde, [bc, ic], num_domain=2000, num_boundary=200, num_initial=100 ) net = dde.nn.FNN([2] + [50] * 4 + [1], "tanh", "Glorot normal") model = dde.Model(data, net) model.compile("adam", lr=1e-3) losshistory, train_state = model.train(iterations=10000)训练完成后,这个网络就能在毫秒级回答“任意位置、任意时刻的温度是多少”。对于控制目的来说,我们真正需要的是“在给定当前温度和热源功率的情况下,下一个时刻的温度是多少”。这可以通过在短时间步长内反复调用网络来实现。
4.2 把 PINN 包成 RL 环境
代理模型训练好之后,第二件重要的事就是把 PINN 包装成标准 RL 环境。这里有一个设计决策值得展开讲:控制量如何融入 PINN 的输入。
最简单的做法是把 PINN 当作查询表。在 RL 训练前,先枚举不同的初始条件和动作序列,用 PINN 计算出后续状态,存成数据表。RL 训练时直接查表。但这个做法不灵活,连续动作空间下的枚举粒度很难控制。
更优雅的做法是把动作直接变成 PINN 的额外输入维度。以热传导为例,网络输入从 (x, t) 变成 (x, t, heat_source),输出仍然是温度。在 RL 每一步中,把当前控制量作为常数并入输入,预测下一时刻的温度场。这个方案保持了动作空间的连续性,也让代理模型天然覆盖了策略可能采取的任意控制序列。
包装成 gym 环境的简化逻辑:
class ThermalEnv(gym.Env): def __init__(self, surrogate_model): super().__init__() self.surrogate = surrogate_model self.action_space = gym.spaces.Box( low=-1.0, high=1.0, shape=(1,) ) self.observation_space = gym.spaces.Box( low=0.0, high=200.0, shape=(5,) ) self.state = None def step(self, action): # 调用 PINN 完成一次前向预测 new_state = self.surrogate.predict(self.state, action) # 奖励:距离目标越近越好,能耗越低越好 target_error = abs(new_state - target_temp) energy_cost = abs(action) reward = -target_error - 0.1 * energy_cost # 硬约束:越界即终止 done = bool(new_state > MAX_TEMP) if done: reward -= 50 # 越界重罚 else: reward += 1.0 # 每存活一步给一个基础正奖励 self.state = new_state return new_state, reward, done, {} def reset(self): self.state = self.sample_initial_state() return self.state这里有一个容易忽略的细节:在 step 函数里对 PINN 做单步预测时,时间步长要选择合理。热传导过程是连续时间系统,而 RL 是离散时间决策模型。步长太短,RL 需要更多步才能看到显著的状态变化,序列变长,训练难度增加。步长太长,PINN 的外推误差会累积。我在实操中通常选择让状态变化在每步中处于可观测、但不至于急剧跳变的量级。
4.3 训练策略与验证闭环
环境包装完成后,就可以用现成的 RL 库来训练。Stable-Baselines3 是最常用的选择,它对 gym 环境的兼容性很好,PPO 和 SAC 等主流算法都有高质量实现:
from stable_baselines3 import PPO model = PPO( "MlpPolicy", env, learning_rate=3e-4, n_steps=2048, batch_size=64, gamma=0.99, verbose=1 ) model.learn(total_timesteps=500000)训练之前有一个很有必要的步骤:随机策略跑几十个回合,观察奖励值的分布。很多时候奖励函数在理论上感觉合理,实际运行时量级完全失衡。比如主奖励在 0 到 1 之间,约束惩罚却高达 50,策略在训练初期会被惩罚项完全压制,无法学到任何有效行为。随机策略试跑能让你在耗费大量算力之前发现这类问题。
训练完成后,验证环节经常被忽略。RL 训练收敛并不意味着控制策略可靠,因为策略是在 PINN 代理环境里学出来的。必须把学到的策略重新放回更精确的仿真器或真实系统里跑一遍,观察实际控制效果。我在一个项目里发现,策略在代理环境里表现得很好,但放到高精度仿真器里,温度曲线出现明显振荡。分析后发现原因是 PINN 在某个状态区域精度不足,策略学到了“利用代理模型误差”的投机行为。这种情况下,需要用真实数据微调 PINN,或者给策略增加不确定性惩罚,让它避开代理模型不太可信的区域。
4.4 关键参数参考速查
| 参数 | 推荐范围 | 经验说明 |
|---|---|---|
| PINN 网络宽度 | 50~200 | 太窄表达力不足,太宽训练慢且易过拟合 |
| PINN 训练步数 | 5000~50000 | 以 PDE 残差进入平台期为准,不只看迭代数 |
| 内部点采样数 | 1000~5000 | 边界和初始时段附近要额外加密 |
| RL 算法 | PPO 优先 | 稳定,适合工程落地;动作复杂可换 SAC |
| RL 训练步数 | 5 万~50 万 | 代理环境快,可以多跑,但要在验证时留意精度 |
| 奖励归一化 | 0~1 或 -1~1 | 避免不同尺度奖惩互相压制 |
| 探索范围限制 | 代理模型可信域内 | 可结合真实数据校验偏差决定 |
5. 仿真、控制、优化,三个场景分别快在哪
5.1 仿真加速:参数族的一次训练、到处推理
用 PINN 做代理模型替代传统求解器,在参数研究、敏感性分析和设计空间探索中收益最明显。这类场景的共同点是:需要跑大量工况,但各工况之间的差异只是参数变化,而不是几何拓扑或边界条件的剧变。PINN 的参数化特性正好能覆盖这个需求。
我在一个设备散热设计项目里做过对比。需要评估翅片形状、材料导热系数、热源功率等参数的组合对温度分布的影响,总共约 300 组参数组合。传统方法按每组平均 40 秒计算,总共需要约 3.3 小时。PINN 方案先花约 20 分钟做训练,之后每组参数只需 5 毫秒,300 组总计约 1.5 秒,加训练时间也不过 21 分钟。工期从半天缩短到一顿饭的功夫。
这里有个前提条件要强调:PINN 要处理的参数空间不能太宽泛。如果参数范围跨越了几个数量级,网络需要拟合的变化范围太大,精度会急剧下降。合理的做法是缩小参数空间,或者为不同区域训练多个代理模型,这样做虽然增加了训练成本,但精度更有保障。
5.2 控制加速:近实时策略
控制加速的突破点在于,RL 训练从“离线斟酌”变成了“在线快速迭代”。在 PINN 代理环境里,RL 可以大规模试错而不影响真实设备。现实中不可能给真实系统几千次越界尝试,但在仿真环境中,这种代价可以忽略。
部署阶段的优势更明显。传统模型预测控制(MPC)每一步都要在线求解一个优化问题,计算时间从几十毫秒到秒级都有可能。而训练完成的 RL 策略,部署时就是一个网络前向推理,从观测输入到控制输出只需几毫秒。对于快速过程控制、高频调节这些场景,这个延迟差异是决定性的。
同时也要注意,RL 策略的可靠性取决于训练阶段是否充分覆盖了部署时可能遇到的状态。如果部署环境与训练环境有较大差异,策略输出可能偏离预期。解决方案是在部署前做充分的域随机化,把环境参数、扰动水平、传感器噪声都在训练中随机化,让策略学会应对不确定性。
5.3 优化加速:兼作梯度信号
PINN 的价值在优化场景中还有一个容易被忽略的维度:它天然提供梯度信息。传统数值求解器给出的是离散解,想通过参数求目标量的梯度,通常需要差分或者伴随方法。而 PINN 的输出对输入参数是处处可导的,可以直接用反向传播算出目标对参数的梯度。
这一点在基于梯度的优化算法中可以利用。比如想优化热源位置使最高温度最小,PINN 可以把热源位置作为输入,输出温度场,梯度即可直接通过自动微分获得。这样的优化过程不需要反复调用传统求解器,只需要在数次前向传播和反向传播中完成。
更进一步的做法是把优化变量本身也作为一个可学习的嵌入向量,在网络训练过程中同时优化。这个做法听起来很聪明,但实践中要注意优化变量和网络参数的尺度差异,通常需要给优化变量设置独立的学习率,否则很容易出现优化不稳定。
5.4 三者衔接起来看
这三个场景不是孤立存在的。实际项目中,仿真模型快,控制训练才能快;控制策略快,优化迭代才能快。PINN 与 RL 的结合本质上是把计算链条最重的那部分前置卸载了。
以数字孪生场景为例。数字孪生要求在线反映物理实体的状态,并支持远程控制和预测性维护。传统方案中,物理模型每次在线更新都要做一次完整 PDE 求解,开销很大;控制策略则依赖工程师手工设计或简单规则。PINN 代理模型让数字孪生的在线更新变成了快速推理,RL 策略则让控制决策从“规则库匹配”升级为“学习后的最优响应”。整体架构从“重模型、轻决策”变成了“轻模型、快决策”。
6. 实际项目中最容易踩的坑
6.1 PINN 不收敛的排查顺序
PINN 训练不收敛是入门阶段最常见的困扰,特征表现是损失函数下降缓慢,或者在一个较高的平台期反复震荡。我的排查顺序一般是这样的。
先检查 PDE 定义。导数的顺序和方向最容易出错,尤其是高维 PDE。建议先用非常简单的测试用例验证导数计算是否正确,比如用已知解析解先跑一遍,看看网络能不能正确学会它。
再检查采样点覆盖。初始条件和边界条件是否都充分采样了。很多时候 PINN 训练不收敛,不是因为优化算法出了问题,而是因为约束信息根本没有给足。边界和初始点至少要占总采样数的 10% 到 20%,否则网络会非常倾向于满足内部方程而忽略边界条件。
接着检查激活函数。使用 ReLU 类激活函数处理二阶 PDE 时会有天然缺陷,因为 ReLU 的二阶导数为零。建议优先用 tanh,虽然收敛稍慢,但导数特性好。
最后考虑损失权重。不同损失项的梯度可能互相冲突,需要对各项做自适应加权或先归一化。DeepXDE 提供了损失权重设置的接口,可以按要求调整。
6.2 RL 振荡与代理模型的失配
RL 训练不收敛的表现比 PINN 更隐蔽。我曾遇到一个训练了 20 万步始终无法稳定的场景。奖励曲线在几千步内上升,然后暴跌,反复震荡,完全找不到规律。
排查到最后,问题出在 PINN 代理模型上。策略在前几万步学会了在初始条件附近行动,控制效果看起来不错。但随着训练推进,策略开始探索更远的状态区域,而 PINN 在这些区域的预测精度明显下降。策略发现代理模型在这些区域给出的反馈有些“漏洞”可以利用,比如通过某些极端动作获得不真实的奖励信号,于是逐步偏离了真实物理规律,训练也随之崩溃。
这个问题的解法有两个方向。一是限制探索范围,在奖励函数中对进入未验证状态区域的行为施加额外惩罚。二是在线校正,每隔一定训练步数,调用传统数值求解器在策略最近访问的状态附近做一次校验,把偏差较大的点加入 PINN 的训练集做微调。第二种方法在实际项目中成本可控,对训练出的策略可信度提升却非常明显。
6.3 训练效率与两段式策略
在工程项目中,我强烈建议采用两段式训练策略:先完全训练好 PINN,再开始 RL 训练。这个策略看起来死板,但调试效率高得多。
两段式训练最大的好处是问题可定位。如果 RL 训练结果不好,你可以先质疑代理模型的精度,再质疑奖励函数设计,最后才质疑算法实现。而如果采用端到端的联合训练,PINN 和 RL 的梯度同时更新,任何一端出了问题,另一端都会被波及。当项目出问题时,你很难判断到底该调哪一端。
当然,两段式也有代价。PINN 代理模型在 RL 训练过程中不会自动改进,如果 RL 策略探索到了 PINN 训练覆盖不足的区域,就会遇到精度问题。解决办法是在两段式框架内引入“校验加微调”的循环,让 PINN 在 RL 训练过程中定期更新。这本质上还是一个循环,但每一轮的目标都很清晰:先确认代理模型精度,再确认策略表现,而不是两者糊在一起。
6.4 工程落地建议
最后几个工程落地的建议,是我在实际项目中反复品尝到甜头和苦头后总结出来的。
第一,PINN 和 RL 都不是可以完全黑盒使用的工具。PINN 需要理解 PDE 的结构,RL 需要理解控制问题的物理意义。团队配置上,最好有人既懂数值方法又懂深度学习,这样在遇到问题时能快速定位到具体环节。
第二,验证环节不能省。PINN 需要对照传统数值方法的结果做精度验证,RL 需要对照真实系统做闭环验证。验证的次数越多,后续出问题的概率越小。
第三,从简单问题做起。PINN 先从 1D 问题学起,RL 先从短回合的简单任务学起。一个经过充分验证的简化流程,比一个从未验证过的复杂流程在工程上更有价值。
关于这个流程的思考,我现在最大的体会是:大多数项目失败,不是因为 PINN 或 RL 本身不工作,而是因为在没有充分校验的状态下就把两者组合起来使用。每一步都做验证,每一步都确认模型的适用范围,这套流程才能真正跑得稳。