fnn update, pinn torch models, tests update. (#88)
* fnn update, remove labeltensors * allow custom torch models * updating tests --------- Co-authored-by: Dario Coscia <dariocoscia@Dario-Coscia.local> Co-authored-by: Dario Coscia <dariocoscia@dhcp-031.eduroam.sissa.it>
This commit is contained in:
committed by
Nicola Demo
parent
c8fb7715c4
commit
be11110bb2
@@ -1,13 +1,13 @@
|
||||
import torch
|
||||
import pytest
|
||||
|
||||
from pina import LabelTensor, Condition, Span, PINN
|
||||
from pina import LabelTensor, Condition, CartesianDomain, PINN
|
||||
from pina.problem import SpatialProblem
|
||||
from pina.model import FeedForward
|
||||
from pina.operators import nabla
|
||||
|
||||
|
||||
example_domain = Span({'x': [0, 1], 'y': [0, 1]})
|
||||
example_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]})
|
||||
def example_dirichlet(input_, output_):
|
||||
value = 0.0
|
||||
return output_.extract(['u']) - value
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import pytest
|
||||
import torch
|
||||
|
||||
from pina import LabelTensor
|
||||
from pina.model import DeepONet
|
||||
from pina.model import FeedForward as FFN
|
||||
|
||||
data = torch.rand((20, 3))
|
||||
input_vars = ['a', 'b', 'c']
|
||||
output_vars = ['d']
|
||||
input_ = LabelTensor(data, input_vars)
|
||||
|
||||
|
||||
def test_constructor():
|
||||
branch = FFN(input_variables=['a', 'c'], output_variables=20)
|
||||
trunk = FFN(input_variables=['b'], output_variables=20)
|
||||
onet = DeepONet(nets=[trunk, branch], output_variables=output_vars)
|
||||
|
||||
def test_constructor_fails_when_invalid_inner_layer_size():
|
||||
branch = FFN(input_variables=['a', 'c'], output_variables=20)
|
||||
trunk = FFN(input_variables=['b'], output_variables=19)
|
||||
with pytest.raises(ValueError):
|
||||
DeepONet(nets=[trunk, branch], output_variables=output_vars)
|
||||
|
||||
def test_forward():
|
||||
branch = FFN(input_variables=['a', 'c'], output_variables=10)
|
||||
trunk = FFN(input_variables=['b'], output_variables=10)
|
||||
onet = DeepONet(nets=[trunk, branch], output_variables=output_vars)
|
||||
output_ = onet(input_)
|
||||
assert output_.labels == output_vars
|
||||
@@ -1,58 +0,0 @@
|
||||
import torch
|
||||
import pytest
|
||||
|
||||
from pina import LabelTensor
|
||||
from pina.model import FeedForward
|
||||
|
||||
class myFeature(torch.nn.Module):
|
||||
"""
|
||||
Feature: sin(pi*x)
|
||||
"""
|
||||
def __init__(self):
|
||||
super(myFeature, self).__init__()
|
||||
|
||||
def forward(self, x):
|
||||
return LabelTensor(torch.sin(torch.pi * x.extract('a')), 'sin(a)')
|
||||
|
||||
|
||||
data = torch.rand((20, 3))
|
||||
input_vars = ['a', 'b', 'c']
|
||||
output_vars = ['d', 'e']
|
||||
input_ = LabelTensor(data, input_vars)
|
||||
|
||||
|
||||
def test_constructor():
|
||||
FeedForward(input_vars, output_vars)
|
||||
FeedForward(3, 4)
|
||||
FeedForward(input_vars, output_vars, extra_features=[myFeature()])
|
||||
FeedForward(input_vars, output_vars, inner_size=10, n_layers=20)
|
||||
FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2])
|
||||
FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2],
|
||||
func=torch.nn.ReLU)
|
||||
FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2],
|
||||
func=[torch.nn.ReLU, torch.nn.ReLU, None, torch.nn.Tanh])
|
||||
|
||||
|
||||
def test_constructor_wrong():
|
||||
with pytest.raises(RuntimeError):
|
||||
FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2],
|
||||
func=[torch.nn.ReLU, torch.nn.ReLU])
|
||||
|
||||
|
||||
def test_forward():
|
||||
fnn = FeedForward(input_vars, output_vars)
|
||||
output_ = fnn(input_)
|
||||
assert output_.labels == output_vars
|
||||
|
||||
|
||||
def test_forward2():
|
||||
dim_in, dim_out = 3, 2
|
||||
fnn = FeedForward(dim_in, dim_out)
|
||||
output_ = fnn(input_)
|
||||
assert output_.shape == (input_.shape[0], dim_out)
|
||||
|
||||
|
||||
def test_forward_features():
|
||||
fnn = FeedForward(input_vars, output_vars, extra_features=[myFeature()])
|
||||
output_ = fnn(input_)
|
||||
assert output_.labels == output_vars
|
||||
31
tests/test_model/test_deeponet.py
Normal file
31
tests/test_model/test_deeponet.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import pytest
|
||||
import torch
|
||||
|
||||
from pina import LabelTensor
|
||||
from pina.model import DeepONet
|
||||
from pina.model import FeedForward as FFN
|
||||
|
||||
data = torch.rand((20, 3))
|
||||
input_vars = ['a', 'b', 'c']
|
||||
output_vars = ['d']
|
||||
input_ = LabelTensor(data, input_vars)
|
||||
|
||||
# TODO
|
||||
|
||||
# def test_constructor():
|
||||
# branch = FFN(input_variables=['a', 'c'], output_variables=20)
|
||||
# trunk = FFN(input_variables=['b'], output_variables=20)
|
||||
# onet = DeepONet(nets=[trunk, branch], output_variables=output_vars)
|
||||
|
||||
# def test_constructor_fails_when_invalid_inner_layer_size():
|
||||
# branch = FFN(input_variables=['a', 'c'], output_variables=20)
|
||||
# trunk = FFN(input_variables=['b'], output_variables=19)
|
||||
# with pytest.raises(ValueError):
|
||||
# DeepONet(nets=[trunk, branch], output_variables=output_vars)
|
||||
|
||||
# def test_forward():
|
||||
# branch = FFN(input_variables=['a', 'c'], output_variables=10)
|
||||
# trunk = FFN(input_variables=['b'], output_variables=10)
|
||||
# onet = DeepONet(nets=[trunk, branch], output_variables=output_vars)
|
||||
# output_ = onet(input_)
|
||||
# assert output_.labels == output_vars
|
||||
33
tests/test_model/test_fnn.py
Normal file
33
tests/test_model/test_fnn.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import torch
|
||||
import pytest
|
||||
|
||||
from pina.model import FeedForward
|
||||
|
||||
|
||||
data = torch.rand((20, 3))
|
||||
input_vars = 3
|
||||
output_vars = 4
|
||||
|
||||
|
||||
def test_constructor():
|
||||
FeedForward(input_vars, output_vars)
|
||||
FeedForward(input_vars, output_vars, inner_size=10, n_layers=20)
|
||||
FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2])
|
||||
FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2],
|
||||
func=torch.nn.ReLU)
|
||||
FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2],
|
||||
func=[torch.nn.ReLU, torch.nn.ReLU, None, torch.nn.Tanh])
|
||||
|
||||
|
||||
def test_constructor_wrong():
|
||||
with pytest.raises(RuntimeError):
|
||||
FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2],
|
||||
func=[torch.nn.ReLU, torch.nn.ReLU])
|
||||
|
||||
|
||||
|
||||
def test_forward():
|
||||
dim_in, dim_out = 3, 2
|
||||
fnn = FeedForward(dim_in, dim_out)
|
||||
output_ = fnn(data)
|
||||
assert output_.shape == (data.shape[0], dim_out)
|
||||
@@ -1,38 +1,10 @@
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import pytest
|
||||
from pina.model import Network
|
||||
from pina.model import Network, FeedForward
|
||||
from pina import LabelTensor
|
||||
|
||||
|
||||
class SimpleNet(nn.Module):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.layers = nn.Sequential(
|
||||
nn.Linear(2, 20),
|
||||
nn.Tanh(),
|
||||
nn.Linear(20, 1)
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
return self.layers(x)
|
||||
|
||||
|
||||
class SimpleNetExtraFeat(nn.Module):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.layers = nn.Sequential(
|
||||
nn.Linear(3, 20),
|
||||
nn.Tanh(),
|
||||
nn.Linear(20, 1)
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
return self.layers(x)
|
||||
|
||||
|
||||
class myFeature(torch.nn.Module):
|
||||
"""
|
||||
Feature: sin(x)
|
||||
@@ -54,13 +26,13 @@ input_ = LabelTensor(data, input_variables)
|
||||
|
||||
|
||||
def test_constructor():
|
||||
net = SimpleNet()
|
||||
net = FeedForward(2, 1)
|
||||
pina_net = Network(model=net, input_variables=input_variables,
|
||||
output_variables=output_variables)
|
||||
|
||||
|
||||
def test_forward():
|
||||
net = SimpleNet()
|
||||
net = FeedForward(2, 1)
|
||||
pina_net = Network(model=net, input_variables=input_variables,
|
||||
output_variables=output_variables)
|
||||
output_ = pina_net(input_)
|
||||
@@ -68,14 +40,14 @@ def test_forward():
|
||||
|
||||
|
||||
def test_constructor_extrafeat():
|
||||
net = SimpleNetExtraFeat()
|
||||
net = FeedForward(3, 1)
|
||||
feat = [myFeature()]
|
||||
pina_net = Network(model=net, input_variables=input_variables,
|
||||
output_variables=output_variables, extra_features=feat)
|
||||
|
||||
|
||||
def test_forward_extrafeat():
|
||||
net = SimpleNetExtraFeat()
|
||||
net = FeedForward(3, 1)
|
||||
feat = [myFeature()]
|
||||
pina_net = Network(model=net, input_variables=input_variables,
|
||||
output_variables=output_variables, extra_features=feat)
|
||||
@@ -1,7 +1,7 @@
|
||||
import torch
|
||||
import pytest
|
||||
|
||||
from pina import LabelTensor, Condition, Span, PINN
|
||||
from pina import LabelTensor, Condition, CartesianDomain, PINN
|
||||
from pina.problem import SpatialProblem
|
||||
from pina.model import FeedForward
|
||||
from pina.operators import nabla
|
||||
@@ -11,7 +11,7 @@ out_ = LabelTensor(torch.tensor([[0.]]), ['u'])
|
||||
|
||||
class Poisson(SpatialProblem):
|
||||
output_variables = ['u']
|
||||
spatial_domain = Span({'x': [0, 1], 'y': [0, 1]})
|
||||
spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]})
|
||||
|
||||
def laplace_equation(input_, output_):
|
||||
force_term = (torch.sin(input_.extract(['x'])*torch.pi) *
|
||||
@@ -25,19 +25,19 @@ class Poisson(SpatialProblem):
|
||||
|
||||
conditions = {
|
||||
'gamma1': Condition(
|
||||
location=Span({'x': [0, 1], 'y': 1}),
|
||||
location=CartesianDomain({'x': [0, 1], 'y': 1}),
|
||||
function=nil_dirichlet),
|
||||
'gamma2': Condition(
|
||||
location=Span({'x': [0, 1], 'y': 0}),
|
||||
location=CartesianDomain({'x': [0, 1], 'y': 0}),
|
||||
function=nil_dirichlet),
|
||||
'gamma3': Condition(
|
||||
location=Span({'x': 1, 'y': [0, 1]}),
|
||||
location=CartesianDomain({'x': 1, 'y': [0, 1]}),
|
||||
function=nil_dirichlet),
|
||||
'gamma4': Condition(
|
||||
location=Span({'x': 0, 'y': [0, 1]}),
|
||||
location=CartesianDomain({'x': 0, 'y': [0, 1]}),
|
||||
function=nil_dirichlet),
|
||||
'D': Condition(
|
||||
location=Span({'x': [0, 1], 'y': [0, 1]}),
|
||||
location=CartesianDomain({'x': [0, 1], 'y': [0, 1]}),
|
||||
function=laplace_equation),
|
||||
'data': Condition(
|
||||
input_points=in_,
|
||||
@@ -53,15 +53,33 @@ class Poisson(SpatialProblem):
|
||||
truth_solution = poisson_sol
|
||||
|
||||
|
||||
problem = Poisson()
|
||||
class myFeature(torch.nn.Module):
|
||||
"""
|
||||
Feature: sin(x)
|
||||
"""
|
||||
|
||||
model = FeedForward(problem.input_variables, problem.output_variables)
|
||||
def __init__(self):
|
||||
super(myFeature, self).__init__()
|
||||
|
||||
def forward(self, x):
|
||||
t = (torch.sin(x.extract(['x'])*torch.pi) *
|
||||
torch.sin(x.extract(['y'])*torch.pi))
|
||||
return LabelTensor(t, ['sin(x)sin(y)'])
|
||||
|
||||
|
||||
problem = Poisson()
|
||||
model = FeedForward(len(problem.input_variables),len(problem.output_variables))
|
||||
model_extra_feat = FeedForward(len(problem.input_variables) + 1,len(problem.output_variables))
|
||||
|
||||
|
||||
def test_constructor():
|
||||
PINN(problem, model)
|
||||
|
||||
|
||||
def test_constructor_extra_feats():
|
||||
PINN(problem, model_extra_feat, [myFeature()])
|
||||
|
||||
|
||||
def test_span_pts():
|
||||
pinn = PINN(problem, model)
|
||||
n = 10
|
||||
@@ -133,6 +151,28 @@ def test_train_2():
|
||||
assert list(pinn.history_loss.keys()) == truth_key
|
||||
|
||||
|
||||
def test_train_extra_feats():
|
||||
pinn = PINN(problem, model_extra_feat, [myFeature()])
|
||||
boundaries = ['gamma1', 'gamma2', 'gamma3', 'gamma4']
|
||||
n = 10
|
||||
pinn.span_pts(n, 'grid', locations=boundaries)
|
||||
pinn.span_pts(n, 'grid', locations=['D'])
|
||||
pinn.train(5)
|
||||
|
||||
|
||||
def test_train_2_extra_feats():
|
||||
boundaries = ['gamma1', 'gamma2', 'gamma3', 'gamma4']
|
||||
n = 10
|
||||
expected_keys = [[], list(range(0, 50, 3))]
|
||||
param = [0, 3]
|
||||
for i, truth_key in zip(param, expected_keys):
|
||||
pinn = PINN(problem, model_extra_feat, [myFeature()])
|
||||
pinn.span_pts(n, 'grid', locations=boundaries)
|
||||
pinn.span_pts(n, 'grid', locations=['D'])
|
||||
pinn.train(50, save_loss=i)
|
||||
assert list(pinn.history_loss.keys()) == truth_key
|
||||
|
||||
|
||||
def test_train_with_optimizer_kwargs():
|
||||
boundaries = ['gamma1', 'gamma2', 'gamma3', 'gamma4']
|
||||
n = 10
|
||||
|
||||
Reference in New Issue
Block a user