lululxvi / deepxde

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

Can't get ideal solution though loss is low when solve ode problem #608

Closed ZSTanone closed 2 years ago

ZSTanone commented 2 years ago

Dear Lu, Thanks for your work to provide such great package about PINN. Recently I have read your paper about SBINNs ,I'm very interesting about your work. Before start doing inverse problem ,I want to figure forward problem first . But when I try to use deepxde to solve my odes some problem occurred. Firstly, I implement odes on Matlab ,it works well and I regard the result of Matlab as correct ,so I can know weather the result from PINN is ok. But the PINN works not that well ,the train loss is pretty low and the predict value can't match the matlab result. Here are five of the six outputs image image image image image

And here is the information about loss during training image

Here is my code

`import deepxde as dde import numpy as np import torch import matplotlib.pyplot as plt

f = 0.6
kd = 1e-5
kp = 1600
ktc = ktd = 1e+8
kt = ktc + ktd

def ode (t, y):
    M=y[:, 0:1]
    I= y[:, 1:2]
    am0=y[:, 2:3]
    dm0=y[:, 3:4]
    am1=y[:, 4:5]
    total12=y[:, 5:6]

    dM_dt = dde.grad.jacobian(y, t, i=0, j=0)
    dI_dt = dde.grad.jacobian(y, t, i=1, j=0)
    dam0_dt = dde.grad.jacobian(y, t, i=2, j=0)
    ddm0_dt = dde.grad.jacobian(y, t, i=3, j=0)
    dam1_dt = dde.grad.jacobian(y, t, i=4, j=0)
    dtotal12_dt = dde.grad.jacobian(y, t, i=5, j=0)

    return [
        dM_dt + kp * M * am0,
        (dI_dt + kd * I),
        (dam0_dt - 2*f * kd *I + kt *am0 *am0),
        (ddm0_dt - 2*f * kd *I + (ktc/2) *am0 *am0),
        (dam1_dt - kp *M * am0 + kt * am0 *am1),
        dtotal12_dt - kp * M *(am0+2*am1) - ktc * am1 *am1
    ]

geom = dde.geometry.TimeDomain(0, 15*3600)

data = dde.data.PDE(geom, ode, [], 1000 )

layer_size = [1] + [128] * 3 + [6]
activation = "tanh"
initializer = "Glorot uniform"
net = dde.nn.FNN(layer_size, activation, initializer)

def input_transform(t):
    t = t / 10000
    return t
net.apply_feature_transform(input_transform)

def output_transform(t, y):
    y1 = y[:, 0:1]
    y2 = y[:, 1:2]
    y3 = y[:, 2:3]
    y4 = y[:, 3:4]
    y5 = y[:, 4:5]
    y6 = y[:, 5:6]

#use hard constrain to define initial condition

    return torch.cat([y1 * 1 * torch.tanh(t) + 4.9994,
                      y2 * 0.1 *torch.tanh(t) + 0.1,
                      y3 * 1e-8 * torch.tanh(t)+7.7448e-8,
                      y4 * 1e-2 * torch.tanh(t)+9.1936e-7,
                      y5 * 1e-5 *torch.tanh(t)+4.0021e-5,
                      y6* 1e3 * torch.tanh(t)+0.7132
                      ], dim=1)

net.apply_output_transform(output_transform)

model = dde.Model(data, net)
model.compile("adam", lr=0.0002,loss_weights=[1e7,1e12,1e13,1e12,1e9,10])
losshistory, train_state = model.train(epochs=20000)
dde.saveplot(losshistory, train_state, issave=True, isplot=True)`

In this problem the Timedomain is large and I used input transform to scale it. As for output transform ,I don't know if I did the right work , the item 'tanh(t)' seem to give my outputs the feature of tanh. As for the chosen of loss weight that I try to maintain my 6 odes' loss on the same magnitude after compile. I've tried to adjust my learning rate or the train epochs and still can't get ideal solution ,and I've read the FQA about loss items ,it can't provide me enough information about my problem. So I hope you can give me some suggestions about my problems ,I'm very appreciate about your help.

lululxvi commented 2 years ago

Before solving a system of 6 ODEs, you may first try a simpler case to get some experience.

ZSTanone commented 2 years ago

Before solving a system of 6 ODEs, you may first try a simpler case to get some experience.

Sorry to bother you again ,first thanks for your answer , I've read the ode example in your DeepXDE doc , and I success in finishing a more complex question ,then I start to figure this 6 ODEs problem out ,but in this ODE system ,I notice some magnitudes of the solution could be very small , like 1e-8 ,which is different from other question . So it's pretty important to do variable scaling . To get a ideal answer, can I do the output scaling like I showed in the code ,make the output in a smaller magnitude ,will this give negative influence on my solution? Thanks

lululxvi commented 2 years ago

Yes, scaling is very important, and you need to resacle.

ZSTanone commented 2 years ago

Yes, scaling is very important, and you need to resacle.

If I want to solve a problem which has a small magnitude could you give me some advice about scaling ,much appreciate.

lululxvi commented 2 years ago

See FAQ Q: I failed to train the network or get the right solution, e.g., large training loss, unbalanced losses.