使用硬约束的物理信息神经网络(PINNs,Physics-Informed Neural Networks)求解一维泊松方程

背景

一维泊松方程定义为: u ′ ′ ( x ) = f ( x ) u''(x) = f(x) u′′(x)=f(x),边界条件为 x = 0 x=0 x=0 和 x = 1 x=1 x=1 处, u ( x ) = 0 u(x) = 0 u(x)=0,其中, f ( x ) = − π 2 sin ⁡ ( π x ) f(x) = -\pi^2 \sin(\pi x) f(x)=−π2sin(πx),该方程的解析解为 u ( x ) = sin ⁡ ( π x ) u(x) = \sin(\pi x) u(x)=sin(πx)。

硬约束原理

硬约束在 PINNs 中用来确保边界条件自动满足。构建硬约束,即解: u ( x ) = x ( 1 − x ) N ( x ) u(x) = x(1-x)N(x) u(x)=x(1−x)N(x)。

  • 边界条件自动满足 :函数形式 x ( 1 − x ) x(1-x) x(1−x) 保证在边界 x = 0 x=0 x=0 和 x = 1 x=1 x=1 处, u ( x ) = 0 u(x) = 0 u(x)=0,这就是硬约束。
  • 神经网络输出 : N ( x ) N(x) N(x) 是神经网络的输出,没有边界限制,任意预测。

代码

python 复制代码
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams[
'axes.unicode_minus'] = False
# 定义一个神经网络类,继承自tf.keras.Model
class PINN(tf.keras.Model):    
def __init__(self, num_hidden_layers=3, num_neurons_per_layer=20):        
# 调用父类的初始化函数        
super(PINN, self).__init__()        
# 创建一个隐藏层的列表,每个隐藏层是一个全连接层,使用tanh作为激活函数
        self.hidden_layers = [tf.keras.layers.Dense(num_neurons_per_layer, activation='tanh')                              
for _ in range(num_hidden_layers)]        
# 创建输出层,输出为一维,没有激活函数(线性激活)
        self.output_layer = tf.keras.layers.Dense(1, activation=None)
    # 定义前向传播的方法    
def call(self, x):        
# 初始输入值
        z = x        
# 通过每一个隐藏层        
for layer in self.hidden_layers:
            z = layer(z)        
# 输出层得到最终输出        
return self.output_layer(z)
# 自定义训练步骤
@tf.function
def train_step(model, optimizer, x):    
# 使用tf.GradientTape()记录梯度信息    
with tf.GradientTape() as tape:        
# 预测 u(x) = x(1-x)N(x),其中N(x)是神经网络的输出
        u_pred = x * (1 - x) * model(x)                
# 计算 u'(x) 使用自动微分
        u_x = tf.gradients(u_pred, x)[0]        
# 计算 u''(x) 使用自动微分
        u_xx = tf.gradients(u_x, x)[0]                
# 定义泊松方程中的右侧项 f(x)
        f = -np.pi**2 * tf.sin(np.pi * x)        
# 计算损失函数,衡量 u''(x) 和 f(x) 的差距
        loss = tf.reduce_mean(tf.square(u_xx - f))        
# 计算损失函数关于模型参数的梯度
    gradients = tape.gradient(loss, model.trainable_variables)    
# 使用优化器更新模型参数
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))    
return loss
# 准备训练数据,生成从0到1的100个点
x_train = np.linspace(0, 1, 100)[:, None]
x_train = tf.convert_to_tensor(x_train, dtype=tf.float32)
# 初始化PINN模型和Adam优化器
model = PINN()
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
# 训练模型,迭代1000次
epochs = 1000
for epoch in range(epochs):    
# 每次训练计算损失值
    loss_value = train_step(model, optimizer, x_train)    
# 每隔100次输出一次损失值    
if epoch % 100 == 0:        
print(f"Epoch {epoch}, Loss: {loss_value.numpy()}")
# 生成测试数据用于结果可视化
x_test = np.linspace(0, 1, 100)[:, None]
x_test = tf.convert_to_tensor(x_test, dtype=tf.float32)
# 使用训练好的模型进行预测
u_pred = x_test * (1 - x_test) * model(x_test)
# 绘制预测结果和精确解进行对比
plt.plot(x_test, u_pred, label='PINN Prediction')
plt.plot(x_test, np.sin(np.pi * x_test), label='Exact Solution', linestyle='dashed')
plt.legend()
plt.xlabel('x')
plt.ylabel('u(x)')
plt.title('PINN硬约束解一维泊松方程')
plt.show()

代码解析

  1. PINN 类定义

    • PINN 类是一个继承自 tf.keras.Model 的神经网络,包含多个全连接层。
    • 使用 tanh 激活函数处理隐藏层,输出层是线性激活。
  2. 前向传播

    • call 方法定义了前向传播过程:输入通过各层处理后,输出为 N ( x ) N(x) N(x)。
  3. 自定义训练步骤

    • 使用 tf.GradientTape() 记录梯度信息,计算神经网络输出 N ( x ) N(x) N(x) 的二阶导数 u ′ ′ ( x ) u''(x) u′′(x)。
    • 损失函数衡量 u ′ ′ ( x ) u''(x) u′′(x) 和右侧项 f ( x ) f(x) f(x) 的差距。
  4. 训练过程

    • 使用 Adam 优化器迭代更新模型参数,逐步减少损失。
    • 每 100 个 epoch 输出损失值以监控训练过程。
  5. 预测与可视化

    • 在训练完成后,使用模型对测试数据进行预测。
    • 绘制模型预测结果与解析解进行对比。

物理信息的引入

  • 使用自动微分计算模型预测值的导数,从而在损失函数中比较预测和物理方程的右侧项。
  • 硬约束通过预先定义的函数形式确保边界条件被满足。

优势

  • 边界条件处理:硬约束方法无需在损失函数中显式加入边界条件损失。
  • 物理一致性:神经网络能够学习到方程的物理特性。
相关推荐
hujinyuan201605 分钟前
2025年12月中国电子学会青少年机器人技术等级考试试卷(二级) 真题+答案
人工智能·算法·机器人
码农小白AI11 分钟前
采购合同与来料证书对标校验,IACheck联动AI报告审核通审Agent版自动识别指标不符单据
人工智能
大江东去浪淘尽千古风流人物23 分钟前
【PromptStereo】零样本立体匹配新范式:用结构与运动Prompt驱动迭代优化(CVPR 2026)
深度学习·3d·slam·视觉定位·dust3r·3d重建·mast3r
元岳数字人小元1 小时前
AI 数字人开发公司浅谈 虚拟数字人打造景区新服务
人工智能·人机交互·交互
哦哦~9211 小时前
AI赋能生物医学:从临床数据到药物分子性质预测实战培
人工智能·生物医学·药物分子
GIS数据转换器1 小时前
城市排水生命线安全运行监测平台深度解析
java·运维·人工智能·python·安全·数据挖掘·无人机
虫无涯1 小时前
本地离线大模型实战:Ollama + Llama 3.1 8B 全流程部署(适配VSCode Continue代码助手)
人工智能
Rocky Ding*1 小时前
Latent Consistency Models:一篇读懂扩散模型的少步生成核心基础知识
人工智能·深度学习·机器学习·ai作画·stable diffusion·aigc·ai-native
大山佬1 小时前
AI 边缘部署:MCU 上的轻量级目标检测,从 YOLO 到 TFLite Micro 的全链路优化
人工智能
数睿数据无代码开发1 小时前
深度解析smardaten数据大屏:六大核心功能重塑可视化开发
人工智能·信息可视化