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

news2025/1/15 15:28:29

背景

一维泊松方程定义为: 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(1x)N(x)

  • 边界条件自动满足:函数形式 x ( 1 − x ) x(1-x) x(1x) 保证在边界 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) 是神经网络的输出,没有边界限制,任意预测。

代码

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. 预测与可视化

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

物理信息的引入

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

优势

  • 边界条件处理:硬约束方法无需在损失函数中显式加入边界条件损失。
  • 物理一致性:神经网络能够学习到方程的物理特性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2258807.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于单片机的多功能函数信号发生器的设计(论文+源码)

系统总体设计思路 在本次课题为信号发生器,其系统整体架构如图2.1所示,在硬件结构上,其主要包括核心控制器AT89C51单片机,液晶显示器LCD1602,数模转换器DAC0832,运算放大器L358以及按键、LED指示灯等器件,…

Docker 安装 sentinel

Docker 安装系列 1、拉取 [rootTseng ~]# docker pull bladex/sentinel-dashboard Using default tag: latest latest: Pulling from bladex/sentinel-dashboard 4abcf2066143: Pull complete 1ec1e81da383: Pull complete 56bccb36a894: Pull complete 7cc80011dc6f: Pull…

解读数据资产管理实践白皮书(5.0版)深入学习掌握数据资产管理知识体系。

本文介绍了数据资产管理的重要性及其概述,详细阐述了数据资产管理的活动职能包括数据模型管理、数据标准管理、数据质量管理等,并强调了数据安全管理的重要性。文章还讨论了数据资产管理的保障措施和实践步骤,以及发展趋势和总结展望。 重点内…

【大前端vue:组件】vue鼠标滑动:平滑滚动效果 向左、向右

【大前端vue&#xff1a;组件】vue鼠标滑动&#xff1a;平滑滚动效果 向左、向右 <template><div class"tab-container"><div class"tab-wrapper"><h2 class"main-title">鼠标滑动&#xff1a;平滑滚动效果 向左、向右…

python脚本:向kafka数据库中插入测试数据

# coding:utf-8 import datetime import json import random import timefrom kafka import KafkaProducer生产者demo向branch-event主题中循环写入10条json数据注意事项&#xff1a;要写入json数据需加上value_serializer参数&#xff0c;如下代码producer KafkaProducer(val…

selenium自动爬虫工具

一、介绍selenium爬虫工具 selenium 是一个自动化测试工具&#xff0c;可以用来进行 web 自动化测试、爬虫 selenium 本质是通过驱动浏览器&#xff0c;完全模拟浏览器的操作&#xff0c;比如跳转、输入、点击、下拉等&#xff0c;来拿到网页渲染之后的结果&#xff0c;可支持…

【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;编写一个程序实现环形队列的基本运算。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 初始化队列、销毁队列、判断队列是否为空、进队列…

笔记本电脑升级硬盘存储、Windows10系统安装及后续步骤(以联想ThinkPad X1 Carbon Gen10为例)

文章目录 1.前言2.材料准备3.Win10系统安装盘制作3.1 系统下载3.2 系统启动U盘刻录 4.拆机更换硬盘5.开机启动项修改6.系统安装&#xff08;以Win10为例&#xff09;7.系统安装后可能需要的步骤7.1 缺少WIFI等网络驱动7.2 系统激活7.3 办公软件安装 8.旧硬盘变废为宝参考文献 1…

关于idea-Java-servlet-Tomcat-Web开发中出现404NOT FOUND问题的解决

在做web项目时&#xff0c;第一次使用servlet开发链接前端和后端的操作&#xff0c;果不其然&#xff0c;遇到了诸多问题&#xff0c;而遇到最多的就是运行项目打开页面时出现404NOT FOUND的情况。因为这个问题我也是鼓捣了好久&#xff0c;上网查了许多资料才最终解决&#xf…

国产物联网平台(IotSharp+IoTGateway+Influxdb)快速上手

环境说明&#xff1a; Visual Studio 2022 CommunityIotSharp代码&#xff1a;https://github.com/IoTSharp/IoTSharp.gitIoTGateway版本&#xff1a;v2.1.1Node版本&#xff1a;v20.18.1Influxdb版本&#xff1a;v2.7.11 安装Node Node.js官网 官网下载并安装&#xff0c;…

网页502 Bad Gateway nginx1.20.1报错与解决方法

目录 网页报错的原理 查到的502 Bad Gateway报错的原因 出现的问题和尝试解决 问题 解决 网页报错的原理 网页显示502 Bad Gateway 报错原理是用户访问服务器时&#xff0c;nginx代理服务器接收用户信息&#xff0c;但无法反馈给服务器&#xff0c;而出现的报错。 查到…

2025系统架构师(一考就过):选择题基础知识二

考点14&#xff1a;知识产权和标准化 真题1&#xff1a;甲软件公司受乙企业委托安排公司软件设计师开发了信息系统管理软件&#xff0c;由于在委托开发合同中未对软件著作权归属作出明确的约定&#xff0c;所以该信息系统管理软件的著作权由(甲) 享有。 真题2&#xff1a;根据…

算法日记48 day 图论(拓扑排序,dijkstra)

今天继续图论章节&#xff0c;主要是拓扑排序和dijkstra算法。 还是举例说明。 题目&#xff1a;软件构建 117. 软件构建 (kamacoder.com) 题目描述 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件…

复原IP地址 什么是运算符重载? 如何在 C++ 中进行运算符重载?运算符重载在面向对象编程中的好处是什么?getline方法

getline方法 getline 是一个强大的函数&#xff0c;主要用于从输入流中按行读取数据或基于自定义分隔符提取字符串。它是 C 标准库的一部分&#xff0c;定义在头文件 <string> 中。 语法 std::getline(istream& input, std::string& str);input&#xff1a;输…

【蓝桥杯备战】Day 1

1.基础题目 LCR 018.验证回文串 给定一个字符串 s &#xff0c;验证 s 是否是 回文串 &#xff0c;只考虑字母和数字字符&#xff0c;可以忽略字母的大小写。 本题中&#xff0c;将空字符串定义为有效的 回文串 。 示例 1: 输入: s "A man, a plan, a canal: Panama…

牛客网刷题 | BC126 小乐乐查找数字

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;从0至1-CSDN博客&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;C语言、C、数据结构、嵌入式、Linux&#x1f36d; &#x1f60e;本文内容&#x1f923;&#xff1a;&#x1f36d;BC1…

单元测试-FATAL ERROR in native method: processing of -javaagent failed

文章目录 前言单元测试-FATAL ERROR in native method: processing of -javaagent failed1. 报错信息2. 解决方案 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运…

使用PaliGemma2构建多模态目标检测系统:从架构设计到性能优化的技术实践指南

目标检测技术作为计算机视觉领域的核心组件&#xff0c;在自动驾驶系统、智能监控、零售分析以及增强现实等应用中发挥着关键作用。本文将详细介绍PaliGemma2模型的微调流程&#xff0c;该模型通过整合SigLIP-So400m视觉编码器与Gemma 2系列的高级语言模型&#xff0c;专门针对…

uni-app 设置缓存过期时间【跨端开发系列】

&#x1f517; uniapp 跨端开发系列文章&#xff1a;&#x1f380;&#x1f380;&#x1f380; uni-app 组成和跨端原理 【跨端开发系列】 uni-app 各端差异注意事项 【跨端开发系列】uni-app 离线本地存储方案 【跨端开发系列】uni-app UI库、框架、组件选型指南 【跨端开…

东方明珠生成式人工智能媒体融合创新平台荣获AI Cloud轻量云典型案例

近日&#xff0c;由全球数字经济大会组委会主办&#xff0c;中国信息通信研究院&#xff08;以下简称“信通院”&#xff09;、中国通信企业协会承办的2024全球数字经济大会云AI计算国际合作论坛在北京成功召开。会上隆重发布了2024年“AI Cloud助力大模型场景化和工程化落地”…