lululxvi / deepxde

A library for scientific machine learning and physics-informed learning
https://deepxde.readthedocs.io
GNU Lesser General Public License v2.1
2.58k stars 732 forks source link

How to fit multivariate functions or perform data fitting by means of the FNN in Deepxde? #111

Closed zxw4688 closed 3 years ago

zxw4688 commented 4 years ago

Hello @lululxvi , I find your package is very powerful, which can do many things on deep learning, such as fitting data which is simpler than solving and learning PDE, regression analysis of data and so on. Therefore, I would like to try to fit multivariate functions, for example, the function is f(x,t)=sin(x)sin(t). The data is provided as follow: Nx=11 , Nt=11 Xx=np.linspace(0,1,Nx) Tt=np.linspace(0,1,Nt) INt=np.ones(Nt) X=np.kron(INt,Xx) INx=np.ones(Nx) T=np.kron(Tt,INx) Input_data=np.array([X,T]) Label_data=np.sin(X)np.sin(T) noise_data=0.02tf.random.normal(shape=[NxNt]) Label_data=Label_data+noise_data data=np.array([Input_data,Label_data]). However, I am not good at tensorflow and python, I tried it, and didn't make it. Please help me ,how to revise it. Thank you very much. My code is : `from future import absolute_import from future import division from future import print_function

import numpy as np

import deepxde as dde from deepxde.backend import tf

def main(): Nx=11 Nt=11 Xx=np.linspace(0,1,Nx) Tt=np.linspace(0,1,Nt) INt=np.ones(Nt) X=np.kron(INt,Xx) INx=np.ones(Nx) T=np.kron(Tt,INx) Input_data=np.array([X,T]) Label_data=np.sin(X)np.sin(T) noise_data=0.02tf.random.normal(shape=[NxNt]) Label_data=Label_data+noise_data data=np.array([Input_data,Label_data]) layer_size = [2] + [50] 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"])
losshistory, train_state = model.train(epochs=10000)

dde.saveplot(losshistory, train_state, issave=True, isplot=True)

if name == "main": main()`

zxw4688 commented 3 years ago

我试过, 我取num_domain = 10000, num_boundary =100,,依然是这样啊,结果仍然是L2的相对误差几乎是接近于1的。

zxw4688 commented 3 years ago

我想知道为什么,我还调整了超参数,隐藏层数神经元数,依然不变。

zxw4688 commented 3 years ago

另外我通过MATLAB对程序运行完的数据train进行与真解的L2误差和相对误差计算,确实很小,但是对程序运行完的数据test进行相同的计算,误差很大,只有速度U误差是10^(-3),其他两个V和P都是大于1的,从而说明应该是过拟合啦,这种情况应该怎么处理啊?

lululxvi commented 3 years ago

Then what about increasing num_domain further?

zxw4688 commented 3 years ago

具体结果为: image

zxw4688 commented 3 years ago
                 num_domain = 10000,
                 num_boundary = 100,
                 solution=true_fun,
                 num_test = 10000
lululxvi commented 3 years ago

The loss is small, which means the solution satisfies PDE and BC well, but the L2 error is large, so the network converges to another local minimum. Could you try what the solution the network found? Also, see FAQ how to use float64

zxw4688 commented 3 years ago

我发现错误了,我的边界条件给错了,应将:` def fun_u(x):

    return np.sin(x[:,0:1]-x[:,1:2])

def fun_v(x):

    return np.sin(x[:,0:1]-x[:,1:2])

geom = dde.geometry.Rectangle([0,0], [ 1, 1 ])
DBC_u = dde.DirichletBC(geom, fun_u, lambda _, on_boundary: on_boundary)
DBC_v = dde.DirichletBC(geom, fun_v, lambda _, on_boundary: on_boundary)`

修改为: `def fun_u(x):

    return np.sin(x[:,0:1]-x[:,1:2])

def fun_v(x):

    return np.sin(x[:,0:1]-x[:,1:2])

# boundary definition of a unit square domain

def boundary_l( x, on_boundary ):

    return on_boundary and np.isclose(x[0], 0 )

def boundary_r( x, on_boundary ):

    return on_boundary and np.isclose(x[0], 1 )

def boundary_upr( x, on_boundary ):

    return on_boundary and np.isclose(x[1], 1 )

def boundary_lwr( x, on_boundary ):

    return on_boundary and np.isclose(x[1], 0 )

geom = dde.geometry.Rectangle([0,0], [ 1, 1 ])

# defining BC for u, v, and p (component = 0, 1, 2 resp assign)

bc_lft_u = dde.DirichletBC(geom, fun_u, boundary_l, component = 0 )
bc_lft_v = dde.DirichletBC(geom, fun_v, boundary_l, component = 1 )

bc_r_u = dde.DirichletBC(geom, fun_u, boundary_r, component = 0 )
bc_r_v = dde.DirichletBC(geom, fun_v, boundary_r, component = 1 )

bc_lwr_u = dde.DirichletBC(geom, fun_u, boundary_lwr, component = 0 )
bc_lwr_v = dde.DirichletBC(geom, fun_v, boundary_lwr, component = 1 )

bc_upr_u = dde.DirichletBC(geom, fun_u, boundary_upr, component = 0 )
bc_upr_v = dde.DirichletBC(geom, fun_v, boundary_upr, component = 1 )`