PINN学习记录(2)

PINN学习记录(2)PINN 学习记录 2 PINN 基于解物理的方程的应用 所以我自己学习了一段时间 参考了网上很多的开源项目 末尾会贴出一些 自己总结了一下思路解微分方程 1 ODEf x f x f x f x f x f x f 0 1f 0 1f 0 1 网络构造这里说明一下 之后用 nn module 来解决 这只是建立一个通用网络 importtorchi nnasnnimport nn Module

PINN学习记录(2)

PINN基于解物理的方程的应用,所以我自己学习了一段时间,参考了网上很多的开源项目,末尾会贴出一些,自己总结了一下思路

解微分方程

1、ODE

f ′ ( x ) = f ( x ) f'(x)=f(x) f(x)=f(x)
f ( 0 ) = 1 f(0)=1 f(0)=1

网络构造

这里说明一下,之后用nn.module,来解决,这只是建立一个通用网络

import torch import torch.nn as nn import numpy as np class Net(nn.Module): def __init__(self, NL, NN): # NL是有多少层隐藏层 # NN是每层的神经元数量 super(Net, self).__init__() self.input_layer = nn.Linear(1, NN) self.hidden_layer = nn.ModuleList([nn.Linear(NN, NN) for i in range(NL)]) self.output_layer = nn.Linear(NN, 1) def forward(self, x): o = self.act(self.input_layer(x)) for i, li in enumerate(self.hidden_layer): o = self.act(li(o)) out = self.output_layer(o) return out def act(self, x): return torch.tanh(x) 
网络,损失,优化声明
net=Net(4,20) mse_cost_function = torch.nn.MSELoss(reduction='mean') # Mean squared error optimizer = torch.optim.Adam(net.parameters(),lr=1e-4) 
ode建立
def ode_01(x,net): y=net(x) y_x = torch.autograd.grad(y, x,grad_outputs=torch.ones_like(net(x)),create_graph=True)[0] return y-y_x 

注意:对于torch.autograd.grad,如果没有说明grad_outputs,就用y.sum()

训练
iterations=1000 for epoch in range(iterations): # Loss based on initial value x_in = np.random.uniform(low=0.0, high=2.0, size=(2000, 1)) pt_x_in = Variable(torch.from_numpy(x_in).float(), requires_grad=True) y = torch.exp(pt_x_in)#与真实值作比较 y_0 = net(torch.zeros( 2000,1)) mse_i = mse_cost_function(y_0, torch.ones( 2000,1)) optimizer.zero_grad() # to make the gradients zero # Loss based on ODE pt_all_zeros= Variable(torch.from_numpy(np.zeros((2000,1))).float(), requires_grad=False) pt_y_colection=ode_01(pt_x_in,net) mse_f=mse_cost_function(pt_y_colection,pt_all_zeros) # Combining the loss functions loss = mse_i+ mse_f #y_train测试 y_train0 = net(pt_x_in) loss.backward() # This is for computing gradients using backward propagation optimizer.step() # This is equivalent to : theta_new = theta_old - alpha * derivative of J w.r.t theta if epoch%1000==0: print(epoch, "Traning Loss:", loss.data) print(f'times { 
     epoch} - loss: { 
     loss.item()} - y_0: { 
     y_0}') plt.cla() plt.scatter(pt_x_in.detach().numpy(), y.detach().numpy()) plt.scatter(pt_x_in.detach().numpy(), y_train0.detach().numpy(),c='red') plt.pause(0.1) 
完整CODE
from mylayer import Net 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 """ NOTE:当用linspace生成,作图可以用plot 但换成uniform,必须用scatter 否则图形会因为随机取样而失真 """ class MyNet(torch.nn.Module): def __init__(self): super(MyNet, self).__init__() # 第一句话,调用父类的构造函数 self.mylayer1 = Net() def forward(self, a): x = self.mylayer1(a) return x """ 用神经网络模拟微分方程,f(x)'=f(x),初始条件f(0) = 1 """ net=Net(4,20) mse_cost_function = torch.nn.MSELoss(reduction='mean') # Mean squared error optimizer = torch.optim.Adam(net.parameters(),lr=1e-4) def ode_01(x,net): y=net(x) y_x = torch.autograd.grad(y, x,grad_outputs=torch.ones_like(net(x)),create_graph=True)[0] return y-y_x iterations=104 #可以试试用linspace也可以做出来 #x_i = torch.linspace(0, 2, 2000, requires_grad=True).unsqueeze(-1) plt.ion() for epoch in range(iterations): # Loss based on initial value x_bc = np.zeros((500, 1)) x_in = np.random.uniform(low=0.0, high=2.0, size=(2000, 1)) pt_x_in = Variable(torch.from_numpy(x_in).float(), requires_grad=True) y = torch.exp(pt_x_in) y_0 = net(torch.zeros( 2000,1)) y_train0 = net(pt_x_in) mse_i = mse_cost_function(y_0, torch.ones( 2000,1)) optimizer.zero_grad() # to make the gradients zero # Loss based on PDE pt_all_zeros= Variable(torch.from_numpy(np.zeros((2000,1))).float(), requires_grad=False) pt_y_colection=ode_01(pt_x_in,net) mse_f=mse_cost_function(pt_y_colection,pt_all_zeros) # Combining the loss functions loss = mse_i+ mse_f loss.backward() # This is for computing gradients using backward propagation optimizer.step() # This is equivalent to : theta_new = theta_old - alpha * derivative of J w.r.t theta if epoch%1000==0: print(epoch, "Traning Loss:", loss.data) print(f'times { 
     epoch} - loss: { 
     loss.item()} - y_0: { 
     y_0}') plt.cla() plt.scatter(pt_x_in.detach().numpy(), y.detach().numpy()) plt.scatter(pt_x_in.detach().numpy(), y_train0.detach().numpy(),c='red') plt.pause(0.1) 

2、PDE

网络构造
import torch import torch.nn as nn import numpy as np class Net(nn.Module): def __init__(self, NL, NN): # NL是有多少层隐藏层 # NN是每层的神经元数量 super(Net, self).__init__() self.input_layer = nn.Linear(2, NN) self.hidden_layer = nn.ModuleList([nn.Linear(NN, NN) for i in range(NL)]) self.output_layer = nn.Linear(NN, 1) def forward(self, x): o = self.act(self.input_layer(x)) for i, li in enumerate(self.hidden_layer): o = self.act(li(o)) out = self.output_layer(o) return out def act(self, x): return torch.tanh(x) 

输入改2即可

网络,损失,优化声明
net=Net(4,30) mse_cost_function = torch.nn.MSELoss(reduction='mean') # Mean squared error optimizer = torch.optim.Adam(net.parameters(),lr=1e-4) 
pde
def f(x): u = net(x) u_x = torch.autograd.grad(u, x,grad_outputs=torch.ones_like(net(x)), create_graph=True,allow_unused=True) u_t = torch.autograd.grad(u, x,grad_outputs=torch.ones_like(net(x)), create_graph=True,allow_unused=True) d_x= u_x[0][:, 1].unsqueeze(-1) d_t = u_t[0][:, 0].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) f = d_t + u * d_x - w * u_xx return f 

这里卡了一下,因为我一开始u_x = torch.autograd.grad(u, x[:,1],grad_outputs=torch.ones_like(net(x)), create_graph=True,allow_unused=True)
这样会报错

边界和初始值
#boundary t_bc = np.zeros((2000,1)) x_bc = np.random.uniform(low=-1.0, high=1.0, size=(2000,1)) # compute u based on BC u_bc = -np.sin(np.pi*x_bc) #initial x_inr=np.ones((2000,1)) x_inl=-np.ones((2000,1)) t_in=np.random.uniform(low=0, high=1.0, size=(2000,1)) u_in= np.zeros((2000,1)) 
训练
for epoch in range(iterations): optimizer.zero_grad() # to make the gradients zero # Loss based on boundary conditions pt_x_bc = Variable(torch.from_numpy(x_bc).float(), requires_grad=False) pt_t_bc = Variable(torch.from_numpy(t_bc).float(), requires_grad=False) pt_u_bc = Variable(torch.from_numpy(u_bc).float(), requires_grad=False) net_bc_out = net(torch.cat([ pt_t_bc,pt_x_bc],1)) # output of u(x,t) mse_u1 = mse_cost_function(net_bc_out, pt_u_bc) # Loss based on initial value pt_x_inr = Variable(torch.from_numpy(x_inr).float(), requires_grad=False) pt_x_inl = Variable(torch.from_numpy(x_inl).float(), requires_grad=False) pt_t_in = Variable(torch.from_numpy(t_in).float(), requires_grad=False) pt_u_in = Variable(torch.from_numpy(u_in).float(), requires_grad=False) net_bc_inr = net(torch.cat([ pt_t_in,pt_x_inr],1)) # output of u(x,t) net_bc_inl = net(torch.cat([ pt_t_in,pt_x_inl],1)) mse_u2r = mse_cost_function(net_bc_inr, pt_u_in) mse_u2l = mse_cost_function(net_bc_inl, pt_u_in) # Loss based on 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) f_out = f(torch.cat([pt_t_collocation, pt_x_collocation],1)) # output of f(x,t) mse_f = mse_cost_function(f_out, pt_all_zeros) # Combining the loss functions loss = mse_u1+mse_u2r+mse_u2l + mse_f loss.backward() # This is for computing gradients using backward propagation 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%1000==0: print(epoch, "Traning Loss:", loss.data) 
画图
#画图 from matplotlib import cm 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) 
fig = plt.figure() ax = fig.gca(projection='3d') x = np.arange(-1, 1, 0.02) t = np.arange(0, 1, 0.02) ms_x, ms_t = np.meshgrid(x, t) # Just because meshgrid is used, we need to do the following adjustment 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).to(device) pt_t = Variable(torch.from_numpy(t).float(), requires_grad=True).to(device) pt_u = net(pt_x, pt_t) u = pt_u.data.cpu().numpy() ms_u = u.reshape(ms_t.shape) surf = ax.plot_surface(ms_x, ms_t, ms_u, cmap=cm.coolwarm, linewidth=0, antialiased=False) ax.zaxis.set_major_locator(LinearLocator(10)) ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f')) fig.colorbar(surf, shrink=0.5, aspect=5) plt.show() 
结果
1在这里插入图片描述
2

2

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 电子琴入门教程视频电子琴简谱

    电子琴入门教程视频电子琴简谱电子琴入门教程视频电子琴简谱9套少儿电子琴教程1,儿童电子琴启蒙(上下集)2,儿童专用-简谱五线谱视频教程3,电子琴启蒙视频教程4,儿童电子琴启蒙-全套教程5,少儿电子琴教程6,少儿电子琴入门7,少年儿童电子琴初级、中级、高级教程8,经典儿童歌曲歌谱大全9,儿童电子琴启蒙文档网盘链接:链接:https://pan.baidu.com/s/1PpguBcJOeS82SzELRyG9PA提取码:love领到了给个赞鼓励下哦~…

    2022年8月29日
    7
  • latex缩进与对齐_latex 换行后缩进「建议收藏」

    latex缩进与对齐_latex 换行后缩进「建议收藏」且每个条目输入完毕之后不需要做任何的强迫换行记号,如:\\\\(换行符)或者\\par(分段符)Latex可以自动处理四重enumerate嵌套,编号规则为第一级自然数,第二级……那么,如何让空格在本行行尾自动换行?有两种方法可以实现:方法一:选中文字,然后点击格式——段落——缩进和间距,在常规栏中,选择对齐方式为“左对齐”……且每个条目输入完毕之后不需要…

    2022年5月15日
    358
  • vim cheat sheet

    vim cheat sheet

    2022年1月9日
    41
  • mac idea 2019 激活码_通用破解码

    mac idea 2019 激活码_通用破解码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月16日
    107
  • matlab 用循环求和,matlab循环求和函数[通俗易懂]

    matlab 用循环求和,matlab循环求和函数[通俗易懂]matlab求和的出错symsum是符号运算,要先用syms定义符号变量用法详见docsymsum如何用matlab解带求和函数sum的方程举个例子吧:D=[345];A=7;fsolve(@(X)sum(10.^(X-D))-A,0)则ans=3.7998就这么简单.(还想补充说明一点,fsolve中第一个变量是一个函数句柄,第二个变量matlab求和.符号运算通过符号运算把这个式子拆开什么意…

    2022年10月6日
    3
  • linux怎么将文件复制到别的文件_linux 文件夹复制

    linux怎么将文件复制到别的文件_linux 文件夹复制1.前言本文主要讲解linux怎么复制文件到其他文件夹。在Linux和Unix系统上工作时,复制文件和目录是您每天要执行的最常见任务之一。cp是一个命令行实用程序,用于复制Unix和Linux系统上的文件和目录。在本文中,我们将解释如何使用cp命令。linux怎么复制文件到其他文件夹2.如何使用cp命令cp命令的使用语法:cp[OPTIONS]源…目标源可以有一个或多个文件或目录作为参数,目标可以有一个文件或文件夹作为参数。当源和目标参数都是文件时,cp命令将第一

    2022年8月23日
    7

发表回复

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

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