使用深度神经网络求解偏微分方程

Posted

技术标签:

【中文标题】使用深度神经网络求解偏微分方程【英文标题】:solving a partial differential equation using a deep neural network 【发布时间】:2022-01-17 02:15:34 【问题描述】:

该程序在计算偏导数时抛出异常:

AttributeError: 'NoneType' object has no attribute 'op'

我怀疑 PDE 函数有问题,但我不知道如何修复它。 我之所以这样编写 PDE 函数是因为我不想依赖外部包 deepxde。一个有效的实现使用 deepxde 包,如下所示:

def pde(x, y):
    dy_t = dde.grad.jacobian(y, x, j=1)
    dy_xx = dde.grad.hessian(y, x, j=0)

    return (
        dy_t
        - dy_xx*0.3)

应该可以使用直接在张量上操作的梯度函数进行微分,以便将计算集成到反向传播算法中。

import tensorflow as tf
#!pip install --upgrade tensorflow
import deepxde as dde
import numpy as np
# Backend tensorflow.compat.v1 or tensorflow
from deepxde.backend import tf
import time 
import matplotlib.pyplot as plt
t0 = time.time()

# Suppress warnings
import warnings
warnings.filterwarnings("ignore")


# ## Helper function to plot $u(x,t)$



def plot(geom_time,data,name):
    plt.figure()
    plt.scatter(geom_time[:,0], geom_time[:,1],s = 20, c=np.reshape(data, (len(data),)), cmap='jet')
    plt.colorbar()
    plt.xlabel('x domain')
    plt.ylabel('time domain')
    plt.title(name)
    plt.show()



def pde(x, y):
    dy_t = tf.gradients(y, x[:, 1:2])
    dy_x = tf.gradients(y, x[:, 0:1])
    dy_xx= tf.gradients(dy_x, x[:, 0:1])
#
    return (
        dy_t
        - dy_xx*0.3)
    

def func(x):
    return np.sin(np.pi * x[:, 0:1]) * np.exp(-x[:, 1:])


# ## 2. initialization
# Define geometry and time horizons for simulation

geom = dde.geometry.Interval(-1, 1)
timedomain = dde.geometry.TimeDomain(0, 1)
geomtime = dde.geometry.GeometryXTime(geom, timedomain)


# Define boundary conditions and initial conditions



bc = dde.DirichletBC(geomtime, func, lambda _, on_boundary: on_boundary)
ic = dde.IC(geomtime, func, lambda _, on_initial: on_initial)


# Create data points needed for building the model

data = dde.data.TimePDE(
    geomtime,
    pde,
    [bc, ic],
    num_domain=4000,
    num_boundary=2000,
    num_initial=1000,
    solution=func,
    num_test=1000,
)


# ### Steps in building the model 
# 
# - Define the number of layers and neurons per layer in the neural network
# - Define activation function on these layers _tanh_
# - Define function for initial weights for training _Glorot uniform_
# - Train the network using Adam optimizer with learning rate of 0.001



layer_size = [2] + [32] * 3 + [1]

activation = "tanh"
initializer = "Glorot uniform"

net = dde.maps.FNN(layer_size, activation, initializer)
model = dde.Model(data, net)
model.compile("adam", lr=0.001, metrics=["l2 relative error"])


# ## 3. Training
# 

t1 = time.time()

losshistory, train_state = model.train(epochs=3000)

t2 = time.time()
print("training time:",(t2-t1))


# ## 4. Post-training Visualization



dde.postprocessing.plot_loss_history(losshistory)
plt.show()


x_data = np.linspace(-1,1,num = 100)
t_data = np.linspace(0,1,num = 100)
test_x , test_t = np.meshgrid(x_data, t_data)
test_domain = np.vstack((np.ravel(test_x), np.ravel(test_t))).T
predicted_solution = model.predict(test_domain)
residual = model.predict(test_domain,operator=pde)



plot(test_domain,predicted_solution,"predicted solution")


plot(test_domain,residual,"residual")


print("total time")
print(t2-t0)

【问题讨论】:

我注意到您将两个不同的(子)模块导入为tf。这可能是问题的一部分吗? 即使只有一个导入语句,问题仍然存在 【参考方案1】:

我找到了一个在 PDE 函数中使用 Tensorflow 梯度的解决方案,如下所示:

def pde(x, y):
#    dy_t = tf.gradients(y, x[:, 1:2])[0]
    dy_t = tf.gradients(y, x)[0][:, 1:2]
#    dy_x = tf.gradients(y, x[:, 0:1])[0]
    dy_x = tf.gradients(y, x)[0][:, 0:1]
#    dy_xx= tf.gradients(dy_x, x[:, 0:1])[0]
    dy_xx= tf.gradients(dy_x, x)[0][:, 0:1]
#
    return (
        dy_t
        - dy_xx*0.3)
    

def func(x):
    return np.sin(np.pi * x[:, 0:1]) * np.exp(-x[:, 1:])

然而,尚不清楚为什么注释掉的语句会导致之前报告的异常。

【讨论】:

以上是关于使用深度神经网络求解偏微分方程的主要内容,如果未能解决你的问题,请参考以下文章

团队在使用深度神经网络求随机微分方程的统计解方面取得重要进展!

加州理工华人博士提出傅里叶神经算子,偏微分方程提速1000倍,告别超算!

70行代码实现深度神经网络算法

天生一对,硬核微分方程与深度学习的「联姻」之路

深度神经网络原理与实践

PyTorch深度学习60分钟快速入门 Part2:Autograd自动化微分