Skip to content
This repository was archived by the owner on Sep 28, 2024. It is now read-only.

Commit 07c1653

Browse files
authored
Merge pull request #46 from SciML/transforms
Separate out transforms from OperatorKernels
2 parents 9c1b044 + 4c05564 commit 07c1653

File tree

18 files changed

+371
-285
lines changed

18 files changed

+371
-285
lines changed

README.md

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@ It performs Fourier transformation across infinite-dimensional function spaces a
3636
With only one time step information of learning, it can predict the following few steps with low loss
3737
by linking the operators into a Markov chain.
3838

39-
**DeepONet operator** (Deep Operator Network)learns a neural operator with the help of two sub-neural net structures described as the branch and the trunk network. The branch network is fed the initial conditions data, whereas the trunk is fed with the locations where the target(output) is evaluated from the corresponding initial conditions. It is important that the output size of the branch and trunk subnets is same so that a dot product can be performed between them.
39+
**DeepONet operator** (Deep Operator Network) learns a neural operator with the help of two sub-neural net structures described as the branch and the trunk network.
40+
The branch network is fed the initial conditions data, whereas the trunk is fed with the locations where the target(output) is evaluated from the corresponding initial conditions.
41+
It is important that the output size of the branch and trunk subnets is same so that a dot product can be performed between them.
4042

41-
Currently, the `FourierOperator` layer is provided in this work.
43+
Currently, the `OperatorKernel` layer is provided in this work.
4244
As for model, there are `FourierNeuralOperator` and `MarkovNeuralOperator` provided. Please take a glance at them [here](src/model.jl).
4345

4446
## Usage
@@ -51,10 +53,10 @@ model = Chain(
5153
# here, d == 1 and n == 64
5254
Dense(2, 64),
5355
# map each hidden representation to the next by integral kernel operator
54-
FourierOperator(64=>64, (16, ), gelu),
55-
FourierOperator(64=>64, (16, ), gelu),
56-
FourierOperator(64=>64, (16, ), gelu),
57-
FourierOperator(64=>64, (16, )),
56+
OperatorKernel(64=>64, (16, ), FourierTransform, gelu),
57+
OperatorKernel(64=>64, (16, ), FourierTransform, gelu),
58+
OperatorKernel(64=>64, (16, ), FourierTransform, gelu),
59+
OperatorKernel(64=>64, (16, ), FourierTransform),
5860
# project back to the scalar field of interest space
5961
Dense(64, 128, gelu),
6062
Dense(128, 1),
@@ -83,27 +85,28 @@ Flux.@epochs 50 Flux.train!(loss, params(model), data, opt)
8385
### DeepONet
8486

8587
```julia
86-
#tuple of Ints for branch net architecture and then for trunk net, followed by activations for branch and trunk respectively
87-
model = DeepONet((32,64,72), (24,64,72), σ, tanh)
88+
# tuple of Ints for branch net architecture and then for trunk net,
89+
# followed by activations for branch and trunk respectively
90+
model = DeepONet((32, 64, 72), (24, 64, 72), σ, tanh)
8891
```
8992
Or specify branch and trunk as separate `Chain` from Flux and pass to `DeepONet`
9093

9194
```julia
92-
branch = Chain(Dense(32,64,σ), Dense(64,72,σ))
93-
trunk = Chain(Dense(24,64,tanh), Dense(64,72,tanh))
94-
model = DeepONet(branch,trunk)
95+
branch = Chain(Dense(32, 64, σ), Dense(64, 72, σ))
96+
trunk = Chain(Dense(24, 64, tanh), Dense(64, 72, tanh))
97+
model = DeepONet(branch, trunk)
9598
```
9699

97100
You can again specify loss, optimization and training parameters just as you would for a simple neural network with Flux.
98101

99102
```julia
100-
loss(xtrain,ytrain,sensor) = Flux.Losses.mse(model(xtrain,sensor),ytrain)
101-
evalcb() = @show(loss(xval,yval,grid))
103+
loss(xtrain, ytrain, sensor) = Flux.Losses.mse(model(xtrain, sensor), ytrain)
104+
evalcb() = @show(loss(xval, yval, grid))
102105

103106
learning_rate = 0.001
104107
opt = ADAM(learning_rate)
105108
parameters = params(model)
106-
Flux.@epochs 400 Flux.train!(loss, parameters, [(xtrain,ytrain,grid)], opt, cb = evalcb)
109+
Flux.@epochs 400 Flux.train!(loss, parameters, [(xtrain, ytrain, grid)], opt, cb=evalcb)
107110
```
108111

109112
## Examples
@@ -130,16 +133,6 @@ PDE training examples are provided in `example` folder.
130133

131134
[Super resolution on time dependent Navier-Stokes equation](example/SuperResolution)
132135

133-
## Roadmap
134-
135-
- [x] `FourierOperator` layer
136-
- [x] One-dimensional Burgers' equation example
137-
- [x] Two-dimensional with time Navier-Stokes equations example
138-
- [x] `MarkovNeuralOperator` model
139-
- [x] Flow over a circle prediction example
140-
- [ ] `NeuralOperator` layer
141-
- [ ] Poisson equation example
142-
143136
## References
144137

145138
- [Fourier Neural Operator for Parametric Partial Differential Equations](https://arxiv.org/abs/2010.08895)

docs/src/apis.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
## Layers
77

8-
### Spectral convolutional layer
8+
### Operator convolutional layer
99

1010
```math
1111
F(s) = \mathcal{F} \{ v(x) \} \\
@@ -18,14 +18,14 @@ where ``v(x)`` and ``v'(x)`` denotes input and output function,
1818
Function ``g`` is a linear transform for lowering Fouier modes.
1919

2020
```@docs
21-
SpectralConv
21+
OperatorConv
2222
```
2323

2424
Reference: [Fourier Neural Operator for Parametric Partial Differential Equations](https://arxiv.org/abs/2010.08895)
2525

2626
---
2727

28-
### Fourier operator layer
28+
### Operator kernel layer
2929

3030
```math
3131
v_{t+1}(x) = \sigma(W v_t(x) + \mathcal{K} \{ v_t(x) \} )
@@ -35,7 +35,7 @@ where ``v_t(x)`` is the input function for ``t``-th layer and ``\mathcal{K} \{ \
3535
Activation function ``\sigma`` can be arbitrary non-linear function.
3636

3737
```@docs
38-
FourierOperator
38+
OperatorKernel
3939
```
4040

4141
Reference: [Fourier Neural Operator for Parametric Partial Differential Equations](https://arxiv.org/abs/2010.08895)

docs/src/index.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ It performs Fourier transformation across infinite-dimensional function spaces a
3030
With only one time step information of learning, it can predict the following few steps with low loss
3131
by linking the operators into a Markov chain.
3232

33-
**DeepONet operator** (Deep Operator Network)learns a neural operator with the help of two sub-neural net structures described as the branch and the trunk network. The branch network is fed the initial conditions data, whereas the trunk is fed with the locations where the target(output) is evaluated from the corresponding initial conditions. It is important that the output size of the branch and trunk subnets is same so that a dot product can be performed between them.
33+
**DeepONet operator** (Deep Operator Network) learns a neural operator with the help of two sub-neural net structures described as the branch and the trunk network.
34+
The branch network is fed the initial conditions data, whereas the trunk is fed with the locations where the target(output) is evaluated from the corresponding initial conditions.
35+
It is important that the output size of the branch and trunk subnets is same so that a dot product can be performed between them.
3436

35-
Currently, the `FourierOperator` layer is provided in this work.
37+
Currently, the `OperatorKernel` layer is provided in this work.
3638
As for model, there are `FourierNeuralOperator` and `MarkovNeuralOperator` provided.
3739
Please take a glance at them [here](apis.html#Models).
3840

@@ -54,10 +56,10 @@ model = Chain(
5456
# here, d == 1 and n == 64
5557
Dense(2, 64),
5658
# map each hidden representation to the next by integral kernel operator
57-
FourierOperator(64=>64, (16, ), gelu),
58-
FourierOperator(64=>64, (16, ), gelu),
59-
FourierOperator(64=>64, (16, ), gelu),
60-
FourierOperator(64=>64, (16, )),
59+
OperatorKernel(64=>64, (16, ), FourierTransform, gelu),
60+
OperatorKernel(64=>64, (16, ), FourierTransform, gelu),
61+
OperatorKernel(64=>64, (16, ), FourierTransform, gelu),
62+
OperatorKernel(64=>64, (16, ), FourierTransform),
6163
# project back to the scalar field of interest space
6264
Dense(64, 128, gelu),
6365
Dense(128, 1),
@@ -86,27 +88,28 @@ Flux.@epochs 50 Flux.train!(loss, params(model), data, opt)
8688
### DeepONet
8789

8890
```julia
89-
#tuple of Ints for branch net architecture and then for trunk net, followed by activations for branch and trunk respectively
90-
model = DeepONet((32,64,72), (24,64,72), σ, tanh)
91+
# tuple of Ints for branch net architecture and then for trunk net,
92+
# followed by activations for branch and trunk respectively
93+
model = DeepONet((32, 64, 72), (24, 64, 72), σ, tanh)
9194
```
9295

9396
Or specify branch and trunk as separate `Chain` from Flux and pass to `DeepONet`
9497

9598
```julia
96-
branch = Chain(Dense(32,64,σ), Dense(64,72,σ))
97-
trunk = Chain(Dense(24,64,tanh), Dense(64,72,tanh))
98-
model = DeepONet(branch,trunk)
99+
branch = Chain(Dense(32, 64, σ), Dense(64, 72, σ))
100+
trunk = Chain(Dense(24, 64, tanh), Dense(64, 72, tanh))
101+
model = DeepONet(branch, trunk)
99102
```
100103

101104
You can again specify loss, optimization and training parameters just as you would for a simple neural network with Flux.
102105

103106
```julia
104-
loss(xtrain,ytrain,sensor) = Flux.Losses.mse(model(xtrain,sensor),ytrain)
105-
evalcb() = @show(loss(xval,yval,grid))
107+
loss(xtrain, ytrain, sensor) = Flux.Losses.mse(model(xtrain, sensor), ytrain)
108+
evalcb() = @show(loss(xval, yval, grid))
106109

107110
learning_rate = 0.001
108111
opt = ADAM(learning_rate)
109112
parameters = params(model)
110-
Flux.@epochs 400 Flux.train!(loss, parameters, [(xtrain,ytrain,grid)], opt, cb = evalcb)
113+
Flux.@epochs 400 Flux.train!(loss, parameters, [(xtrain, ytrain, grid)], opt, cb=evalcb)
111114
```
112115
A more complete example using DeepONet architecture to solve Burgers' equation can be found in the [examples](../../example/Burgers/src/Burgers_deeponet.jl)

example/Burgers/src/Burgers.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ function train()
2121
modes = (16, )
2222
ch = 64 => 64
2323
σ = gelu
24+
Transform = FourierTransform
2425
m = Chain(
2526
Dense(2, 64),
26-
FourierOperator(ch, modes, σ),
27-
FourierOperator(ch, modes, σ),
28-
FourierOperator(ch, modes, σ),
29-
FourierOperator(ch, modes),
27+
OperatorKernel(ch, modes, Transform, σ),
28+
OperatorKernel(ch, modes, Transform, σ),
29+
OperatorKernel(ch, modes, Transform, σ),
30+
OperatorKernel(ch, modes, Transform),
3031
Dense(64, 128, σ),
3132
Dense(128, 1),
3233
flatten

example/Burgers/src/Burgers_deeponet.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
function train_don()
2-
if has_cuda()
3-
@info "CUDA is on"
4-
device = gpu
5-
CUDA.allowscalar(false)
6-
else
2+
# if has_cuda()
3+
# @info "CUDA is on"
4+
# device = gpu
5+
# CUDA.allowscalar(false)
6+
# else
77
device = cpu
8-
end
8+
# end
99

1010
x, y = get_data_don(n=300)
1111
xtrain = x[1:280, :]' |> device
12-
xval = x[end-19:end, :]' |device
12+
xval = x[end-19:end, :]' |> device
1313

1414
ytrain = y[1:280, :] |> device
1515
yval = y[end-19:end, :] |> device
@@ -20,7 +20,7 @@ function train_don()
2020
opt = ADAM(learning_rate)
2121

2222
m = DeepONet((1024,1024,1024),(1,1024,1024),gelu,gelu)
23-
loss(xtrain,ytrain,sensor) = Flux.Losses.mse(model(xtrain,sensor),ytrain)
23+
loss(xtrain,ytrain,sensor) = Flux.Losses.mse(m(xtrain,sensor),ytrain)
2424
evalcb() = @show(loss(xval,yval,grid))
2525

2626
Flux.@epochs 400 Flux.train!(loss, params(m), [(xtrain,ytrain,grid)], opt, cb = evalcb)

example/DoublePendulum/src/DoublePendulum.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ function train(; Δt=1)
2626

2727
m = Chain(
2828
Dense(2, 64),
29-
FourierOperator(64=>64, (4, 16), gelu),
30-
FourierOperator(64=>64, (4, 16), gelu),
31-
FourierOperator(64=>64, (4, 16), gelu),
32-
FourierOperator(64=>64, (4, 16)),
29+
OperatorKernel(64=>64, (4, 16), FourierTransform, gelu),
30+
OperatorKernel(64=>64, (4, 16), FourierTransform, gelu),
31+
OperatorKernel(64=>64, (4, 16), FourierTransform, gelu),
32+
OperatorKernel(64=>64, (4, 16), FourierTransform),
3333
Dense(64, 128, gelu),
3434
Dense(128, 2),
3535
) |> device

example/FlowOverCircle/src/FlowOverCircle.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ function train()
2424

2525
m = Chain(
2626
Dense(1, 64),
27-
FourierOperator(64=>64, (24, 24), gelu),
28-
FourierOperator(64=>64, (24, 24), gelu),
29-
FourierOperator(64=>64, (24, 24), gelu),
30-
FourierOperator(64=>64, (24, 24), gelu),
27+
OperatorKernel(64=>64, (24, 24), FourierTransform, gelu),
28+
OperatorKernel(64=>64, (24, 24), FourierTransform, gelu),
29+
OperatorKernel(64=>64, (24, 24), FourierTransform, gelu),
30+
OperatorKernel(64=>64, (24, 24), FourierTransform, gelu),
3131
Dense(64, 1),
3232
) |> device
3333

example/SuperResolution/src/SuperResolution.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ function train()
2424

2525
m = Chain(
2626
Dense(1, 64),
27-
FourierOperator(64=>64, (24, 24), gelu),
28-
FourierOperator(64=>64, (24, 24), gelu),
29-
FourierOperator(64=>64, (24, 24), gelu),
30-
FourierOperator(64=>64, (24, 24), gelu),
27+
OperatorKernel(64=>64, (24, 24), gelu),
28+
OperatorKernel(64=>64, (24, 24), gelu),
29+
OperatorKernel(64=>64, (24, 24), gelu),
30+
OperatorKernel(64=>64, (24, 24), gelu),
3131
Dense(64, 1),
3232
) |> device
3333

src/NeuralOperators.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ module NeuralOperators
1010

1111
export DeepONet
1212

13-
include("fourier.jl")
13+
include("Transform/Transform.jl")
14+
include("operator_kernel.jl")
1415
include("model.jl")
1516
include("DeepONet.jl")
1617
include("subnets.jl")

src/Transform/Transform.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export
2+
AbstractTransform,
3+
transform,
4+
truncate_modes,
5+
inverse
6+
7+
"""
8+
AbstractTransform
9+
10+
## Interface
11+
12+
* `Base.ndims(<:AbstractTransform)`: N dims of modes
13+
* `transform(<:AbstractTransform, 𝐱::AbstractArray)`: Apply the transform to 𝐱
14+
* `truncate_modes(<:AbstractTransform, 𝐱_transformed::AbstractArray)`: Truncate modes that contribute to the noise
15+
* `inverse(<:AbstractTransform, 𝐱_transformed::AbstractArray)`: Apply the inverse transform to 𝐱_transformed
16+
"""
17+
abstract type AbstractTransform end
18+
19+
include("fourier_transform.jl")

0 commit comments

Comments
 (0)