物理信息网络(Physics-Informed Neural Networks, PINN)是一种将物理定律(如偏微分方程、守恒定律等)嵌入神经网络训练过程的深度学习方法。其核心思想是通过神经网络同时拟合观测数据并满足物理约束,从而解决传统数值方法难以处理的高维、噪声数据或复杂边界条件问题。
来源:PINN起源于对传统数值方法局限性的改进需求(如网格生成复杂、反问题求解困难),结合了深度学习中的自动微分技术与物理建模思想,2017年由Raissi等人首次提出并应用于流体力学问题。
数学表达示例(以热传导方程为例):
假设控制方程为:
∂ T ∂ t = k ( ∂ 2 T ∂ x 2 + ∂ 2 T ∂ y 2 ) \frac{\partial T}{\partial t} = k \left( \frac{\partial^2 T}{\partial x^2} + \frac{\partial^2 T}{\partial y^2} \right) ∂t∂T=k(∂x2∂2T+∂y2∂2T)
损失函数为:
L = MSE data + λ ⋅ MSE PDE \mathcal{L} = \text{MSE}_\text{data} + \lambda \cdot \text{MSE}_\text{PDE} L=MSEdata+λ⋅MSEPDE
其中, MSE PDE \text{MSE}_\text{PDE} MSEPDE为方程残差的均方误差, λ \lambda λ为权重系数。
以下三个案例详细说明PINN的实现过程:
物理场景:
模拟金属棒的温度随时间扩散的过程。初始时棒的一端高温,另一端低温,热量逐渐扩散直至平衡。
控制方程:
∂ u ∂ t = α ∂ 2 u ∂ x 2 \frac{\partial u}{\partial t} = \alpha \frac{\partial^2 u}{\partial x^2} ∂t∂u=α∂x2∂2u
其中, u ( x , t ) u(x,t) u(x,t) 为温度, α \alpha α 为热扩散系数。
解决思路:
PyTorch实现:
import torch
import torch.nn as nn
class HeatPINN(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Linear(2, 64), nn.Tanh(),
nn.Linear(64, 64), nn.Tanh(),
nn.Linear(64, 1)
)
def forward(self, x, t):
inputs = torch.cat([x, t], dim=1)
return self.net(inputs)
def heat_residual(u_pred, x, t, alpha):
u_t = torch.autograd.grad(u_pred, t, grad_outputs=torch.ones_like(u_pred), create_graph=True)[0]
u_x = torch.autograd.grad(u_pred, x, grad_outputs=torch.ones_like(u_pred), create_graph=True, retain_graph=True)[0]
u_xx = torch.autograd.grad(u_x, x, grad_outputs=torch.ones_like(u_x), create_graph=True)[0]
residual = u_t - alpha * u_xx
return torch.mean(residual**2)
# 模拟数据(初始条件:u(x,0)=sin(πx),边界条件:u(0,t)=u(1,t)=0)
x = torch.linspace(0, 1, 100).unsqueeze(1)
t = torch.linspace(0, 1, 100).unsqueeze(1)
X, T = torch.meshgrid(x.squeeze(), t.squeeze())
u_initial = torch.sin(torch.pi * X) # 初始时刻温度分布
model = HeatPINN()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
alpha = 0.01
for epoch in range(1000):
# 内部点残差损失
x_in = torch.rand(500, 1, requires_grad=True)
t_in = torch.rand(500, 1, requires_grad=True)
u_pred = model(x_in, t_in)
loss_pde = heat_residual(u_pred, x_in, t_in, alpha)
# 初始/边界条件损失
u_initial_pred = model(x, torch.zeros_like(x))
loss_ic = torch.mean((u_initial_pred - u_initial)**2)
total_loss = loss_pde + loss_ic
optimizer.zero_grad()
total_loss.backward()
optimizer.step()
物理场景:
计算二维空间中电荷分布产生的静电势场。已知电荷密度分布( f(x,y) ),求解势场( u(x,y) )。
控制方程:
∇ 2 u = f ( x , y ) \nabla^2 u = f(x, y) ∇2u=f(x,y)
解决思路:
PyTorch实现:
class PoissonPINN(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Linear(2, 32), nn.ReLU(),
nn.Linear(32, 32), nn.ReLU(),
nn.Linear(32, 1)
)
def forward(self, x, y):
inputs = torch.cat([x, y], dim=1)
return self.net(inputs)
def poisson_residual(u_pred, x, y, f):
u_x = torch.autograd.grad(u_pred, x, grad_outputs=torch.ones_like(u_pred), create_graph=True)[0]
u_y = torch.autograd.grad(u_pred, y, grad_outputs=torch.ones_like(u_pred), create_graph=True)[0]
u_xx = torch.autograd.grad(u_x, x, grad_outputs=torch.ones_like(u_x), create_graph=True)[0]
u_yy = torch.autograd.grad(u_y, y, grad_outputs=torch.ones_like(u_y), create_graph=True)[0]
residual = u_xx + u_yy - f(x, y)
return torch.mean(residual**2)
# 电荷密度函数(示例:f(x,y) = 2π² sin(πx) sin(πy))
def f_source(x, y):
return 2 * (torch.pi**2) * torch.sin(torch.pi * x) * torch.sin(torch.pi * y)
model = PoissonPINN()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
for epoch in range(2000):
x = torch.rand(500, 1, requires_grad=True)
y = torch.rand(500, 1, requires_grad=True)
u_pred = model(x, y)
loss_pde = poisson_residual(u_pred, x, y, f_source)
# 边界条件(假设边界u=0)
x_bc = torch.cat([torch.zeros(100,1), torch.ones(100,1), torch.rand(100,1), torch.rand(100,1)], dim=0)
y_bc = torch.cat([torch.rand(100,1), torch.rand(100,1), torch.zeros(100,1), torch.ones(100,1)], dim=0)
u_bc_pred = model(x_bc, y_bc)
loss_bc = torch.mean(u_bc_pred**2) # 假设边界u=0
total_loss = loss_pde + loss_bc
optimizer.zero_grad()
total_loss.backward()
optimizer.step()
物理场景:
根据大气参数(如温度、湿度)预测降水分布,结合Koren-Feingold云雨模型。
控制方程:
∂ q ∂ t = − v ⋅ ∇ q + S ( q ) \frac{\partial q}{\partial t} = -v \cdot \nabla q + S(q) ∂t∂q=−v⋅∇q+S(q) 其中, q q q 为云水含量, S ( q ) S(q) S(q) 为降水源项。
解决思路:
PyTorch实现:
class PrecipitationPINN(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Linear(3, 64), nn.Tanh(), # 输入(x, y, t)
nn.Linear(64, 64), nn.Tanh(),
nn.Linear(64, 2) # 输出(云水含量q, 降水率p)
)
def forward(self, x, y, t):
inputs = torch.cat([x, y, t], dim=1)
return self.net(inputs)
def cloud_loss(model, x, y, t, v_x, v_y):
q_pred, p_pred = model(x, y, t)
# 计算云水守恒方程残差
q_t = torch.autograd.grad(q_pred, t, grad_outputs=torch.ones_like(q_pred), create_graph=True)[0]
q_x = torch.autograd.grad(q_pred, x, grad_outputs=torch.ones_like(q_pred), create_graph=True)[0]
q_y = torch.autograd.grad(q_pred, y, grad_outputs=torch.ones_like(q_pred), create_graph=True)[0]
residual = q_t + v_x * q_x + v_y * q_y + p_pred # 假设S(q)=降水率p
return torch.mean(residual**2)
# 训练过程(示例)
model = PrecipitationPINN()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
v_x, v_y = 0.1, 0.2 # 风速分量
for epoch in range(3000):
x = torch.rand(500, 1, requires_grad=True)
y = torch.rand(500, 1, requires_grad=True)
t = torch.rand(500, 1, requires_grad=True)
loss_physics = cloud_loss(model, x, y, t, v_x, v_y)
# 假设有部分观测数据
q_obs = torch.rand(100, 1) # 模拟云水含量观测值
t_obs = torch.rand(100, 1)
q_pred, _ = model(x_obs, y_obs, t_obs)
loss_data = torch.mean((q_pred - q_obs)**2)
total_loss = loss_physics + loss_data
optimizer.zero_grad()
total_loss.backward()
optimizer.step()
PINN的优势在于无需网格离散化、可处理高维问题,但训练稳定性(如梯度爆炸)仍需改进。未来方向包括:
通过以上案例和代码,初学者可逐步掌握PINN的核心逻辑与实现方法。