lululxvi / deepxde

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

Question about dde.saveplot #623

Open chihaofang opened 2 years ago

chihaofang commented 2 years ago

I'm trying to solve the Black-Scholes pde but when I was in the part of dde.saveplot, I got an error about dimensions. The following is the code. `import matplotlib.pyplot as plt import numpy as np

import deepxde as dde from deepxde.backend import tf from scipy import sparse from scipy.sparse.linalg import splu

import scipy as scp import scipy.stats as ss from scipy import signal from scipy.integrate import quad import sympy; sympy.init_printing() from math import factorial from time import time`

` def pde(x, y): """ Expresses the PDE residual of the heat equation.
""" r = 0.1 sigma = 0.2 S0 = 100 K = 100 T = 1 x_min = np.log(K/3) x_max = np.log(3K) dy_x = dde.grad.jacobian(y, x, j=0) dy_t = dde.grad.jacobian(y, x, j=1) dy_xx = dde.grad.hessian(y, x, j=0) return dy_t + (r-(1/2)(sigma2))dy_x +0.5(sigma2)dy_xx-ry

def boundary_xl(x,on_boundary):

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

def boundary_xr(x,on_boundary):

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

def boundary_tr(x,on_boundary):
    T = 1
    return  np.isclose(x[1],T)

def func1(x):
    K=100
    return np.exp(x[:,0:1]) - K* np.exp(-r*(T-x[:,1:]))

def func2(x):
    K=100
    return np.maximum(np.exp(x[:,0:1])-K,0)`

The above are the pde and corresponding boundary conditions about the space and time.

` # Computational geometry: geom = dde.geometry.Interval(np.log(K/3), np.log(3*K)) timedomain = dde.geometry.TimeDomain(0, T) geomtime = dde.geometry.GeometryXTime(geom, timedomain)

# Boundary conditions:
bc_l = dde.icbc.DirichletBC(geomtime, lambda x:0, boundary_xl)
bc_r = dde.icbc.DirichletBC(geomtime, func1, boundary_xr)
bc_t = dde.icbc.DirichletBC(geomtime, func2, boundary_tr)

# Define the PDE problem and configurations of the network:
data = dde.data.TimePDE(
    geomtime, pde, [bc_l, bc_r,bc_t],  num_domain=2000,
num_boundary=200,
num_initial=1000

)
layer_size = [2] + [60] * 3 + [1]
activation = "tanh"
initializer = "Glorot uniform"
net = dde.maps.FNN(layer_size, activation, initializer)
model = dde.Model(data, net)

# Build and train the model:
model.compile("adam", lr=0.001)
losshistory, train_state = model.train(epochs=20000)

# Plot/print the results
dde.saveplot(losshistory, train_state, issave=True, isplot=True)`

The above are the network construction. However, I got the error message:

`ValueError Traceback (most recent call last)

in 29 30 # Plot/print the results ---> 31 dde.saveplot(losshistory, train_state, issave=True, isplot=True) ~/anaconda3/lib/python3.7/site-packages/deepxde/utils/external.py in saveplot(loss_history, train_state, issave, isplot, loss_fname, train_fname, test_fname, output_dir) 173 test_fname = os.path.join(output_dir, test_fname) 174 save_loss_history(loss_history, loss_fname) --> 175 save_best_state(train_state, train_fname, test_fname) 176 177 if isplot: ~/anaconda3/lib/python3.7/site-packages/deepxde/utils/external.py in save_best_state(train_state, fname_train, fname_test) 342 print("Saving test data to {} ...".format(fname_test)) 343 if y_test is None: --> 344 test = np.hstack((train_state.X_test, best_y)) 345 if best_ystd is None: 346 np.savetxt(fname_test, test, header="x, y_pred") <__array_function__ internals> in hstack(*args, **kwargs) ~/anaconda3/lib/python3.7/site-packages/numpy/core/shape_base.py in hstack(tup) 343 return _nx.concatenate(arrs, 0) 344 else: --> 345 return _nx.concatenate(arrs, 1) 346 347 <__array_function__ internals> in concatenate(*args, **kwargs) ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s) ` How can I fix this error? And another question. At the same time I got the training details: `Compiling model... Building feed-forward neural network... 'build' took 0.025377 s 'compile' took 0.255090 s Initializing variables... Training model... 0 [3.87e-02, 8.27e-02, 4.20e+04, nan][3.87e-02, 8.27e-02, 4.20e+04, nan][] Best model at step 0: train loss: inf test loss: inf test metric: 'train' took 0.220294 s` The train loss and test loss seems to be questionable, I wonder why I got this result. Thank you for your suggestion and help.
lululxvi commented 2 years ago

The error is due to nan. You may check why you get nan.

Wulx2050 commented 2 years ago

The error is due to nan. You may check why you get nan.

hi,lulu,可以在 dde.saveplot() 中加入 plt.figure(figsize=figsize) 中的 figsize 参数吗, 像这样dde.saveplot(losshistory, train_state, issave=True, isplot=True, figsize=(10,8)) 去使用它。这样方便在 jupyter notebook 中使用 plot,dde.saveplot()在notebook 中画出的图太小。 比如: https://github.com/lululxvi/deepxde/blob/master/examples/pinn_forward/heat_conduction_1d_uniform_bar.ipynb

这是一个修改 figsize 的例子: https://github.com/Wulx2050/DeepXDE-and-PINN/blob/main/4%E5%9B%9B%E5%A4%A7%E7%BA%BF%E6%80%A7%E5%81%8F%E5%BE%AE%E5%88%86%E6%96%B9%E7%A8%8B.ipynb

https://deepxde.readthedocs.io/en/latest/_modules/deepxde/utils/external.html#saveplot

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

def plot_loss_history(loss_history, figsize=(10, 8)):
    """Plot the training and testing loss history.

    Note:
        You need to call ``plt.show()`` to show the figure.

    Args:
        loss_history: ``LossHistory`` instance. The first variable returned from
            ``Model.train()``.
    """
    loss_train = np.sum(loss_history.loss_train, axis=1)
    loss_test = np.sum(loss_history.loss_test, axis=1)

    plt.figure(figsize=figsize)
    plt.semilogy(loss_history.steps, loss_train, label="Train loss")
    plt.semilogy(loss_history.steps, loss_test, label="Test loss")
    for i in range(len(loss_history.metrics_test[0])):
        plt.semilogy(
            loss_history.steps,
            np.array(loss_history.metrics_test)[:, i],
            label="Test metric",
        )
    plt.xlabel("Steps")
    plt.ylabel("loss")
    plt.legend()
    plt.show()

def plot_best_state(train_state, figsize=(10, 6)):
    """Plot the best result of the smallest training loss.

    This function only works for 1D and 2D problems. For other problems and to better
    customize the figure, use ``save_best_state()``.

    Note:
        You need to call ``plt.show()`` to show the figure.

    Args:
        train_state: ``TrainState`` instance. The second variable returned from
            ``Model.train()``.
    """
    if isinstance(train_state.X_train, (list, tuple)):
        print(
            "Error: The network has multiple inputs, and plotting such result han't been implemented."
        )
        return

    y_train, y_test, best_y, best_ystd = _pack_data(train_state)
    y_dim = best_y.shape[1]

    # Regression plot
    # 1D
    if train_state.X_test.shape[1] == 1:
        idx = np.argsort(train_state.X_test[:, 0])
        X = train_state.X_test[idx, 0]
        plt.figure(figsize=figsize)
        for i in range(y_dim):
            if y_train is not None:
                plt.plot(train_state.X_train[:, 0], y_train[:, i], "ok", label="Train")
            if y_test is not None:
                plt.plot(X, y_test[idx, i], "-k", label="True")
            plt.plot(X, best_y[idx, i], "--r", label="Prediction")
            if best_ystd is not None:
                plt.plot(
                    X, best_y[idx, i] + 2 * best_ystd[idx, i], "-b", label="95% CI"
                )
                plt.plot(X, best_y[idx, i] - 2 * best_ystd[idx, i], "-b")
        plt.xlabel("x")
        plt.ylabel("y")
        plt.legend()
    # 2D
    elif train_state.X_test.shape[1] == 2:
        for i in range(y_dim):
            plt.figure(figsize=tuple([i*2 for i in figsize]))
            ax = plt.axes(projection=Axes3D.name)
            ax.plot3D(
                train_state.X_test[:, 0],
                train_state.X_test[:, 1],
                best_y[:, i],
                ".",
            )
            ax.set_xlabel("$x_1$")
            ax.set_ylabel("$x_2$")
            ax.set_zlabel("$y_{}$".format(i + 1))

    plt.show()
lululxvi commented 2 years ago

If you are interested, welcome to submit a PR.

mfdys-tt commented 1 year ago

I'm trying to solve the Black-Scholes pde but when I was in the part of dde.saveplot, I got an error about dimensions. The following is the code. `import matplotlib.pyplot as plt import numpy as np

import deepxde as dde from deepxde.backend import tf from scipy import sparse from scipy.sparse.linalg import splu

import scipy as scp import scipy.stats as ss from scipy import signal from scipy.integrate import quad import sympy; sympy.init_printing() from math import factorial from time import time`

` def pde(x, y): """ Expresses the PDE residual of the heat equation. """ r = 0.1 sigma = 0.2 S0 = 100 K = 100 T = 1 x_min = np.log(K/3) x_max = np.log(3_K) dy_x = dde.grad.jacobian(y, x, j=0) dy_t = dde.grad.jacobian(y, x, j=1) dy_xx = dde.grad.hessian(y, x, j=0) return dyt + (r-(1/2)(sigma2))_dyx +0.5(sigma2)_dy_xx-r_y

def boundary_xl(x,on_boundary):

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

def boundary_xr(x,on_boundary):

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

def boundary_tr(x,on_boundary):
    T = 1
    return  np.isclose(x[1],T)

def func1(x):
    K=100
    return np.exp(x[:,0:1]) - K* np.exp(-r*(T-x[:,1:]))

def func2(x):
    K=100
    return np.maximum(np.exp(x[:,0:1])-K,0)`

The above are the pde and corresponding boundary conditions about the space and time.

` # Computational geometry: geom = dde.geometry.Interval(np.log(K/3), np.log(3*K)) timedomain = dde.geometry.TimeDomain(0, T) geomtime = dde.geometry.GeometryXTime(geom, timedomain)

# Boundary conditions:
bc_l = dde.icbc.DirichletBC(geomtime, lambda x:0, boundary_xl)
bc_r = dde.icbc.DirichletBC(geomtime, func1, boundary_xr)
bc_t = dde.icbc.DirichletBC(geomtime, func2, boundary_tr)

# Define the PDE problem and configurations of the network:
data = dde.data.TimePDE(
    geomtime, pde, [bc_l, bc_r,bc_t],  num_domain=2000,
num_boundary=200,
num_initial=1000

)
layer_size = [2] + [60] * 3 + [1]
activation = "tanh"
initializer = "Glorot uniform"
net = dde.maps.FNN(layer_size, activation, initializer)
model = dde.Model(data, net)

# Build and train the model:
model.compile("adam", lr=0.001)
losshistory, train_state = model.train(epochs=20000)

# Plot/print the results
dde.saveplot(losshistory, train_state, issave=True, isplot=True)`

The above are the network construction. However, I got the error message:

`ValueError Traceback (most recent call last) in 29 30 # Plot/print the results ---> 31 dde.saveplot(losshistory, train_state, issave=True, isplot=True)

~/anaconda3/lib/python3.7/site-packages/deepxde/utils/external.py in saveplot(loss_history, train_state, issave, isplot, loss_fname, train_fname, test_fname, output_dir) 173 test_fname = os.path.join(output_dir, test_fname) 174 save_loss_history(loss_history, loss_fname) --> 175 save_best_state(train_state, train_fname, test_fname) 176 177 if isplot:

~/anaconda3/lib/python3.7/site-packages/deepxde/utils/external.py in save_best_state(train_state, fname_train, fname_test) 342 print("Saving test data to {} ...".format(fname_test)) 343 if y_test is None: --> 344 test = np.hstack((train_state.X_test, best_y)) 345 if best_ystd is None: 346 np.savetxt(fname_test, test, header="x, y_pred")

<array_function internals> in hstack(*args, **kwargs)

~/anaconda3/lib/python3.7/site-packages/numpy/core/shape_base.py in hstack(tup) 343 return _nx.concatenate(arrs, 0) 344 else: --> 345 return _nx.concatenate(arrs, 1) 346 347

<array_function internals> in concatenate(*args, **kwargs)

ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s) ` How can I fix this error?

And another question. At the same time I got the training details: `Compiling model... Building feed-forward neural network... 'build' took 0.025377 s

'compile' took 0.255090 s

Initializing variables... Training model...

0 [3.87e-02, 8.27e-02, 4.20e+04, nan][3.87e-02, 8.27e-02, 4.20e+04, nan][]

Best model at step 0: train loss: inf test loss: inf test metric:

'train' took 0.220294 s`

The train loss and test loss seems to be questionable, I wonder why I got this result.

Thank you for your suggestion and help.

have you solved your problem?