PINN学习与实验(二)

PINN学习与实验(二)目录所用工具数学方程模型搭建所有实现代码结果展示参考文献今天第二天接触 PINN 用深度学习的方法求解 PDE 看来是非常不错的方法 做了一个简单易懂的例子 这个例子非常适合初学者 跟着教程做了一个小 demo 大家可以参考参考 本文代码亲测可用 直接复制就能使用 非常方便 所用工具使用了 python 和 pytorch 进行实现 python3 6toch1 10 数学方程使用一个最简单的常微分方程 ut u ux w uxx 0 1 u 0 x sin x 2 u t 1 0 3 u

接触PINN一段时间了,用深度学习的方法求解偏微分方程PDE,看来是非常不错的方法。做了一个简单易懂的例子,这个例子非常适合初学者。跟着教程做了一个小demo, 大家可以参考参考。本文代码亲测可用,直接复制就能使用,非常方便。

所用工具

数学方程

模型搭建

核心-使用最简单的全连接层:

class Net(nn.Module): def __init__(self, NN): # NL n个l(线性,全连接)隐藏层, NN 输入数据的维数, 128 256 # NL是有多少层隐藏层 # NN是每层的神经元数量 super(Net, self).__init__() self.input_layer = nn.Linear(2, NN) self.hidden_layer1 = nn.Linear(NN,int(NN/2))  原文这里用NN,我这里用的下采样,经过实验验证,“等采样”更优 self.hidden_layer2 = nn.Linear(int(NN/2), int(NN/2)  原文这里用NN,我这里用的下采样,经过实验验证,“等采样”更优 self.output_layer = nn.Linear(int(NN/2, 1) def forward(self, x): # 一种特殊的方法 __call__() 回调 out = torch.tanh(self.input_layer(x)) out = torch.tanh(self.hidden_layer1(out)) out = torch.tanh(self.hidden_layer2(out)) out_final = self.output_layer(out) return out_final 

偏微分方程定义,也就是公式(1):

def pde(x, net): u = net(x) # 网络得到的数据 u_tx = torch.autograd.grad(u, x, grad_outputs=torch.ones_like(net(x)), create_graph=True, allow_unused=True)[0] # 求偏导数 d_t = u_tx[:, 0].unsqueeze(-1) d_x = u_tx[:, 1].unsqueeze(-1) u_xx = torch.autograd.grad(d_x, x, grad_outputs=torch.ones_like(d_x), create_graph=True, allow_unused=True)[0][:,1].unsqueeze(-1) # 求偏导数 w = torch.tensor(0.01 / np.pi) return d_t + u * d_x - w * u_xx # 公式(1) 

所有实现代码

一下代码复制粘贴,可直接运行:

import torch import torch.nn as nn import torch import torch.nn as nn import numpy as np import matplotlib.pyplot as plt import torch.optim as optim from torch.autograd import Variable import numpy as np from matplotlib import cm # 模型搭建 class Net(nn.Module): def __init__(self, NN): # NL n个l(线性,全连接)隐藏层, NN 输入数据的维数, 128 256 # NL是有多少层隐藏层 # NN是每层的神经元数量 super(Net, self).__init__() self.input_layer = nn.Linear(2, NN) self.hidden_layer1 = nn.Linear(NN,int(NN/2))  原文这里用NN,我这里用的下采样,经过实验验证,“等采样”更优 self.hidden_layer2 = nn.Linear(int(NN/2), int(NN/2))  原文这里用NN,我这里用的下采样,经过实验验证,“等采样”更优 self.output_layer = nn.Linear(int(NN/2, 1)) def forward(self, x): # 一种特殊的方法 __call__() 回调 out = torch.tanh(self.input_layer(x)) out = torch.tanh(self.hidden_layer1(out)) out = torch.tanh(self.hidden_layer2(out)) out_final = self.output_layer(out) return out_final def pde(x, net): u = net(x) # 网络得到的数据 u_tx = torch.autograd.grad(u, x, grad_outputs=torch.ones_like(net(x)), create_graph=True, allow_unused=True)[0] # 求偏导数 d_t = u_tx[:, 0].unsqueeze(-1) d_x = u_tx[:, 1].unsqueeze(-1) u_xx = torch.autograd.grad(d_x, x, grad_outputs=torch.ones_like(d_x), create_graph=True, allow_unused=True)[0][:,1].unsqueeze(-1) # 求偏导数 w = torch.tensor(0.01 / np.pi) return d_t + u * d_x - w * u_xx # 公式(1) net = Net(30) mse_cost_function = torch.nn.MSELoss(reduction='mean') # Mean squared error optimizer = torch.optim.Adam(net.parameters(), lr=1e-4) # 初始化 常量 t_bc_zeros = np.zeros((2000, 1)) x_in_pos_one = np.ones((2000, 1)) x_in_neg_one = -np.ones((2000, 1)) u_in_zeros = np.zeros((2000, 1)) iterations = 10000 for epoch in range(iterations): optimizer.zero_grad() # 梯度归0 # 求边界条件的误差 # 初始化变量 t_in_var = np.random.uniform(low=0, high=1.0, size=(2000, 1)) x_bc_var = np.random.uniform(low=-1.0, high=1.0, size=(2000, 1)) u_bc_sin = -np.sin(np.pi * x_bc_var) # 将数据转化为torch可用的 pt_x_bc_var = Variable(torch.from_numpy(x_bc_var).float(), requires_grad=False) pt_t_bc_zeros = Variable(torch.from_numpy(t_bc_zeros).float(), requires_grad=False) pt_u_bc_sin = Variable(torch.from_numpy(u_bc_sin).float(), requires_grad=False) pt_x_in_pos_one = Variable(torch.from_numpy(x_in_pos_one).float(), requires_grad=False) pt_x_in_neg_one = Variable(torch.from_numpy(x_in_neg_one).float(), requires_grad=False) pt_t_in_var = Variable(torch.from_numpy(t_in_var).float(), requires_grad=False) pt_u_in_zeros = Variable(torch.from_numpy(u_in_zeros).float(), requires_grad=False) # 求边界条件的损失 net_bc_out = net(torch.cat([pt_t_bc_zeros, pt_x_bc_var], 1)) # u(x,t)的输出 mse_u_2 = mse_cost_function(net_bc_out, pt_u_bc_sin) # e = u(x,t)-(-sin(pi*x)) 公式(2) net_bc_inr = net(torch.cat([pt_t_in_var, pt_x_in_pos_one], 1)) # 0=u(t,1) 公式(3) net_bc_inl = net(torch.cat([pt_t_in_var, pt_x_in_neg_one], 1)) # 0=u(t,-1) 公式(4) mse_u_3 = mse_cost_function(net_bc_inr, pt_u_in_zeros) # e = 0-u(t,1) 公式(3) mse_u_4 = mse_cost_function(net_bc_inl, pt_u_in_zeros) # e = 0-u(t,-1) 公式(4) # 求PDE函数式的误差 # 初始化变量 x_collocation = np.random.uniform(low=-1.0, high=1.0, size=(2000, 1)) t_collocation = np.random.uniform(low=0.0, high=1.0, size=(2000, 1)) all_zeros = np.zeros((2000, 1)) pt_x_collocation = Variable(torch.from_numpy(x_collocation).float(), requires_grad=True) pt_t_collocation = Variable(torch.from_numpy(t_collocation).float(), requires_grad=True) pt_all_zeros = Variable(torch.from_numpy(all_zeros).float(), requires_grad=False) # 将变量x,t带入公式(1) f_out = pde(torch.cat([pt_t_collocation, pt_x_collocation], 1), net) # output of f(x,t) 公式(1) mse_f_1 = mse_cost_function(f_out, pt_all_zeros) # 将误差(损失)累加起来 loss = mse_f_1 + mse_u_2 + mse_u_3 + mse_u_4 loss.backward() # 反向传播 optimizer.step() # This is equivalent to : theta_new = theta_old - alpha * derivative of J w.r.t theta with torch.autograd.no_grad(): if epoch % 100 == 0: print(epoch, "Traning Loss:", loss.data)  画图  t = np.linspace(0, 1, 100) x = np.linspace(-1, 1, 256) ms_t, ms_x = np.meshgrid(t, x) x = np.ravel(ms_x).reshape(-1, 1) t = np.ravel(ms_t).reshape(-1, 1) pt_x = Variable(torch.from_numpy(x).float(), requires_grad=True) pt_t = Variable(torch.from_numpy(t).float(), requires_grad=True) pt_u0 = net(torch.cat([pt_t, pt_x], 1)) u = pt_u0.data.cpu().numpy() pt_u0 = u.reshape(256, 100) fig = plt.figure() ax = fig.add_subplot(projection='3d') ax.set_zlim([-1, 1]) ax.plot_surface(ms_t, ms_x, pt_u0, cmap=cm.RdYlBu_r, edgecolor='blue', linewidth=0.0003, antialiased=True) ax.set_xlabel('t') ax.set_ylabel('x') ax.set_zlabel('u') plt.savefig('Preddata.png') plt.close(fig) 

结果展示

参考文献




















版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207258.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午2:13
下一篇 2026年3月19日 下午2:13


相关推荐

  • python 字典操作提取key,value

    python 字典操作提取key,valuepython 字典操作提取 key valuediction key value1 为字典增加一项 2 访问字典中的值 3 删除字典中的一项 4 遍历字典 5 字典遍历的 key value6 字典的标准操作符 7 判断一个键是否在字典中 8 python 中其他的一些字典方法 9 将两个字典合并 a a 1

    2026年3月20日
    2
  • HUE beeswax中文显示问题的解决方案

    HUE beeswax中文显示问题的解决方案HUE 是 Cloudera 推出的 Hadoop 生态系统的 Web 访问接口 基于 PythonDjango 开发 在使用过程中发现 如果提交的 SQL 语句中有中文的注释 提交之后 整个语句将会保存在后端的 MySQL 历史表中 但是再次去查看历史记录的时候 其中的中文却显示成一串问号 显然 这种问题是因为数据库编码问题导致的 为了解决这个问题 可以做如下的操作 1 修改 MySQL 的配置文件 e

    2026年3月18日
    1
  • 神经网络的优化算法_梯度下降优化算法

    神经网络的优化算法_梯度下降优化算法最近回顾神经网络的知识,简单做一些整理,归档一下神经网络优化算法的知识。关于神经网络的优化,吴恩达的深度学习课程讲解得非常通俗易懂,有需要的可以去学习一下,本人只是对课程知识点做一个总结。吴恩达的深度

    2022年8月1日
    9
  • 收藏!小白程序员快速入门大模型与智能体核心概念解析

    收藏!小白程序员快速入门大模型与智能体核心概念解析

    2026年3月14日
    3
  • 整除计算器_0 整除

    整除计算器_0 整除原题链接这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如,111111就可以被13整除。 现在,你的程序要读入一个整数x,这个整数一定是奇数并且不以5结尾。然后,经过计算,输出两个数字:第一个数字s,表示x乘以s是一个光棍,第二个数字n是这个光棍的位数。这样的解当然不是唯一的,题目要求你输出最小的解。提示:一个显然的办法是逐渐增加光棍的位数,直到可以整除x为止。但难点在于,s可能是个非常大的数 ——

    2022年8月8日
    5
  • USB转232和485的区别

    1串口串口,即串行通信接口,与之相对应的另一种接口叫并口,并行接口。两者的区别是,传输一个字节(8个位)的数据时,串口是将8个位排好队,逐个地在1条连接线上传输,而并口则将8个位一字排开,分别在8条连接线上同时传输,也就是进行数据传输的接口串口是一种物理接口形式,(硬件)通常指COM接口,当然这些接口有着很多标准接口标准:串口通信的接口标准有很多,而我们所了解的RS-23…

    2022年4月7日
    82

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号