使用软约束的物理信息神经网络解一维泊松方程

news/2024/12/13 21:25:09/

物理信息神经网络是一种将物理方程和神经网络结合的方法,通过将方程的物理约束转化为损失函数的一部分来指导神经网络的训练。下面是软约束的物理信息神经网络求解一维泊松方程。

数学原理

  1. 目标方程

    • 一维泊松方程,形式为 u ′ ′ ( x ) = f ( x ) u''(x) = f(x) u′′(x)=f(x),其中 f ( x ) = − π 2 sin ⁡ ( π x ) f(x) = -\pi^2 \sin(\pi x) f(x)=π2sin(πx)
  2. 边界条件

    • 在边界 x = 0 x = 0 x=0 x = 1 x = 1 x=1 上,给定 u ( 0 ) = 0 u(0) = 0 u(0)=0 u ( 1 ) = 0 u(1) = 0 u(1)=0
  3. 神经网络模型

    • 使用一个多层神经网络来近似解 u ( x ) u(x) u(x)
    • 网络的输入是 x x x,输出是 u ( x ) u(x) u(x)
  4. 损失函数

    • 内部点损失:通过自动微分计算 u ′ ′ ( x ) u''(x) u′′(x),并与给定的 f ( x ) f(x) f(x) 进行比较:
      l o s s i n t e r i o r = 1 N ∑ i = 1 N ( u ′ ′ ( x i ) − f ( x i ) ) 2 loss_{interior} = \frac{1}{N} \sum_{i=1}^{N} (u''(x_i) - f(x_i))^2 lossinterior=N1i=1N(u′′(xi)f(xi))2

    • 边界条件损失:直接计算在边界点的偏差:
      l o s s b c = u ( 0 ) 2 + u ( 1 ) 2 loss_{bc} = u(0)^2 + u(1)^2 lossbc=u(0)2+u(1)2

  5. 总损失

    • 总损失是内部点损失和边界条件损失的加权和:
      l o s s = l o s s i n t e r i o r + l o s s b c loss = loss_{interior} + loss_{bc} loss=lossinterior+lossbc

    • 这里,内部点损失和边界条件损失共同构成了优化目标,其中边界条件损失可以被视为软约束,因为它在损失函数中作为一项,而非严格的约束条件。

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__()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):    
with tf.GradientTape() as tape:        
# 预测 u(x) = N(x),直接使用神经网络的输出u_pred = 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_interior = tf.reduce_mean(tf.square(u_xx - f))                
# 边界条件损失:在 x=0 和 x=1 处,u(x) 应为 0u_0 = model(tf.constant([[0.0]], dtype=tf.float32))u_1 = model(tf.constant([[1.0]], dtype=tf.float32))loss_bc = tf.square(u_0) + tf.square(u_1)                
# 总损失loss = loss_interior + loss_bcgradients = 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)    
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 = 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.savefig('图片/pinn_poisson_solution_soft.png', dpi=300, bbox_inches='tight')

在这里插入图片描述

代码解释

  1. PINN模型的构建

    • PINN类定义了一个简单的前馈神经网络,具有3个隐藏层,每层20个神经元,使用tanh激活函数。输出层不使用激活函数,以保持输出的线性。
  2. 自定义训练步骤

    • train_step函数中,通过自动微分计算网络输出的二阶导数 u ′ ′ ( x ) u''(x) u′′(x),并与泊松方程的右端项 f ( x ) f(x) f(x) 进行比较。
    • 使用tf.GradientTape计算损失相对于网络参数的梯度,并使用Adam优化器更新参数。
  3. 软约束的实现

    • 边界条件损失 l o s s b c loss_{bc} lossbc 被添加到总损失中,作为优化的一个软约束。这意味着网络在训练过程中不仅需要拟合内部点的方程,还要尽量满足边界条件。
  4. 训练过程

    • 使用100个从0到1均匀分布的点作为训练数据。
    • 通过1000次迭代优化网络参数,最小化总损失。
  5. 结果可视化

    • 使用训练后的模型对从0到1的测试点进行预测,可以与真实解进行比较以评估模型性能。

http://www.ppmy.cn/news/1554853.html

相关文章

抖音后端实习一面总结

置之死地而后生 抖音后端开发实习一面 自我介绍 你参加了PAT比赛?介绍一下? 平时有刷题吗?有的,那来做一下算法题目吧,单词拆分(动态规划1h过去了...) TCP有哪些状态?每种状态代表…

H5接入Steam 获取用户数据案例 使用 OpenID 登录绑定公司APP账户 steam公开用户信息获取 steam webapi文档使用

官方文档地址 1.注册 Steam API Key: 你需要一个 Steam Web API Key,可以在 Steam API Key 页面 获取。https://steamcommunity.com/dev/apikey 这里开发做demo用自己steam账户的就好,后续上线要用公司的账户 2.使用 OpenID 登录&#xff…

OpenCV中的水印添加

一、原理 将两个不同的logo图像(logo 和 logo2)插入到背景图像(img)的指定位置。这个过程涉及到图像处理的几个关键步骤,包括灰度化、二值化、区域选择(ROI)、位运算和图像融合。 二、实验代码 …

水下机器人:科技助力水下救援的新力量|鼎跃安全

在自然灾害、海洋事故或复杂水域救援中,传统人工救援常面临环境恶劣、作业危险等挑战。水下机器人作为现代科技的结晶,凭借其卓越的水下作业能力和智能技术,成为救援任务中的“隐形英雄”。这种高效、智能的救援装备正逐步改变着水下救援的模…

MATLAB小电流接地系统单向故障仿真分析

基于Simulink的小电流接地系统单向故障仿真分析,包涵中性点不接地系统仿真和中性点经消弧线圈接地系统仿真模型。 电力系统常用的接地方式有两种,即中性点有效接地系统和非有效接地系统,也称为大电流接地系统和小电流接地系统。 对于小电流接…

MyBatis 基础学习与优化技巧解析

1. 引言 在当今的软件开发领域,数据库操作是至关重要的一环。MyBatis 作为一款优秀的持久层框架,简化了 JDBC 代码,为开发者提供了高效、灵活的数据访问方式。在之前的学习中,我们已经对 MyBatis 有了一定的了解,今天将…

基于 SSM 的校园一卡通密钥管理系统的用户交互与业务功能集成

摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装校园一卡通密钥管理系统软件来发挥其高效地信息处理的作用&a…

Docker 学习总结(84)—— Docker 常用运维命令

版本与信息查询 docker --version:查看安装的Docker版本。 docker info:获取Docker系统的详细配置信息。 镜像管理 docker images:列出本地所有镜像。 docker search IMAGE_NAME:搜索Docker Hub上的镜像。 docker pull IMAGE_NAME[:TAG]:从仓库下载指定镜像。 docker rmi …