lululxvi / deepxde

A library for scientific machine learning and physics-informed learning
https://deepxde.readthedocs.io
GNU Lesser General Public License v2.1
2.5k stars 715 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 3 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()`

lululxvi commented 3 years ago

If you are not familiar enough Python/numpy, a better way could be that you generate the dateset using Matlab, and then use DeepXDE to learn. See an example dataset.py, col_x is the columns that the input variables, and col_y is the output column.

zxw4688 commented 3 years ago

Hello @lululxvi , Thank you very much for your reply, I have read the example dataset.py, but I can not understand which function is fitted in the code. And I try to revised it so that it can fit the function f(x,t)=sin(x)sin(t), both x and t are in [0,1]. And the error happened, can you help me how to revise it. Thank you very much!The error of my code is:` File "E:\DNN_matlab\myrebp\solve_PDE_0811\DeepXDE\deepxde-master\examples\my_example_0819\try_FNN_0824_2.py", line 51, in main()

File "E:\DNN_matlab\myrebp\solve_PDE_0811\DeepXDE\deepxde-master\examples\my_example_0819\try_FNN_0824_2.py", line 29, in main data = dde.data.DataSet(

File "D:\ProgramData\envs\tensorflow\lib\site-packages\deepxde\data\dataset.py", line 35, in init train_data = np.loadtxt(fname_train)

File "D:\ProgramData\envs\tensorflow\lib\site-packages\numpy\lib\npyio.py", line 981, in loadtxt fh = np.lib._datasource.open(fname, 'rt', encoding=encoding)

File "D:\ProgramData\envs\tensorflow\lib\site-packages\numpy\lib_datasource.py", line 269, in open return ds.open(path, mode, encoding=encoding, newline=newline)

File "D:\ProgramData\envs\tensorflow\lib\site-packages\numpy\lib_datasource.py", line 623, in open raise IOError("%s not found." % path)

OSError: dataset/dataset.train not found.`

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(): fname_train = "dataset/dataset.train" fname_test = "dataset/dataset.test" 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])

以上是构造出meshgrid形式的数据

#构造标签并加入误差扰动
Label_data=np.sin(X)*np.sin(T)
noise_data=0.02*tf.random.normal(shape=[Nx*Nt])
Label_data=Label_data+noise_data
data = dde.data.DataSet(
    fname_train=fname_train,
    fname_test=fname_test,

    col_x=Input_data,
    col_y=Label_data,
    standardize=True,
)

layer_size = [1] + [50] * 3 + [1]
activation = "tanh"
initializer = "Glorot normal"
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=50000)

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

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

lululxvi commented 3 years ago
data = dde.data.DataSet(
    fname_train=fname_train,
    fname_test=fname_test,
    col_x=...,
    col_y=...,
    standardize=True,
)

Here, fname_train and fname_test are the files of training and testing data, you can look at the files in the examples folder. col_x is the column number of the inputs (x, t), and col_y is the column number of output (y).

zxw4688 commented 3 years ago

不好意思,我还是用中文和你交流吧。我的意思是我不知道你的这个程序dataset.py拟合的是哪一个函数的,也就是真实函数是哪一个。另外,我打开你的数据dataset.test和dataset.train看了,和我的想法是类似的,只不过我这里给出的数据是由[0,1]生成的, 一行一行的, 我现在加入转置把它改为列的形式了,但是还是运行不了,麻烦你帮我看一下,谢谢!,错误为: image

代码为:`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])

以上是构造出meshgrid形式的数据

#构造标签并加入误差扰动
Label_data=np.sin(X)*np.sin(T)
noise_data=0.02*tf.random.normal(shape=[Nx*Nt])
Label_data=Label_data+noise_data
data = dde.data.DataSet(
    col_x=np.transpose(Input_data),
    col_y=np.transpose(Label_data),
    standardize=True,
)

layer_size = [1] + [50] * 3 + [1]
activation = "tanh"
initializer = "Glorot normal"
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=50000)

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

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

lululxvi commented 3 years ago

I don't remember what is the exact function. You can plot it.

The example is for using data file. If you want to pass the numpy array, use the following:

data = dde.data.DataSet(X_train=..., y_train=..., X_test=..., y_test=...,)
zxw4688 commented 3 years ago

LuLu 博士,你好! 我认为代码应该很简单,就是一个数据输入问题,但是我怎么就搞不定呢,你能不帮我改一下,我改过了测试集和训练集为同一个, 这里只是为了验证结果,使得代码可以运行而已。麻烦你帮我看一下,非常感谢!,代码入下: 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])

以上是构造出meshgrid形式的数据

#构造标签并加入误差扰动
Label_data=np.sin(X)*np.sin(T)
noise_data=0.02*tf.random.normal(shape=[Nx*Nt])
Label_data=Label_data+noise_data
data = dde.data.DataSet(
    X_train=np.transpose(Input_data),
    y_train=np.transpose(Label_data),
    X_test=X_train,
    y_test=y_train,        
    standardize=True,
)

layer_size = [1] + [50] * 3 + [1]
activation = "tanh"
initializer = "Glorot normal"
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=50000)

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

if name == "main": main()

lululxvi commented 3 years ago
data = dde.data.DataSet(
    X_train=np.transpose(Input_data),
    y_train=np.transpose(Label_data),
    X_test=np.transpose(Input_data),
    y_test=np.transpose(Label_data),        
    standardize=True,
)

Make sure np.transpose(Input_data) is N x 2 and np.transpose(Label_data) is N x 1.

zxw4688 commented 3 years ago

这个没有问题啊,确实np.transpose(Input_data)是两列的,np.transpose(Label_data)确实是一列的。

lululxvi commented 3 years ago
X_test=np.transpose(Input_data),
y_test=np.transpose(Label_data),        
zxw4688 commented 3 years ago

I have revised it as you said, but it can not run. The error is NotImplementedError: Cannot convert a symbolic Tensor (add_15:0) to a numpy array. This error may indicate that you're trying to pass a Tensor to a NumPy call, which is not supported. and 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])

以上是构造出meshgrid形式的数据

#构造标签并加入误差扰动
Label_data=np.sin(X)*np.sin(T)
noise_data=0.02*tf.random.normal(shape=[Nx*Nt])
Label_data=Label_data+noise_data
data = dde.data.DataSet(
    X_train=np.transpose(Input_data),
    y_train=np.transpose(Label_data),
    X_test=np.transpose(Input_data),
    y_test=np.transpose(Label_data),        
    standardize=True,
)

layer_size = [1] + [50] * 3 + [1]
activation = "tanh"
initializer = "Glorot normal"
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=50000)

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

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

lululxvi commented 3 years ago

noise_data=0.02*tf.random.normal(shape=[Nx*Nt]): use np here, not tf

zxw4688 commented 3 years ago

I have revised it and the error is : TypeError: normal() got an unexpected keyword argument 'shape'

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])

以上是构造出meshgrid形式的数据

#构造标签并加入误差扰动
Label_data=np.sin(X)*np.sin(T)
noise_data=0.02*np.random.normal(shape=[Nx*Nt])
Label_data=Label_data+noise_data
data = dde.data.DataSet(
    X_train=np.transpose(Input_data),
    y_train=np.transpose(Label_data),
    X_test=np.transpose(Input_data),
    y_test=np.transpose(Label_data),        
    standardize=True,
)

layer_size = [1] + [50] * 3 + [1]
activation = "tanh"
initializer = "Glorot normal"
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=50000)

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

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

lululxvi commented 3 years ago

Check online to how to use np.random.normal

zxw4688 commented 3 years ago

I have revised the use of np.random.normal, but the error is : ValueError: Cannot feed value of shape (121, 2) for Tensor 'Placeholder_23:0', which has shape '(?, 1)' 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])

以上是构造出meshgrid形式的数据

#构造标签并加入误差扰动
Label_data=np.sin(X)*np.sin(T)
noise_data=0.02*np.random.normal(0.0, 1.0, Nx*Nt)
Label_data=Label_data+noise_data
data = dde.data.DataSet(
    X_train=np.transpose(Input_data),
    y_train=np.transpose(Label_data),
    X_test=np.transpose(Input_data),
    y_test=np.transpose(Label_data),        
    standardize=True,
)

layer_size = [1] + [50] * 3 + [1]
activation = "tanh"
initializer = "Glorot normal"
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=50000)

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

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

zxw4688 commented 3 years ago

同时,我也用np.shape()检查过了,X_train=np.transpose(Input_data), X_test=np.transpose(Input_data), y_test=np.transpose(Label_data), y_train=np.transpose(Label_data), 分别是1212 ,1212, 1211,1211。这个没有问题啊! 但是程序还是出错,不知道错在那里,麻烦LuLu博士帮忙看一下,非常感谢!

zxw4688 commented 3 years ago

121x2 ,121x2, 1x211,1x211

lululxvi commented 3 years ago

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

zxw4688 commented 3 years ago

LuLu博士,你好!, 我改过了,还是有错,错误为:` File "E:\DNN_matlab\myrebp\solve_PDE_0811\DeepXDE\deepxde-master\examples\my_example_0819\try_FNN_0824_2.py", line 48, in main()

File "E:\DNN_matlab\myrebp\solve_PDE_0811\DeepXDE\deepxde-master\examples\my_example_0819\try_FNN_0824_2.py", line 42, in main losshistory, train_state = model.train(epochs=50000)

File "D:\ProgramData\envs\tensorflow\lib\site-packages\deepxde\utils.py", line 52, in wrapper result = f(*args, **kwargs)

File "D:\ProgramData\envs\tensorflow\lib\site-packages\deepxde\model.py", line 146, in train self._test(uncertainty)

File "D:\ProgramData\envs\tensorflow\lib\site-packages\deepxde\model.py", line 254, in _test self.train_state.loss_train, self.train_state.y_pred_train = self.sess.run(

File "D:\ProgramData\envs\tensorflow\lib\site-packages\tensorflow\python\client\session.py", line 957, in run result = self._run(None, fetches, feed_dict, options_ptr,

File "D:\ProgramData\envs\tensorflow\lib\site-packages\tensorflow\python\client\session.py", line 1154, in _run raise ValueError(

ValueError: Cannot feed value of shape (121,) for Tensor 'Placeholder_49:0', which has shape '(?, 1)'`

我的code为: 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])

以上是构造出meshgrid形式的数据

#构造标签并加入误差扰动
Label_data=np.sin(X)*np.sin(T)
noise_data=0.02*np.random.normal(0.0, 1.0, Nx*Nt)
Label_data=Label_data+noise_data
data = dde.data.DataSet(
    X_train=np.transpose(Input_data),
    y_train=np.transpose(Label_data),
    X_test=np.transpose(Input_data),
    y_test=np.transpose(Label_data),        
    standardize=True,
)

layer_size = [2] + [50] * 3 + [1]
activation = "tanh"
initializer = "Glorot normal"
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=50000)

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

if name == "main": main()

lululxvi commented 3 years ago

np.transpose(Label_data) should be 121x1, not 1x121.

zxw4688 commented 3 years ago

这下我修改了,数据维度显示为: image 但是任然说数据维度有错误啊! 我的代码为: `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.transpose(np.array([X,T]))

以上是构造出meshgrid形式的数据

#构造标签并加入误差扰动
Label_data=np.sin(X)*np.sin(T)
noise_data=0.2*np.random.normal(0.0, 1.0, Nx*Nt)
Label_data=np.transpose(Label_data+noise_data)
print(np.shape(Input_data))
print(np.shape(Label_data))
data = dde.data.DataSet(
    X_train=Input_data,
    y_train=Label_data,
    X_test=Input_data,
    y_test=Label_data,        
    standardize=True,
)

layer_size = [2] + [50] * 3 + [1]
activation = "tanh"
initializer = "Glorot normal"
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=50000)

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

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

lululxvi commented 3 years ago

(121, ) is 1-d array. It should be 2-d array of size (121, 1)

zxw4688 commented 3 years ago

哦,那应该怎么改啊!

zxw4688 commented 3 years ago

我知道,用一个reshape(121,1)就可以啦,现在可以运行啦!谢谢LuLu博士的耐心帮助!

zxw4688 commented 3 years ago

怎么训练过程中当数据增加时,训练误差就不会下降,一直保持不变!比如对x轴和时间t轴取离散点均为201个点,则训练集共有201x201个点,进行训练,结果为: image ,这个时为什么啊?感觉怪怪的,和我用matlab训练的时候不一样。 我的代码为: `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=201 Nt=201 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.transpose(np.array([X,T]))

以上是构造出meshgrid形式的数据

#构造标签并加入误差扰动
Label_data=np.sin(X)*np.sin(T)
noise_data=0.2*np.random.normal(0.0, 1.0, Nx*Nt)
Label_data=np.transpose(Label_data+noise_data)
Label_data=Label_data.reshape(Nx*Nt,1)
print(np.shape(Input_data))
print(np.shape(Label_data))
data = dde.data.DataSet(
    X_train=Input_data,
    y_train=Label_data,
    X_test=Input_data,
    y_test=Label_data,        
    standardize=True,
)

layer_size = [2] + [100] * 3 + [1]
activation = "tanh"
initializer = "Glorot normal"
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=50000)

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

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

lululxvi commented 3 years ago

It is only 4000 steps. There is nothing wrong. Just try more iterations.

zxw4688 commented 3 years ago

I have performed it run the whole proccess, but all error of train have no descent, keep a constant value, how to explain the phenomenon , and the result is : image and image

lululxvi commented 3 years ago

Try different activation like relu, larger network, smaller learning rate

zxw4688 commented 3 years ago

Thank you very much! I am trying it! But I think the result will not change much! Because I have add noise_data to realistic value, and their errors are not over 0.1, then the training error is not more than 0.1. In my view, the training error will not be over the error of noisy data and realistic value. However, I can not explain the l2 relative error, What do you think?

lululxvi commented 3 years ago

You noise may be too large.

zxw4688 commented 3 years ago

I have get the result as follow, and it is not good , the l2 relative error keep a constant value. I performed layer_size = [2] + [50] * 6 + [1], and the learning rate is ` activation = "relu" initializer = "Glorot normal" net = dde.maps.FNN(layer_size, activation, initializer)

model = dde.Model(data, net)
model.compile("adam", lr=0.00001, metrics=["l2 relative error"])
losshistory, train_state = model.train(epochs=50000)

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

the result is image 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=101 Nt=101 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.transpose(np.array([X,T]))

以上是构造出meshgrid形式的数据

#构造标签并加入误差扰动
Label_data=np.sin(X)*np.sin(T)
noise_data=0.1*np.random.normal(0.0, 1.0, Nx*Nt)
Label_data=np.transpose(Label_data+noise_data)
Label_data=Label_data.reshape(Nx*Nt,1)
print(np.shape(Input_data))
print(np.shape(Label_data))
data = dde.data.DataSet(
    X_train=Input_data,
    y_train=Label_data,
    X_test=Input_data,
    y_test=Label_data,        
    standardize=True,
)

layer_size = [2] + [50] * 6 + [1]
activation = "relu"
initializer = "Glorot normal"
net = dde.maps.FNN(layer_size, activation, initializer)

model = dde.Model(data, net)
model.compile("adam", lr=0.00001, metrics=["l2 relative error"])
losshistory, train_state = model.train(epochs=50000)

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

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

lululxvi commented 3 years ago

Try even smaller noise

zxw4688 commented 3 years ago

You are right, I obtain relatively good result by smaller noise and no noise. But the l2 relative error is near 0.001.

zxw4688 commented 3 years ago

Hello @lululxvi I used FNN in Deepxde to fit the functions f(x,t)=sin(x)*sin(t), and both x and t are in interval [0,1]. I made it, but x and t in the figure of fitted function are in interval [-1.5,1.5]. I would like to know why? . Thank you very much! The fitted result and the code are : image

And the 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(): def pde(x, y): dy_x = tf.gradients(y, x)[0] dy_x, dy_t = dy_x[:, 0:1], dy_x[:, 1:] dy_xx = tf.gradients(dy_x, x)[0][:, 0:1] dy_xxx = tf.gradients(dy_xx, x)[0][:, 0:1] return ( dy_t + ydy_x +0.0025dy_xxx -0.5tf.sin(2x[:, 0:1])*(tf.sin(x[:, 1:]))*2 +0.0025tf.cos(x[:, 0:1])tf.sin(x[:, 1:]) -tf.sin(x[:, 0:1])tf.cos(x[:, 1:]) )

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

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

bc = dde.DirichletBC(geomtime, func, lambda _, on_boundary: on_boundary)
ic = dde.IC(geomtime, func, lambda _, on_initial: on_initial)
data = dde.data.TimePDE(
    geomtime,
    pde,
    [bc, ic],
    num_domain=400,
    num_boundary=200,
    num_initial=100,
    solution=func,
    num_test=1000,
)

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()

lululxvi commented 3 years ago

It is normalized to mean 0 variance 1. Use standardize=False to un-normalize

zxw4688 commented 3 years ago

Meanwhile, I changed the interval [0,1]x[0,1] to [-pi, pi]x[0,1], but x and t in the figure of fitted function still are in interval [-1.5,1.5]. The figure is:

image

zxw4688 commented 3 years ago

Thank you very much! In fact, I had thought it. Thanks a lot !

zxw4688 commented 3 years ago

hello @lululxvi , Thank you very much for your big patience to solve my problem in my learning package Deepxde. I love it very much. Therefore, I would like to understand all of it. I have some questions to require you about it and it's referrence. Q1. how to obtain the function value of FNN in X_train or other new input data. Q2、In solving the inverse problem, I want to know what observe_y and observe_x are, and they are related to the expression I(u,x) in 2.7 of the paper "A deep learning library for solving differential equations", image and image ,here,
image is label related to the input x, how to understant.

zxw4688 commented 3 years ago

Q3、I have done it to obtain the partial derivative of FNN(x) on x as you told to me yesterday, but some error happened as follow, image And 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=101 Nt=101 Xx=np.linspace(-np.pi,np.pi,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.transpose(np.array([X,T]))

以上是构造出meshgrid形式的数据

#构造标签并加入误差扰动
Label_data=np.sin(X)*np.sin(T)
#noise_data=0.1*np.random.normal(0.0, 1.0, Nx*Nt)
#Label_data=np.transpose(Label_data+noise_data)
Label_data=Label_data.reshape(Nx*Nt,1)
print(np.shape(Input_data))
print(np.shape(Label_data))
data = dde.data.DataSet(
    X_train=Input_data,
    y_train=Label_data,
    X_test=Input_data,
    y_test=Label_data,        
    standardize=False,
)

layer_size = [2] + [10] * 6 + [1]
activation = "relu"
initializer = "Glorot normal"
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=50000)
model.train(epochs=50000)
dde.saveplot(losshistory, train_state, issave=True, isplot=True)
def f(x,y):
    dy=tf.gradients(y,x)[0]                     
    dy_x,dy_t=dy[:,0:1],dy[:,1:]
    dy_xx=tf.gradients(dy_x,x)[0][:,0:1]                
    return dy_x,dy_xx
 Dx,Dxx= model.predict(Input_data, operator=f)

if name == "main": main()

lululxvi commented 3 years ago
  1. See "Q: How can I use a trained model for new predictions?" at FAQ.
  2. observe_y and observe_x are observation data. See my talk video and slides at the homepage.
  3. You indent is wrong. There is an extra empty space before Dx,Dxx
zxw4688 commented 3 years ago

非常感谢lulu博士的快速准确耐心的回答, 我想知道你的observation data包含边界点吗,还是仅有内部点,还是说两个都要有? 从你的文章里,应该来说就是一个数据拟合需要的训练集啊,无所谓内部与边界,不知道我理解对不对? 再次感谢lulu博士。

lululxvi commented 3 years ago

You are right. It is totally your choice.

zxw4688 commented 3 years ago

Hello @lululxvi 1、我有个关于神经网络训练集,测试集,验证集的关系问题,我的理解:训练的NN函数决定于训练集,测试集主要是决定训练出来的这么多NN函数中选择一个适合测试集的,而验证集主要是应用所得的NN函数。不知到我理解的对不对啊? 2、对数据拟合我做了一个点数较少的,但是我发现,用你的Packagea画出的函数图像测试集的输入对应的NN函数的图像啊,怎么不是训练集的。 我的代码和图像为: `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

首先进行DNN函数的数据拟合

给出符合Deepxde所需的数据格式:Nd_in,Nd_out

def data_input1(Nx,Nt,Lx,Rx,Lt,Rt): xx=np.linspace(Lx,Rx,Nx) tt=np.linspace(Lt,Rt,Nt) X,T=np.meshgrid(xx,tt) X=np.reshape(X,[NxNt,1]) T=np.reshape(T,[NxNt,1]) XT=np.concatenate((X,T),1)

print(XT,np.shape(XT))

return X,T,XT

开始构造训练集,输入和标签

Nx=11 Nt=11 X,T,Input_data=data_input1(Nx,Nt,0,1,0,1)

Y_T=np.sin(X)np.sin(T) Y_T=Y_T.reshape(NxNt,1)

构造输入标签

Label_data=Y_T #+0.1np.random.normal(0.0, 1.0, [NxNt,1])

开始构造测试集

tNx=5 tNt=5 tX,tT,tInput_data=data_input1(tNx,tNt,0.2,0.9,0.3,0.9) tLabel_data=np.sin(tX)np.sin(tT) tLabel_data=tLabel_data.reshape(tNxtNt,1) #+0.1np.random.normal(0.0, 1.0, [tNxtNt,1])

数据导入

data = dde.data.DataSet( X_train=Input_data, y_train=Label_data, X_test=tInput_data, y_test=tLabel_data,
standardize=False ) layer_size = [2] + [32] * 3 + [1] activation = "tanh" initializer = "Glorot normal" 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)` image

zxw4688 commented 3 years ago

另外我用matlab自带的NN函数和你的比较,我发现只要训练次数足够多,比如超过500以上,matlab相对误差更小 我的matlab代码及其结果发你邮箱啦,但是我感觉怪怪,可是又说不出什么原因。 第一个函数: function XT=D1_space_time_combine_0831_1(Xx,Tt) %将一组时空坐标按照一个时刻一个时刻的坐标放在一起组成一个两行的矩阵, %使得该矩阵的每一列刚好是一个时空坐标点 %这里主要使用了matlab自带的kron函数 %kron(A,B)=A(i,j)*B Nt=length(Tt);%时间t离散点Tt的长度 Nx=length(Xx);%空间x离散点Xx的长度 At=ones(1,Nt); X=kron(At,Xx);%一个时刻一个时刻存放空间x离散点Xx Ax=ones(1,Nx); T=kron(Tt,Ax);%一个空间x离散点Xx的长度对应一个时刻点 XT=[X;T]; end 第二个函数 function RU=compute_real_solve_0831_1(a,b,c,d,M,N,u) %计算函数二元函数u在区间[a,b]x[c,d]取MxN个点的函数值 Mx=M; Nt=N; Xx=linspace(a,b,Mx); Tt=linspace(c,d,Nt); %将上述时空坐标(Xx,Tt)按照一个时刻一个时刻的坐标放在一起组成一个两行的矩阵. X=D1_space_time_combine_0831_1(Xx,Tt); X1=X(1,:); T1=X(2,:); syms x t real; uu=inline(u,'x','t'); U=uu(X1,T1); RU=U; end 第三个函数: function [net,WT,bT,Result_error_1]=DNN_WB_ER_0831_1(X,T,hiddenSizes,RU,fsig,train_fun) %本函数主要是用来训练全连接的神经网络 %X表示训练集中的输入向量; %T表示训练集中的label标签 %hiddenSizes是一个向量表示隐藏层的层数及其神经元的个数 %RU为计算误差所需的真值 %fsig为激活函数的表示符,用于matlab隐藏层的激活函数的设置 %WT表示训练完成后全连接神经网络的权重矩阵 %bT表示训练完成后全连接神经网络的偏置向量 %Result_error_1表示训练完成后全连接神经网络的L2误差和最大模误差 net = feedforwardnet(hiddenSizes);% 创建前向网络 %view(net); NL=length(hiddenSizes); %权重和偏置的初始化 for k=1:NL+1 net.layers{k}.initFcn = 'initnw';%初始化各层上使用的初始函数 end %初始化输入层到隐藏层上权重和偏置 net.inputWeights{1,1}.initFcn = 'rands'; net.biases{1,1}.initFcn = 'rands'; %初始化隐藏层到隐藏层上权重和偏置 for k=1:NL net.inputWeights{k}.initFcn = 'rands'; net.biases{k}.initFcn = 'rands'; end %初始化隐藏层到输出层上权重和偏置 net.inputWeights{NL,1}.initFcn = 'rands'; net.biases{NL,1}.initFcn = 'rands'; %net = init(net); for i=1:length(hiddenSizes) % net.layers{i}.transferFcn = 'logsig'; % net.layers{i}.transferFcn = 'tansig'; % net.layers{i}.transferFcn = 'poslin'; net.layers{i}.transferFcn =fsig; end %总体而言, %traingda---自适应调整学习率的梯度下降反向传播算法训练函数; %trainlm--- 中型网络,,内存需求最大,收敛速度最快 % trainbfg---BFGS算法(拟牛顿反向传播算法)训练函数; % traingdx---自适应调整学习率并附加动量因子的梯度下降反向传播算法训练函数; % trainc---以学习函数依次对输入样本进行训练的函数;(太慢) %trainr---以学习函数随机对输入样本进行训练的函数. %以上这几种方法较好。 net.trainParam.epochs=10000; net.trainParam.lr=0.005; net.trainParam.goal=1e-9; net.trainFcn =train_fun; net.trainParam.min_grad=1e-9; net.performParam.regularization = 0; net = train(net,X,T); % 训练,确定输入输出向量的维度 Y=sim(net,X); % 计算预测值 %给出训练好的神经网络的权重和偏置 AW=net.LW;%找出隐藏层上的权重矩阵,其大小为输出到输入。第一个权重矩阵为隐藏层到隐藏层,最后一个为输出层到隐藏层。 AW(cellfun(@isempty,AW))=[];%去掉空数组 AIW=net.IW;%找出输入层上的权重,即从第一个隐藏层到输入层的权重矩阵 AIW(cellfun(@isempty,AIW))=[];%去掉空数组 AB=cell(1);%建立输入层上空权重矩阵和偏置 Bb=net.b';%找出各层上偏置向量 WT=[AB,AIW,AW];%整个DNN的权重矩阵 bT=[AB,Bb];%整个DNN的偏置向量 %求出MSE(均方差); [~,N]=size(X);%训练集的样本点数 Loss_L2=vpa(sqrt(sum((RU-Y).^2)/N));%误差的L2模 % Loss_cost1=vpa(sum((RU-Y).^2)/(2*Mx*Nt),9); Loss_Max1=vpa(max(abs(RU-Y)));%误差的最大模 relative_err=norm(RU-Y)/norm(RU); Result_error_1=vpa([N,Loss_L2,Loss_Max1,relative_err],9);%N为训练集的样本点数 end 主程序代码为: clear; Nx=11; Nt=11; a=0; b=1; c=0; d=1; Xx=linspace(a,b,Nx); Tt=linspace(c,d,Nt); XT=D1_space_time_combine_0831_1(Xx,Tt); X=XT;%训练集的输入值 syms x t real; u=sin(x)*sin(t);%拟合数据对应真实函数 RU=compute_real_solve_0831_1(a,b,c,d,Nx,Nt,u); aa=-1; bb=1; ha=1; n=1; hx=1/(Nx-1); T=RU;%+(hx^(n*ha))*sign(aa+(bb-aa)*rand(size(RU)));%训练集的标签 fsig='tansig';%激活函数 hiddenSizes=[10];%hiddenSizes为行向量,为隐藏层的层数及其神经元的数目 train_fun='trainlm'; [net,WT,bT,Result_error_1]=DNN_WB_ER_0831_1(X,T,hiddenSizes,RU,fsig,train_fun) 计算结果为: image 训练过程为: image

zxw4688 commented 3 years ago

matlab代码发到你邮箱:lu_lu_1@brown.edu 非常感谢!

lululxvi commented 3 years ago
  1. It seems that your understanding of test set and validation set is in a opposite way.
  2. In DeepXDE, we only use two sets: training and testing.
  3. The plot is for test set. You can also plot the datasets using the saved data files.
  4. Unfortunately, I don't have any experience on Matlab neural network.
zxw4688 commented 3 years ago

Hello @lululxvi 我想知道训练集和测试集的作用是什么,测试集参与修改权重和偏置了吗?应该没有吧,权重和偏置主要是由训练集来决定吧,所以我很是糊涂这里,训练集和测试集的作用,麻烦帮忙解释一下,非常感谢! 另外,为什么你的图像只针对测试集呢,这里有没有要表达什么?我的理解图像应该画训练集的。而且测试集的样本数量应该要比训练集少,而你的软件例子中,反而测试集的点数多于了训练集,这个我不是很理解,谢谢!

lululxvi commented 3 years ago
zxw4688 commented 3 years ago

Hello @lululxvi 我用你的Package求解了一个Stokes方程: image 但是得出的结果感觉不对啊,怎么L2的相对误差几乎是接近于1, 具体的结果如下: image

具体的代码为: `

-- coding: utf-8 --

""" Created on Fri Sep 4 01:10:20 2020

@author: Administrator """ from future import absolute_import from future import division from future import print_function

import numpy as np

from tensorflow.keras.backend import set_floatx

import sys sys.path.insert( 0, "E:/DNN_matlab/myrebp/solve_PDE_0811/DeepXDE/deepxde-master")

import deepxde as dde

import tensorflow as tf

def main(): set_floatx("float64")

beta=1.0
eps = 1e-8

def pde( x, y ):

    u, v, p = y[:, 0:1], y[:, 1:2 ], y[:, 2:3]

    u_x = tf.gradients( u , x )[0]
    v_x = tf.gradients( v , x )[0]
    p_x = tf.gradients( p , x )[0]

    dp_x, dp_y = p_x[:, 0:1 ], p_x[:, 1:2 ]

    du_x, du_y = u_x[:, 0:1], u_x[:, 1:2 ]

    dv_x, dv_y = v_x[:, 0:1], v_x[ :, 1:2 ]

    Bdu_xx = tf.gradients( beta*du_x, x )[0][:, 0:1 ]
    Bdu_yy = tf.gradients( beta*du_y, x )[0][:, 1:2 ]

    Bdv_xx = tf.gradients( beta*dv_x, x)[0][:, 0:1 ]
    Bdv_yy = tf.gradients( beta*dv_y, x)[0][:, 1:2 ]

    f1=tf.exp(x[:,0:1])*tf.cos(x[:,1:2])+2*beta*tf.sin(x[:,0:1]-x[:,1:2])
    f2=-tf.exp(x[:,0:1])*tf.sin(x[:,1:2])+2*beta*tf.sin(x[:,0:1]-x[:,1:2])

    return [-( Bdu_xx + Bdu_yy ) + dp_x - f1,
            -( Bdv_xx + Bdv_yy ) + dp_y - f2,
            du_x + dv_y - eps*y[:,2:3] ]

# function definition 

realistic solution

def true_fun(x):
    """
    y1 = sin(x-y) notes u 
    y2 = sin(x-y) notes v 
    y3=exp(x)*cos(y) notes p 
    """
    return np.hstack((np.sin(x[:,0:1]-x[:,1:2]), np.sin(x[:,0:1]-x[:,1:2]), np.exp(x[:,0:1])*np.cos(x[:,1:2])))

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)

data = dde.data.PDE(
                 geom,
                 pde,
                 [DBC_u,DBC_v],
                 num_domain = 1000,
                 num_boundary = 500,
                 solution=true_fun,
                 num_test = 3000
               )

layer_size = [2] + [50] * 3 + [3]
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=20000)

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

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

zxw4688 commented 3 years ago

麻烦LuLu博士有空的时候,帮我看看!非常感谢!

lululxvi commented 3 years ago

Try: num_domain = 10000