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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 硬盘上的esp分区和msr分区_win10引导盘符选ESP还是MSR

    硬盘上的esp分区和msr分区_win10引导盘符选ESP还是MSRwindows

    2022年8月5日
    6
  • java jar 没有主清单_java运行jar命令提示没有主清单属性

    java jar 没有主清单_java运行jar命令提示没有主清单属性在 JAVA 中将 class 文件编译成 jar 文件包 运行提示没有主清单属性 这是怎么回事 今天来教大家如何解决这个问题 1 在 java 中编译 JAR 文件的时候我们都会用到 jar 这个命令 当用着 jar 文件时候我们不可少的是 cvf 这几个参数来生成 jar 文件 但是用个文件来了 在用不使用工具的前提下我们生成的 jar 文件包后运行会出现 某某类的没有主清单属性 如下图 2 这样的问题是因为 jar 包中的 META

    2025年11月6日
    1
  • 个人数字作品合作协议

    个人数字作品合作协议个人数字作品合作协议甲方:地址:身份证号:联系方式:乙方:北京创新乐知网络技术有限公司地址:北京市朝阳区酒仙桥路10号恒通商务园B8b二层本协议系由北京创新乐知网络技术有限公司(以下简称”CSDN”)与所有通过CSDN下载平台发布作品的用户就资源的引入、使用及相关服务所订立的有效合约,您必须同意并遵守本协议。您通过任何方式参与数字作品提交均被视为您完全接受本协议。本协议具有合同效力。一、总则1.1本协议内容包括协议正文及所有CSDN及CSDN下载平台已经发布的或将来.

    2022年6月23日
    25
  • dom4j解析xml字符串

    dom4j解析xml字符串与利用DOM、SAX、JAXP机制来解析xml相比,DOM4J表现更优秀,具有性能优异、功能强大和极端易用使用的特点,只要懂得DOM基本概念,就可以通过dom4j的api文档来解析xml。dom4j是一套开源的api。实际项目中,往往选择dom4j来作为解析xml的利器。先来看看dom4j中对应XML的DOM树建立的继承关系针对于XML标准定义,对应于图2-1列出的内容,do

    2022年6月21日
    39
  • C语言 stat 函数「建议收藏」

    C语言 stat 函数「建议收藏」C语言stat函数stat头文件:#include<sys/stat.h>#include<unistd.h>函数原型:intstat(constchar*file_name,structstat*buf)**函数说明:**stat函数获取file_name指向文件的文件状态,并将文件信息保存到结构体buf中,执行成功返回0,失…

    2022年8月21日
    20
  • DatabaseMetaData的简单使用

    DatabaseMetaData的简单使用在看大佬写的一个导出数据库建标脚本的接口的时候,发现频频用到DataBaseMetaData这个类,之前也没有用过这个类下的API,记录一下心得用法。DatabaseMetaData是java.sql包中的接口,利用它可以获取我们连接到的数据库的结构、存储等很多信息;先上个API文档:这英文看的是心力憔悴,直接来看这个接口…

    2022年6月19日
    24

发表回复

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

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