Skip to content

Commit 87239d0

Browse files
[Example] Add spinn on helmholtz equation (#958)
* update spinn code(WIP) * update code(l2err=0.089) * update SPINN helmholtz3d * update pretraind model url(TRAIN.nc=64) * add spinn doc * refine code and docs * update * update docs * update supports information * update code and doc * refine arch code
1 parent be0802f commit 87239d0

File tree

12 files changed

+911
-10
lines changed

12 files changed

+911
-10
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ PaddleScience 是一个基于深度学习框架 PaddlePaddle 开发的科学计
2727

2828
| 问题类型 | 案例名称 | 优化算法 | 模型类型 | 训练方式 | 数据集 | 参考资料 |
2929
|-----|---------|-----|---------|----|---------|---------|
30+
| 三维亥姆霍兹方程 | [SPINN(Helmholtz3D)](https://paddlescience-docs.readthedocs.io/zh/examples/spinn.md) | 机理驱动 | ModifiedMLP | 无监督学习 | - | [Paper](https://arxiv.org/pdf/2306.15969) |
3031
| 相场方程 | [Allen-Cahn](https://paddlescience-docs.readthedocs.io/zh/latest/zh/examples/allen_cahn) | 机理驱动 | MLP | 无监督学习 | [Data](https://paddle-org.bj.bcebos.com/paddlescience/datasets/AllenCahn/allen_cahn.mat) | [Paper](https://arxiv.org/pdf/2402.00326) |
3132
| 微分方程 | [拉普拉斯方程](https://paddlescience-docs.readthedocs.io/zh/latest/zh/examples/laplace2d) | 机理驱动 | MLP | 无监督学习 | - | - |
3233
| 微分方程 | [伯格斯方程](https://paddlescience-docs.readthedocs.io/zh/latest/zh/examples/deephpms) | 机理驱动 | MLP | 无监督学习 | [Data](https://github.com/maziarraissi/DeepHPMs/tree/master/Data) | [Paper](https://arxiv.org/pdf/1801.06637.pdf) |
@@ -212,7 +213,7 @@ python -c "import paddle; paddle.utils.run_check()"
212213

213214
## 🎈其他领域支持
214215

215-
除 PaddleScience 套件外,Paddle 框架还支持了 [DeepXDE](https://github.com/lululxvi/deepxde/tree/master?tab=readme-ov-file#deepxde) 的所有案例,分子动力学套件 [DeepMD-kit](https://github.com/deepmodeling/deepmd-kit/tree/paddle2?tab=readme-ov-file#deepmd-kitpaddlepaddle-backend) 部分案例和功能,以及正在适配中的 Modulus
216+
除 PaddleScience 套件外,Paddle 框架还支持了 [Modulus-sym](https://github.com/PaddlePaddle/modulus-sym/tree/paddle?tab=readme-ov-file#modulus-symbolic-betapaddle-backend)、[DeepXDE](https://github.com/lululxvi/deepxde/tree/master?tab=readme-ov-file#deepxde) 的所有案例,分子动力学套件 [DeepMD-kit](https://github.com/deepmodeling/deepmd-kit/tree/paddle2?tab=readme-ov-file#deepmd-kitpaddlepaddle-backend) 部分案例和功能。
216217

217218
<!-- --8<-- [start:support] -->
218219
## 💬支持与建议
@@ -232,9 +233,9 @@ PaddleScience 项目欢迎并依赖开发人员和开源社区中的用户,会
232233
旨在鼓励更多的开发者参与到飞桨科学计算社区的开源建设中,帮助社区修复 bug 或贡献 feature,加入开源、共建飞桨。了解编程基本知识的入门用户即可参与,活动进行中:
233234
[PaddleScience 快乐开源活动表单](https://github.com/PaddlePaddle/PaddleScience/issues/379)
234235

235-
- 🔥第六期黑客松
236+
<!-- - 🔥第六期黑客松
236237

237-
面向全球开发者的深度学习领域编程活动,鼓励开发者了解与参与飞桨深度学习开源项目与文心大模型开发实践。活动进行中:[【PaddlePaddle Hackathon 5th】开源贡献个人挑战赛](https://github.com/PaddlePaddle/community/blob/master/hackathon/hackathon_6th/%E3%80%90Hackathon%206th%E3%80%91%E5%BC%80%E6%BA%90%E8%B4%A1%E7%8C%AE%E4%B8%AA%E4%BA%BA%E6%8C%91%E6%88%98%E8%B5%9B%E7%A7%91%E5%AD%A6%E8%AE%A1%E7%AE%97%E4%BB%BB%E5%8A%A1%E5%90%88%E9%9B%86.md)
238+
面向全球开发者的深度学习领域编程活动,鼓励开发者了解与参与飞桨深度学习开源项目与文心大模型开发实践。活动进行中:[【PaddlePaddle Hackathon 5th】开源贡献个人挑战赛](https://github.com/PaddlePaddle/community/blob/master/hackathon/hackathon_6th/%E3%80%90Hackathon%206th%E3%80%91%E5%BC%80%E6%BA%90%E8%B4%A1%E7%8C%AE%E4%B8%AA%E4%BA%BA%E6%8C%91%E6%88%98%E8%B5%9B%E7%A7%91%E5%AD%A6%E8%AE%A1%E7%AE%97%E4%BB%BB%E5%8A%A1%E5%90%88%E9%9B%86.md) -->
238239
<!-- --8<-- [end:contribution] -->
239240

240241
<!-- --8<-- [start:collaboration] -->

docs/index.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272

7373
| 问题类型 | 案例名称 | 优化算法 | 模型类型 | 训练方式 | 数据集 | 参考资料 |
7474
|-----|---------|-----|---------|----|---------|---------|
75+
| 三维亥姆霍兹方程 | [SPINN(Helmholtz3D)](./zh/examples/spinn.md) | 机理驱动 | ModifiedMLP | 无监督学习 | - | [Paper](https://arxiv.org/pdf/2306.15969) |
7576
| 相场方程 | [Allen-Cahn](./zh/examples/allen_cahn.md) | 机理驱动 | MLP | 无监督学习 | [Data](https://paddle-org.bj.bcebos.com/paddlescience/datasets/AllenCahn/allen_cahn.mat) | [Paper](https://arxiv.org/pdf/2402.00326) |
7677
| 微分方程 | [拉普拉斯方程](./zh/examples/laplace2d.md) | 机理驱动 | MLP | 无监督学习 | - | - |
7778
| 微分方程 | [伯格斯方程](./zh/examples/deephpms.md) | 机理驱动 | MLP | 无监督学习 | [Data](https://github.com/maziarraissi/DeepHPMs/tree/master/Data) | [Paper](https://arxiv.org/pdf/1801.06637.pdf) |
@@ -181,16 +182,16 @@
181182
<br><span class="text-large">全量支持</span></br>
182183
</div>
183184
</a>
185+
<a href="https://github.com/PaddlePaddle/modulus-sym/tree/paddle?tab=readme-ov-file#modulus-symbolic-betapaddle-backend">
186+
<div class="card card-deepmd">
187+
Modulus-sym
188+
<br><span class="text-large">全量支持</span></br>
189+
</div>
190+
</a>
184191
<a href="https://github.com/deepmodeling/deepmd-kit/tree/paddle?tab=readme-ov-file#deepmd-kitpaddlepaddle-backend">
185192
<div class="card card-modulus">
186193
DeepMD
187-
<br><span class="text-large">适配中</span></br>
188-
</div>
189-
</a>
190-
<a href="https://github.com/PaddlePaddle/modulus-sym/tree/paddle?tab=readme-ov-file#modulus-symbolic-betapaddle-backend">
191-
<div class="card card-deepmd">
192-
Modulus
193-
<br><span class="text-large">适配中</span></br>
194+
<br><span class="text-large">部分适配</span></br>
194195
</div>
195196
</a>
196197
</div>

docs/zh/api/equation.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Biharmonic
1010
- FractionalPoisson
1111
- HeatExchanger
12+
- Helmholtz
1213
- Laplace
1314
- LinearElasticity
1415
- NavierStokes

docs/zh/examples/spinn.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# SPINN(helmholtz3d)
2+
3+
<!-- <a href="https://aistudio.baidu.com/projectdetail/8219967" class="md-button md-button--primary" style>AI Studio快速体验</a> -->
4+
5+
=== "模型训练命令"
6+
7+
``` sh
8+
python helmholtz3d.py
9+
```
10+
11+
=== "模型评估命令"
12+
13+
``` sh
14+
python helmholtz3d.py mode=eval EVAL.pretrained_model_path=https://paddle-org.bj.bcebos.com/paddlescience/models/spinn/spinn_helmholtz3d_pretrained.pdparams
15+
```
16+
17+
=== "模型导出命令"
18+
19+
``` sh
20+
python helmholtz3d.py mode=export
21+
```
22+
23+
=== "模型推理命令"
24+
25+
``` sh
26+
python helmholtz3d.py mode=infer
27+
```
28+
29+
| 预训练模型 | 指标 |
30+
|:--| :--|
31+
| [spinn_helmholtz3d.pdparams](https://paddle-org.bj.bcebos.com/paddlescience/models/spinn/spinn_helmholtz3d_pretrained.pdparams) | l2_err: 0.0183 <br> rmse: 0.0064 |
32+
33+
## 1. 背景简介
34+
35+
Helmholtz方程是一个重要的偏微分方程,广泛应用于物理学和工程学中,特别是在波动理论和振动问题中。它以德国物理学家赫尔曼·冯·亥姆霍兹(Hermann von Helmholtz)的名字命名。Helmholtz方程的标准形式如下:
36+
37+
$$
38+
\nabla^2 u + k^2 u = q
39+
$$
40+
41+
这里:
42+
43+
- $\nabla^2$ 是拉普拉斯算子(也称为拉普拉斯算符),在三维直角坐标系下,它的形式是:$\nabla^2 = \frac{\partial^2 }{\partial x^2} + \frac{\partial^2 }{\partial y^2} + \frac{\partial^2 }{\partial z^2}$
44+
- $u$ 是待求解的函数,通常表示物理量的幅度,如电磁场、声压或量子波函数等。
45+
- $k$ 是波数,定义为 $k = \frac{2\pi}{\lambda}$,其中 $\lambda$ 是波长。
46+
- $q$ 是源项,通常表示物理量与时间、空间导数之间的相互作用。
47+
48+
本案例解决以下三维 Helmholtz 方程:
49+
50+
$$
51+
\begin{aligned}
52+
& \nabla^2 u + k^2 u = q, x \in \Omega \\
53+
& u(x) = 0, x \in \partial \Omega \\
54+
\end{aligned}
55+
$$
56+
57+
$$
58+
\begin{aligned}
59+
& \text{source term } q = -(a_1 \pi)^2 u -(a_2 \pi)^2 u -(a_3 \pi)^2 u + k^2 u \\
60+
& \text{where }k=1, a_1=4, a_2=4, a_3=3
61+
\end{aligned}
62+
$$
63+
64+
## 2. 问题定义
65+
66+
本问题的计算域在 $[-1, 1] ^3$ 一个单位正方体内,对于计算域内部点,要求满足上述 Helmholtz 方程,对于计算域边界点,要求满足 $u = 0$。
67+
68+
## 3. 问题求解
69+
70+
接下来开始讲解如何将问题一步一步地转化为 PaddleScience 代码,用深度学习的方法求解该问题。
71+
为了快速理解 PaddleScience,接下来仅对模型构建、方程构建、计算域构建等关键步骤进行阐述,而其余细节请参考 [API文档](../api/arch.md)
72+
73+
### 3.1 模型构建
74+
75+
SPINN 的模型结构设计如下:
76+
77+
![SPINN_structure](https://paddle-org.bj.bcebos.com/paddlescience/docs/spinn/spinn_structure.png)
78+
79+
在 Helmholtz 问题中,每一个已知的坐标点 $(x, y, z)$ 都有对应的待求解的未知量 $u$(此处我们用 $u$代替),在这里使用 SPINN 来表示 $(x, y, z)$ 到 $(u)$ 的映射函数 $f: \mathbb{R}^3 \to \mathbb{R}^1$ ,即:
80+
81+
$$
82+
u = m(x, y, z)
83+
$$
84+
85+
上式中 $m$ 即为 SPINN 模型本身,用 PaddleScience 代码表示如下
86+
87+
``` py linenums="99"
88+
--8<--
89+
examples/spinn/helmholtz3d.py:99:100
90+
--8<--
91+
```
92+
93+
为了在计算时,准确快速地访问具体变量的值,在这里指定网络模型的输入变量名是 `("x", "y", "z")`,输出变量名是 `("u")`,这些命名与后续代码保持一致。
94+
95+
接着通过指定 SPINN 的层数、神经元个数,就实例化出了一个拥有 4 层全连接层,每层全连接层的神经元个数为 64 ,每一个输出变量的隐层特征维度 `r` 为 32 的神经网络模型 `model`, 并且使用 `tanh` 作为激活函数。
96+
97+
``` yaml linenums="38"
98+
--8<--
99+
examples/spinn/conf/helmholtz3d.yaml:38:45
100+
--8<--
101+
```
102+
103+
### 3.2 方程构建
104+
105+
Helmholtz 微分方程可以用如下代码表示:
106+
107+
``` py linenums="102"
108+
--8<--
109+
examples/spinn/helmholtz3d.py:102:104
110+
--8<--
111+
```
112+
113+
注:此处我们需要把 model 手动传递给 `equation["Helmholtz"]`,因为 `Helmholtz` 方程需要用到前向微分功能。
114+
115+
### 3.3 约束构建
116+
117+
#### 3.3.1 内部点约束
118+
119+
以作用在内部点上的 `SupervisedConstraint` 为例,用于生成内部点训练数据的代码如下:
120+
121+
``` py linenums="39"
122+
--8<--
123+
examples/spinn/helmholtz3d.py:39:83
124+
--8<--
125+
```
126+
127+
用于构建内部点约束的代码如下:
128+
129+
``` py linenums="106"
130+
--8<--
131+
examples/spinn/helmholtz3d.py:106:156
132+
--8<--
133+
```
134+
135+
`SupervisedConstraint` 的第一个参数是用于训练的数据配置,由于我们使用实时随机生成的数据,而不是固定数据点,因此填入自定义的输入数据/标签生成函数;
136+
137+
第二个参数是方程表达式,因此传入 Helmholtz 的方程对象;
138+
139+
第三个参数是损失函数,此处选用 `MSELoss` 即可;
140+
141+
第四个参数是约束条件的名字,需要给每一个约束条件命名,方便后续对其索引。此处命名为 "PDE" 即可。
142+
143+
#### 3.3.3 边值约束
144+
145+
第三个约束条件是边值约束,代码如下:
146+
147+
``` py linenums="158"
148+
--8<--
149+
examples/spinn/helmholtz3d.py:158:190
150+
--8<--
151+
```
152+
153+
### 3.4 超参数设定
154+
155+
接下来需要指定训练轮数和学习率,此处按实验经验,使用 50 轮训练轮数,每轮迭代 1000 步,0.001 的初始学习率。
156+
157+
``` yaml linenums="47"
158+
--8<--
159+
examples/spinn/conf/helmholtz3d.yaml:47:63
160+
--8<--
161+
```
162+
163+
### 3.5 优化器构建
164+
165+
训练过程会调用优化器来更新模型参数,此处选择较为常用的 `Adam` 优化器,并配合使用机器学习中常用的 ExponentialDecay 学习率调整策略。
166+
167+
``` py linenums="192"
168+
--8<--
169+
examples/spinn/helmholtz3d.py:192:196
170+
--8<--
171+
```
172+
173+
### 3.6 模型训练、评估与可视化
174+
175+
完成上述设置之后,只需要将上述实例化的对象按顺序传递给 `ppsci.solver.Solver`,然后启动训练、评估、可视化。
176+
177+
``` py linenums="198"
178+
--8<--
179+
examples/spinn/helmholtz3d.py:198:227
180+
--8<--
181+
```
182+
183+
## 4. 完整代码
184+
185+
``` py linenums="1" title="helmholtz3d.py"
186+
--8<--
187+
examples/spinn/helmholtz3d.py
188+
--8<--
189+
```
190+
191+
## 5. 结果展示
192+
193+
在计算域上均匀采样出 $100^3$ 个点,其预测结果和解析解如下图所示。
194+
195+
<figure markdown>
196+
![spinn_helmholtz3d.jpg](https://paddle-org.bj.bcebos.com/paddlescience/docs/spinn/spinn_helmholtz3d.png){ loading=lazy }
197+
<figcaption> 左侧为 PaddleScience 预测结果,右侧为解析解结果</figcaption>
198+
</figure>
199+
200+
本问题使用模型预测的误差为 l2_err = 0.0183,rmse = 0.0064,与解析解误差较小,基本一致。
201+
202+
## 6. 参考资料
203+
204+
- [Separable Physics-Informed Neural Networks](https://arxiv.org/pdf/2306.15969)
205+
- [SPINN](https://github.com/stnamjef/SPINN?tab=readme-ov-file)

examples/spinn/conf/helmholtz3d.yaml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
defaults:
2+
- ppsci_default
3+
- TRAIN: train_default
4+
- TRAIN/ema: ema_default
5+
- TRAIN/swa: swa_default
6+
- EVAL: eval_default
7+
- INFER: infer_default
8+
- hydra/job/config/override_dirname/exclude_keys: exclude_keys_default
9+
- _self_
10+
11+
hydra:
12+
run:
13+
# dynamic output directory according to running time and override name
14+
dir: outputs_spinn_helmholtz3d/${now:%Y-%m-%d}/${now:%H-%M-%S}/${hydra.job.override_dirname}
15+
job:
16+
name: ${mode} # name of logfile
17+
chdir: false # keep current working directory unchanged
18+
callbacks:
19+
init_callback:
20+
_target_: ppsci.utils.callbacks.InitCallback
21+
sweep:
22+
# output directory for multirun
23+
dir: ${hydra.run.dir}
24+
subdir: ./
25+
26+
# general settings
27+
mode: train # running mode: train/eval
28+
seed: 111
29+
output_dir: ${hydra:run.dir}
30+
log_freq: 100
31+
32+
# set working condition
33+
K: 1.0
34+
a1: 4
35+
a2: 4
36+
a3: 3
37+
38+
# model settings
39+
MODEL:
40+
input_keys: ["x", "y", "z"]
41+
output_keys: ["u"]
42+
num_layers: 4
43+
hidden_size: 64
44+
r: 32
45+
activation: "tanh"
46+
47+
# training settings
48+
TRAIN:
49+
epochs: 50
50+
iters_per_epoch: 1000
51+
save_freq: 10
52+
eval_during_train: false
53+
eval_freq: 5
54+
lr_scheduler:
55+
epochs: ${TRAIN.epochs}
56+
iters_per_epoch: ${TRAIN.iters_per_epoch}
57+
learning_rate: 1.0e-3
58+
gamma: 0.9
59+
decay_steps: 1000
60+
by_epoch: false
61+
nc: 64
62+
pretrained_model_path: null
63+
checkpoint_path: null
64+
65+
# evaluation settings
66+
EVAL:
67+
pretrained_model_path: null
68+
eval_with_no_grad: true
69+
batch_size: 1024
70+
nc: 100
71+
72+
# inference settings
73+
INFER:
74+
pretrained_model_path: https://paddle-org.bj.bcebos.com/paddlescience/models/spinn/spinn_helmholtz3d_pretrained.pdparams
75+
export_path: ./inference/spinn_helmholtz3d
76+
pdmodel_path: ${INFER.export_path}.pdmodel
77+
pdiparams_path: ${INFER.export_path}.pdiparams
78+
onnx_path: ${INFER.export_path}.onnx
79+
device: gpu
80+
engine: native
81+
precision: fp32
82+
ir_optim: true
83+
min_subgraph_size: 5
84+
gpu_mem: 2000
85+
gpu_id: 0
86+
max_batch_size: 1024
87+
num_cpu_threads: 10
88+
batch_size: 1024

0 commit comments

Comments
 (0)