带硬约束的物理信息神经网络(PINN with Hard Constraint)示例及代码

本文介绍了一种改进的物理信息神经网络(PINN),通过在神经网络结构中内置边界条件,实现了自动满足约束条件,简化了权重调整,展示了在解决二阶常微分方程中的应用效果和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

0.摘要

1.问题描述

2.带硬约束的物理信息神经网络

3.参数设置

4.结果展示

5.完整代码

6.总结


0.摘要

        本文以一个案例介绍了带硬约束的物理信息神经网络的原理及实现步骤。

1.问题描述

        考虑下面的二阶常微分方程。定义域为[0,1]。

2.带硬约束的物理信息神经网络

        常规的PINN解决这个问题需要同时考虑方程项损失和边界条件项损失,由此带来各项损失权重调整等问题。考虑将边界条件构造进神经网络中,使得网络输出自动满足边界条件,即带硬约束的物理信息神经网络。

        针对本文问题实际,将网络输出经过sin(\pi x)映射后,自动满足边界条件,可以只考虑方程项损失。代码如下:

    def forward(self, x):
        if torch.is_tensor(x) == False:
            x = torch.from_numpy(x)
        a = x.float()
        for i in range(len(layers)-2):
            z = self.linears[i](a)
            a = self.activation(z)
        a = self.linears[-1](a)
        def transform(x, y):
            return torch.sin(torch.pi*x) * y
        return transform(x, a)
3.参数设置

        本文基于pytorch平台编写代码,神经网络相关参数:网络架构为\left [ 1 \right ]*\left [ 50 \right ]*\left [ 1 \right ],学习率为0.0001,激活函数为tanh,优化器为Adam,训练10000轮。

4.结果展示

图1 损失下降曲线

图2 结果图像
图3 误差曲线

        从损失曲线看,网络训练良好,从结果图像及误差曲线看,硬约束的施加使得网络输出自动满足边界条件,避免了繁琐的权重调整,同时也降低了误差。

5.完整代码
import time
import torch
import torch.autograd as autograd
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt

torch.set_default_dtype(torch.float)

torch.manual_seed(1234)

np.random.seed(1234)

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)

if device == 'cuda':
    print(torch.cuda.get_device_name())

class FCN(nn.Module):
    def __init__(self, layers):
        super().__init__()
        self.activation = nn.Tanh()
        self.loss_function = nn.MSELoss(reduction='mean')
        self.linears = nn.ModuleList([nn.Linear(layers[i], layers[i+1]) for i in range(len(layers)-1)])
        self.iter = 0

        for i in range(len(layers)-1):
            nn.init.xavier_normal_(self.linears[i].weight.data, gain=1.0)
            nn.init.zeros_(self.linears[i].bias.data)

    def forward(self, x):
        if torch.is_tensor(x) == False:
            x = torch.from_numpy(x)
        a = x.float()
        for i in range(len(layers)-2):
            z = self.linears[i](a)
            a = self.activation(z)
        a = self.linears[-1](a)
        def transform(x, y):    #硬约束施加
            return torch.sin(torch.pi*x) * y
        return transform(x, a)

    def lossPDE(self, x_PDE):
        g = x_PDE.clone()
        g.requires_grad = True
        f = self.forward(g)
        f_x = autograd.grad(f, g, torch.ones_like(g).to(device), retain_graph=True, create_graph=True)[0]
        f_xx = autograd.grad(f_x, g, torch.ones_like(g).to(device), create_graph=True)[0]
        f = f_xx - 1
        return self.loss_function(f, torch.zeros_like(f))

x = torch.linspace(0, 1, 101).reshape(-1,1)
index = torch.randperm(x.size(0))
x = x[index]
x_train = x.float().to(device)

#网络参数设置
steps = 10000
lr = 1e-4
layers = np.array([1, 50, 1])

PINN = FCN(layers)
PINN.to(device)
print(PINN)
params = list(PINN.parameters())
optimizer = torch.optim.Adam(PINN.parameters(), lr=lr, amsgrad=False)
losses = []

start_time = time.time()
for i in range(steps):
    if i == 0:
        print('Start Training')
    loss = PINN.lossPDE(x_train)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    losses.append(loss.item())

    if i%100 == 0:
        print(f'epoch:{i}','loss:',loss.detach().cpu().numpy())

print('Running Time: ', -start_time+time.time())
plt.plot(range(steps), losses)
plt.title('Loss')
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

path_state_dict = './model_state_dict.pkl'
net_state_dict = PINN.state_dict()
torch.save(net_state_dict, path_state_dict)

Net_new = FCN(layers).to(device)
path_state_dict = r'D:\Python1\PINN\model_state_dict.pkl'
state_dict_load = torch.load(path_state_dict)
Net_new.load_state_dict(state_dict_load)

x_test = torch.linspace(0, 1, 101).reshape(-1,1).to(device)
y_pred = Net_new(x_test)

x_plot = x_test.detach().cpu().numpy()
y_plot = y_pred.detach().cpu().numpy()
y_true = (-1/2)*x_plot*(1-x_plot)   #理论解

plt.figure(1)
plt.plot(x_plot, y_plot, label='Predicted')
plt.plot(x_plot, y_true, label='True')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()

plt.figure(2)
plt.plot(x_plot,y_true-y_plot,label='Error')
plt.xlabel('x')
plt.ylabel('y_error')
plt.legend()
plt.show()
6.总结

        本文分享了作者在带硬约束的物理信息神经网络方面的一些工作。

        转载请注明出处。

### 回答1: MATLAB PINN代码是指基于神经网络的偏微分方程求解代码。这种新型求解方法通过神经网络学习偏微分方程的解,进而求解未知的物理量。这种方法能够比传统的基于网格的求解方法更高效、更精确地求解偏微分方程,并且能够适应复杂的多物理场耦合问题。 在MATLAB PINN代码中,主要包括以下几个部分: 1. 数据预处理:对要求解的偏微分方程进行网格化,对数据进行预处理、归一化等操作 2. 神经网络定义:通过搭建神经网络,进行训练与求解偏微分方程。在网络中,可以加入各种不同的激活函数、损失函数等,以实现不同的物理场求解。 3. 模型训练与求解:对搭建好的神经网络进行训练,利用梯度下降等算法不断更新网络权重,使其逐渐逼近真实的解。在模型训练完成后,就可以进行偏微分方程的求解。 4. 结果可视化:将求解结果可视化,通过二维或三维图像来展现不同物理场的解的情况。 总结来说,MATLAB PINN代码作为一种新型的偏微分方程求解方法,具有速度快、准确度高、适用于复杂多物理场问题等优点,是当前求解偏微分方程领域的研究热点。 ### 回答2: MATLAB Pinn(Physically-Informed Neural Networks)代码是用于神经网络建模的一种工具,它可以用于物理系统建模、动力学建模和流体力学等领域。它允许用户将微分方程融入神经网络模型中,并且可以通过数据拟合来验证和优化模型的准确性。 Pinn代码有以下几个主要部分: 1.输入数据处理部分:这个部分主要用于数据预处理、分块和归一化。用户需要将数据处理成合适的格式,以供网络训练使用。 2.神经网络结构部分:这个部分定义了神经网络的结构和参数。用户需要选择合适的网络架构、层数、单元数和激活函数等参数,并定义优化器和损失函数。 3.微分方程部分:这个部分包含微分方程的定义和参数。用户需要定义微分方程的形式和参数,并将其嵌入到神经网络模型中。 4.模型训练部分:这个部分使用准备好的数据、神经网络结构和微分方程定义来进行训练。用户需要选择训练数据和测试数据,并设置训练批次、学习率和训练周期等参数。 5.模型验证部分:这个部分将训练好的模型用于数据验证和预测。用户可以用测试数据验证模型的准确度,并使用模型进行预测。 总的来说,Pinn代码是一种快速有效的工具,可以结合微分方程和神经网络对各种自然现象进行建模和预测,为科学研究和应用提供有力支持。 ### 回答3: MATLAB Pinn代码是指用MATLAB编写的神经网络预测程序,它使用了物理约束以及神经网络来对某个系统或过程进行建模和预测。Pinn全称为Physics-Informed Neural Networks,是近年来出现的一种结合了物理约束和神经网络的技术,其主要思想是将物理定律和现象加入到神经网络中,以提高神经网络的预测精度和泛化能力。 MATLAB Pinn代码的实现过程中,主要分为以下几个步骤: 1. 数据预处理:对原始数据进行清洗、预处理和特征提取,以便后续神经网络进行训练和预测。其中包括对数据进行标准化、降维和筛选等操作。 2. 模型搭建:根据物理模型和神经网络模型,构建全局损失函数和局部损失函数,并将其加入到神经网络的训练过程中,以提高模型的精度和泛化能力。 3. 训练模型:利用已预处理的数据集,使用反向传播算法对神经网络进行训练,并监测模型的训练误差和验证误差,以调整模型参数并优化模型性能。 4. 模型预测:将训练好的模型应用到新的数据上,进行预测并输出结果。同时,对预测结果进行评估和分析,以检验模型的准确性和可靠性。 总之,MATLAB Pinn代码是一种全新的、高度灵活和可扩展的预测方法,可用于各种科学研究、工程应用和商业领域,具有很大的应用潜力和商业价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值