Skip to content

Commit 36e3233

Browse files
authored
Backend paddle: Add dde.nn.MfNN (#1923)
1 parent 7bcda4b commit 36e3233

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

deepxde/nn/paddle/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
"DeepONet",
55
"DeepONetCartesianProd",
66
"FNN",
7+
"MfNN",
78
"MsFFN",
89
"PFNN",
910
"STMsFFN",
1011
]
1112

1213
from .deeponet import DeepONet, DeepONetCartesianProd
1314
from .fnn import FNN, PFNN
15+
from .mfnn import MfNN
1416
from .msffn import MsFFN, STMsFFN

deepxde/nn/paddle/mfnn.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import paddle
2+
3+
from .nn import NN
4+
from .. import activations
5+
from .. import initializers
6+
from .. import regularizers
7+
from ... import config
8+
9+
10+
class MfNN(NN):
11+
"""Multifidelity neural networks."""
12+
13+
def __init__(
14+
self,
15+
layer_sizes_low_fidelity,
16+
layer_sizes_high_fidelity,
17+
activation,
18+
kernel_initializer,
19+
regularization=None,
20+
residue=False,
21+
trainable_low_fidelity=True,
22+
trainable_high_fidelity=True,
23+
):
24+
super().__init__()
25+
self.layer_size_lo = layer_sizes_low_fidelity
26+
self.layer_size_hi = layer_sizes_high_fidelity
27+
28+
self.activation = activations.get(activation)
29+
self.initializer = initializers.get(kernel_initializer)
30+
self.trainable_lo = trainable_low_fidelity
31+
self.trainable_hi = trainable_high_fidelity
32+
self.residue = residue
33+
self.regularizer = regularizers.get(regularization)
34+
35+
# low fidelity
36+
self.linears_lo = self._init_dense(self.layer_size_lo, self.trainable_lo)
37+
38+
# high fidelity
39+
# linear part
40+
self.linears_hi_l = paddle.nn.Linear(
41+
in_features=self.layer_size_lo[0] + self.layer_size_lo[-1],
42+
out_features=self.layer_size_hi[-1],
43+
weight_attr=paddle.ParamAttr(initializer=self.initializer),
44+
)
45+
if not self.trainable_hi:
46+
for param in self.linears_hi_l.parameters():
47+
param.stop_gradient = False
48+
# nonlinear part
49+
self.layer_size_hi = [
50+
self.layer_size_lo[0] + self.layer_size_lo[-1]
51+
] + self.layer_size_hi
52+
self.linears_hi = self._init_dense(self.layer_size_hi, self.trainable_hi)
53+
# linear + nonlinear
54+
if not self.residue:
55+
alpha = self._init_alpha(0.0, self.trainable_hi)
56+
self.add_parameter("alpha", alpha)
57+
else:
58+
alpha1 = self._init_alpha(0.0, self.trainable_hi)
59+
alpha2 = self._init_alpha(0.0, self.trainable_hi)
60+
self.add_parameter("alpha1", alpha1)
61+
self.add_parameter("alpha2", alpha2)
62+
63+
def _init_dense(self, layer_size, trainable):
64+
linears = paddle.nn.LayerList()
65+
for i in range(len(layer_size) - 1):
66+
linear = paddle.nn.Linear(
67+
in_features=layer_size[i],
68+
out_features=layer_size[i + 1],
69+
weight_attr=paddle.ParamAttr(initializer=self.initializer),
70+
)
71+
if not trainable:
72+
for param in linear.parameters():
73+
param.stop_gradient = False
74+
linears.append(linear)
75+
return linears
76+
77+
def _init_alpha(self, value, trainable):
78+
alpha = paddle.create_parameter(
79+
shape=[1],
80+
dtype=config.real(paddle),
81+
default_initializer=paddle.nn.initializer.Constant(value),
82+
)
83+
alpha.stop_gradient = not trainable
84+
return alpha
85+
86+
def forward(self, inputs):
87+
# low fidelity
88+
y = inputs
89+
for i, linear in enumerate(self.linears_lo):
90+
y = linear(y)
91+
if i != len(self.linears_lo) - 1:
92+
y = self.activation(y)
93+
y_lo = y
94+
95+
# high fidelity
96+
x_hi = paddle.concat([inputs, y_lo], axis=1)
97+
# linear
98+
y_hi_l = self.linears_hi_l(x_hi)
99+
# nonlinear
100+
y = x_hi
101+
for i, linear in enumerate(self.linears_hi):
102+
y = linear(y)
103+
if i != len(self.linears_hi) - 1:
104+
y = self.activation(y)
105+
y_hi_nl = y
106+
# linear + nonlinear
107+
if not self.residue:
108+
alpha = paddle.tanh(self.alpha)
109+
y_hi = y_hi_l + alpha * y_hi_nl
110+
else:
111+
alpha1 = paddle.tanh(self.alpha1)
112+
alpha2 = paddle.tanh(self.alpha2)
113+
y_hi = y_lo + 0.1 * (alpha1 * y_hi_l + alpha2 * y_hi_nl)
114+
115+
return y_lo, y_hi

0 commit comments

Comments
 (0)