深度学习基础:神经网络结构、损失函数、优化器与自动微分
物理信息神经网络(PINN)的核心思想是将物理方程(如Navier-Stokes方程、热传导方程)的残差作为损失项嵌入到神经网络训练中。因此,理解神经网络的基本构建模块——网络结构、损失函数、优化器以及自动微分——是搭建PINN模型的前提。本章将围绕这四个核心要素展开,重点说明它们在流体力学与热传导建模中的特殊考量与实现方式。
上图展示了PINN中各组件的协作关系:输入坐标通过全连接网络前向传播得到预测场变量,自动微分从输出中计算各阶导数以构造PDE残差,数据损失与物理损失加权求和后,由优化器迭代更新网络参数。下面逐一深入剖析每个组件。
3.1 神经网络结构:全连接层与激活函数
在PINN中,最常用的网络结构是多层全连接前馈神经网络(MLP)。其数学表达为:
z^(0) = x
z^(l) = W^(l) · σ(z^(l-1)) + b^(l), l = 1, 2, ..., L
u(x) = z^(L)
其中,W^(l) 和 b^(l) 分别是第 l 层的权重矩阵和偏置向量,σ(·) 是逐元素激活函数。对于流体力学问题,输入通常是时空坐标 (x, y, z, t),输出是速度分量 (u, v, w)、压力 p 和温度 T。
3.1.1 激活函数的选择策略
激活函数直接影响PINN的训练难度和精度。由于PDE残差需要计算高阶导数,激活函数的平滑性至关重要。常用选项对比如下:
| 激活函数 | 表达式 | 优点 | PINN中的问题 |
|---|---|---|---|
| tanh | (e^x - e^-x)/(e^x + e^-x) | 光滑、有界、二阶可导 | 深层网络易梯度消失 |
| sigmoid | 1/(1+e^-x) | 输出范围(0,1) | 梯度饱和严重,不推荐 |
| ReLU | max(0, x) | 计算快、缓解梯度消失 | 二阶导为0,无法用于PDE |
| Swish | x · sigmoid(x) | 光滑、非单调 | 计算量略大,效果较好 |
| GELU | x · Φ(x) | 光滑、近似ReLU | 适合复杂PDE |
对于热传导方程(抛物型PDE)和Navier-Stokes方程,tanh 和 Swish 是首选。ReLU及其变体由于二阶导为零,无法构造扩散项 ∂²T/∂x²,应避免使用。
p = p_scale * tanh(p_raw)),以匹配压力量级并加速收敛。
3.1.2 网络深度与宽度设计
PINN的近似能力取决于网络的容量。对于二维稳态热传导问题,4-6层隐藏层、每层50-100个神经元通常足够;而对于三维非稳态湍流,可能需要8-10层、每层100-200个神经元。但过深的网络会导致优化困难,建议配合残差连接(ResNet风格)或归一化技术。
3.2 损失函数:物理约束与数据拟合的加权融合
PINN的损失函数由三部分构成:
L_total = w_pde · L_pde + w_data · L_data + w_bc · L_bc
其中,L_pde 是PDE残差的均方误差,L_data 是观测数据拟合误差,L_bc 是边界/初始条件误差。权重 w 的选取对训练稳定性影响显著。
3.2.1 PDE残差的计算
以一维热传导方程 ∂T/∂t = α ∂²T/∂x² 为例,残差定义为:
r(x, t) = ∂T̂/∂t - α ∂²T̂/∂x²
其中 T̂ 是网络输出。训练时在计算域内随机采样 N_pde 个配点(collocation points),计算:
L_pde = (1/N_pde) Σ |r(x_i, t_i)|²
3.2.2 权重自适应策略
固定权重往往导致训练不平衡——PDE残差和边界损失量级差异大时,梯度被大项主导。常用解决方案包括:
- 归一化损失:将各项损失除以初始值,使其量级一致。
- 动态权重(NTK理论):根据梯度统计信息自动调整权重。
- 学习率退火:先训练数据损失,再逐步引入PDE损失。
3.3 优化器:Adam与L-BFGS的协同使用
PINN训练通常采用两阶段策略:先用Adam进行全局搜索,再用L-BFGS进行局部精调。这是因为Adam对超参数不敏感、能快速逃离不良区域,但收敛精度有限;L-BFGS利用二阶信息,收敛快且精度高,但对初始点敏感。
3.3.1 Adam优化器
Adam(Adaptive Moment Estimation)结合动量与RMSProp,更新规则为:
m_t = β1 · m_{t-1} + (1-β1) · g_t
v_t = β2 · v_{t-1} + (1-β2) · g_t²
θ_{t+1} = θ_t - η · m̂_t / (√v̂_t + ε)
其中 g_t 是梯度,β1=0.9,β2=0.999,ε=1e-8。在PINN中,建议初始学习率 η=1e-3,并配合余弦退火或ReduceLROnPlateau策略。
3.3.2 L-BFGS优化器
L-BFGS(Limited-memory Broyden–Fletcher–Goldfarb–Shanno)是一种拟牛顿法,通过近似Hessian矩阵加速收敛。在PyTorch中,需使用 torch.optim.LBFGS,其特殊之处在于需要传入一个闭包函数来计算损失和梯度:
optimizer = torch.optim.LBFGS(model.parameters(), lr=1.0, max_iter=500)
def closure():
optimizer.zero_grad()
loss = compute_total_loss()
loss.backward()
return loss
optimizer.step(closure)
3.4 自动微分:PINN的基石
自动微分(Automatic Differentiation, AD)是计算PDE残差中导数项的关键技术。与数值微分(有限差分)和符号微分不同,AD通过链式法则在计算图上精确计算导数,精度达到机器精度。
3.4.1 前向模式与反向模式
AD有两种模式:前向模式(forward mode)和反向模式(reverse mode)。PINN中,由于输出维度(速度、压力、温度)远小于输入维度(坐标+时间),通常使用反向模式(即反向传播),因为其计算复杂度与输出维度成正比,而非输入维度。
3.4.2 TensorFlow与PyTorch实现对比
| 框架 | 高阶导数实现 | 示例代码 |
|---|---|---|
| TensorFlow | tf.GradientTape 嵌套 | |
| PyTorch | torch.autograd.grad 多次调用 | |
在PyTorch中,create_graph=True 是必须的,否则无法计算二阶导数。TensorFlow中则需使用 persistent=True 以允许多次调用 gradient 方法。
3.4.3 计算图的内存管理
高阶导数会显著增加内存消耗。对于三维非稳态问题,二阶导数计算可能需要数GB显存。建议:
- 使用
torch.no_grad()包裹不需要梯度的计算(如验证集评估)。 - 分批计算PDE残差,避免一次性计算所有配点的二阶导数。
- 在TensorFlow中,使用
tf.function编译计算图以提高效率。
3.5 案例拆解:二维稳态热传导PINN实现
考虑一个二维稳态热传导问题:在 [0,1]×[0,1] 方形域内,温度场满足拉普拉斯方程 ∂²T/∂x² + ∂²T/∂y² = 0,边界条件为:左侧 T=100,右侧 T=0,上下边界绝热(∂T/∂n=0)。
3.5.1 网络与损失设计
import torch
import torch.nn as nn
class PINN(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Linear(2, 50), nn.Tanh(),
nn.Linear(50, 50), nn.Tanh(),
nn.Linear(50, 50), nn.Tanh(),
nn.Linear(50, 1)
)
def forward(self, x, y):
return self.net(torch.cat([x, y], dim=1))
# 损失计算
def pde_loss(model, x, y):
x.requires_grad_(True)
y.requires_grad_(True)
T = model(x, y)
dT_dx = torch.autograd.grad(T, x, grad_outputs=torch.ones_like(T), create_graph=True)[0]
dT_dy = torch.autograd.grad(T, y, grad_outputs=torch.ones_like(T), create_graph=True)[0]
d2T_dx2 = torch.autograd.grad(dT_dx, x, grad_outputs=torch.ones_like(dT_dx), create_graph=True)[0]
d2T_dy2 = torch.autograd.grad(dT_dy, y, grad_outputs=torch.ones_like(dT_dy), create_graph=True)[0]
return torch.mean((d2T_dx2 + d2T_dy2)**2)
3.5.2 训练过程与结果
在域内随机采样10000个配点,边界上各采样500个点。训练过程如下:
- Adam优化器,学习率
1e-3,训练3000步,损失从1e2降至1e-3。 - 切换L-BFGS,最大迭代500次,损失降至
1e-6。 - 最终预测温度场与解析解(分离变量法)的最大误差
0.5%。
tanh 激活函数比 Swish 收敛更快,但最终精度略低。
3.6 常见误区与总结
在PINN实践中,以下问题值得特别关注:
- 激活函数选择不当:使用ReLU导致二阶导为零,PDE残差恒为零,网络无法学习。
- 权重初始化不当:建议使用Xavier或He初始化,避免梯度爆炸或消失。
- 配点采样不均匀:在边界附近应加密采样,否则边界层处的解精度差。
- 忽略损失权重调整:固定权重往往导致训练失败,需根据损失量级动态调整。
- 过早切换L-BFGS:若Adam尚未收敛到合理区域,L-BFGS可能陷入局部极小。