Skip to content

Commit 207c54f

Browse files
add quickstart
1 parent aa85dec commit 207c54f

File tree

6 files changed

+253
-21
lines changed

6 files changed

+253
-21
lines changed
78.2 KB
Loading
78.5 KB
Loading

docs/install_setup.md renamed to docs/zh/install_setup.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ ppsci.utils.run_check()
6565

6666
- 编写自己的案例(假设案例名为demo)
6767

68-
推荐在 `examples/` 下新建 `demo` 文件夹,然后在 `demo` 文件夹下新建 `demo.py`,最后在 `demo.py` 文件中使用 PaddleScience 提供的 [API](./zh/api/arch.md) 编写代码
68+
推荐在 `examples/` 下新建 `demo` 文件夹,然后在 `demo` 文件夹下新建 `demo.py`,最后在 `demo.py` 文件中使用 PaddleScience 提供的 [API](./api/arch.md) 编写代码
6969

7070
``` py linenums="1" title="examples/demo/demo.py"
7171
import ppsci

docs/overview.md renamed to docs/zh/overview.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ PaddleScience 在代码结构上划分为 12 个模块。从一般深度学习
55
## 1. 整体工作流
66

77
<figure markdown>
8-
![workflow](./images/overview/workflow.jpg){ loading=lazy style="height:80%;width:80%"}
8+
![workflow](../images/overview/workflow.jpg){ loading=lazy style="height:80%;width:80%"}
99
</figure>
1010

1111
上图是 PaddleScience 的 workflow 示意图(以基于几何的问题求解为例),流程描述如下
@@ -21,18 +21,18 @@ PaddleScience 在代码结构上划分为 12 个模块。从一般深度学习
2121

2222
## 2. 模块简介
2323

24-
### 2.1 [Arch](./zh/api/arch.md)
24+
### 2.1 [Arch](./api/arch.md)
2525

2626
Arch 模块负责各种神经网络模型的组网、参数初始化、前向计算等功能,内置了多种模型供用户使用。
2727

28-
### 2.2 [AutoDiff](./zh/api/autodiff.md)
28+
### 2.2 [AutoDiff](./api/autodiff.md)
2929

3030
AutoDiff 模块负责计算高阶微分功能,内置基于 Paddle 自动微分机制的全局单例 `jacobian``hessian` 供用户使用。
3131

32-
### 2.3 [Constraint](./zh/api/constraint.md)
32+
### 2.3 [Constraint](./api/constraint.md)
3333

3434
<figure markdown>
35-
![constraint](./images/overview/constraint.jpg){ loading=lazy style="height:50%;width:50%"}
35+
![constraint](../images/overview/constraint.jpg){ loading=lazy style="height:50%;width:50%"}
3636
</figure>
3737

3838
为了在套件中统一物理信息驱动、数据驱动、数理融合三种求解方式,我们将数据构造、输入到输出的计算过程、损失函数等必要接口在其定义完毕之后,统一记录在 Constraint 这一模块中,有了这些接口,Constraint 就能表示不同的训练目标,如:
@@ -48,54 +48,54 @@ AutoDiff 模块负责计算高阶微分功能,内置基于 Paddle 自动微分
4848

4949
Data 模块负责数据的读取、包装和预处理,由以下 3 个子模块分别负责。
5050

51-
#### 2.4.1 [Dataset](./zh/api/data/dataset.md)
51+
#### 2.4.1 [Dataset](./api/data/dataset.md)
5252

5353
Dataset 模块存放各种数据集的包装类,将数据包装成统一的结构再用于读取。
5454

55-
#### 2.4.2 [Transform](./zh/api/data/process/transform.md)
55+
#### 2.4.2 [Transform](./api/data/process/transform.md)
5656

5757
Transform 模块存放各种基于单样本的数据预处理方法,包括数据平移 `Translate` 和数据缩放 `Scale`,一般与 `data.dataset` 结合使用。
5858

59-
#### 2.4.3 [BatchTransform](./zh/api/data/process/batch_transform.md)
59+
#### 2.4.3 [BatchTransform](./api/data/process/batch_transform.md)
6060

6161
BatchTransform 模块存放各种基于批样本的数据预处理方法。
6262

63-
### 2.5 [Equation](./zh/api/equation.md)
63+
### 2.5 [Equation](./api/equation.md)
6464

6565
<figure markdown>
66-
![equation](./images/overview/equation.jpg){ loading=lazy style="height:80%;width:80%" align="center" }
66+
![equation](../images/overview/equation.jpg){ loading=lazy style="height:80%;width:80%" align="center" }
6767
</figure>
6868

6969
Equation 模块负责定义各种常见方程的计算函数,如 `NavierStokes` 表示 N-S 方程,`Vibration` 表示振动方程,每个方程内部含有相关变量的计算函数。
7070

71-
### 2.6 [Geometry](./zh/api/geometry.md)
71+
### 2.6 [Geometry](./api/geometry.md)
7272

7373
<figure markdown>
74-
![geometry](./images/overview/geometry.jpg#center){ loading=lazy style="height:50%;width:50%" }
74+
![geometry](../images/overview/geometry.jpg#center){ loading=lazy style="height:50%;width:50%" }
7575
</figure>
7676

7777
Geometry 模块负责定义各种常见的几何形状,如 `Interval` 线段几何、`Rectangle` 矩形几何、`Sphere` 球面几何。
7878

79-
### 2.7 [Loss](./zh/api/loss.md)
79+
### 2.7 [Loss](./api/loss.md)
8080

8181
Loss 模块负责定义各种损失函数,在模型前向与方程计算完毕后,将结果与参考值计算损失值,供后续的梯度优化算法使用。
8282

83-
### 2.8 [Optimizer](./zh/api/optimizer.md)
83+
### 2.8 [Optimizer](./api/optimizer.md)
8484

8585
Optimizer 模块负责定义各种优化器,如 `SGD``Adam``LBFGS`
8686

87-
### 2.9 [Solver](./zh/api/solver.md)
87+
### 2.9 [Solver](./api/solver.md)
8888

8989
Solver 模块负责定义求解器,作为训练、评估、推理、可视化的启动和管理引擎。
9090

91-
### 2.10 [Utils](./zh/api/utils.md)
91+
### 2.10 [Utils](./api/utils.md)
9292

9393
Utils 模块内部存放了一些适用于多种场景下的工具类、函数,如在 `reader.py` 下的数据读取函数,在 `logger.py` 下的日志打印函数,以及在 `expression.py` 下的方程计算类。
9494

95-
### 2.11 [Validate](./zh/api/validate.md)
95+
### 2.11 [Validate](./api/validate.md)
9696

9797
Validator 模块负责定义各种评估器,用于模型训练完一个 epoch 后自动在指定数据上进行评估(可选,默认不开启训练时评估)并得到评估指标。
9898

99-
### 2.12 [Visualize](./zh/api/visualize.md)
99+
### 2.12 [Visualize](./api/visualize.md)
100100

101101
Visualizer 模块负责定义各种可视化器,用于模型评估完后在指定数据上进行预测(可选,默认不开启训练时可视化)并将结果保存成可视化的文件。

docs/zh/quickstart.md

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
# 快速开始
2+
3+
本文通过一个简单的 demo 及其扩展问题,介绍如何使用 PaddleScience 训练模型,解决一类方程学习与预测问题,并可视化预测结果。
4+
5+
## 1. 问题简介
6+
7+
假设我们希望用神经网络模型去拟合 $x \in [-\pi, \pi]$ 区间内,$u=sin(x)$ 这一函数。在拟合函数已知和未知两种情形下,如何去尽可能地准确拟合 $u=sin(x)$。
8+
9+
第一种场景下,假设已知目标函数 $u$ 的解析解就是 $u=sin(x)$,我们采用监督训练的思路,直接用该公式生成标签因变量 $u$,与自变量 $x$ 共同作为监督数据对模型进行训练。
10+
11+
第二种场景下,假设不知道目标函数 $u$ 的解析解,但我们知道其满足某种微分关系,我们这里以其中一个满足条件的微分方程 $\dfrac{\partial u} {\partial x}=cos(x)$ 为例,介绍如何生成数据进行训练。
12+
13+
## 2. 场景一
14+
15+
目标拟合函数:
16+
17+
$$
18+
u=sin(x), x \in [-\pi, \pi].
19+
$$
20+
21+
我们生成 $N$ 组数据对 $(x_i, u_i), i=1,...,N$ 作为监督数据进行训练即可。
22+
23+
在撰写代码之前,我们首先导入必要的包。
24+
25+
``` py
26+
import numpy as np
27+
import paddle
28+
29+
import ppsci
30+
from ppsci.utils import logger
31+
```
32+
33+
然后创建日志和模型保存目录供训练过程记录和保存使用,这一步是绝大部分案例在正式开始前都需要进行的操作。
34+
35+
``` py
36+
# set random seed for reproducibility
37+
ppsci.utils.misc.set_random_seed(42)
38+
39+
# set output directory
40+
output_dir = "./output_quick_start"
41+
42+
# initialize logger
43+
logger.init_logger("ppsci", f"{output_dir}/train.log", "info")
44+
```
45+
46+
接下来正式开始撰写代码。
47+
48+
首先定义问题区间,我们使用 `ppsci.geometry.Interval` 定义一个线段几何形状,方便后续在该线段上对 $x$ 进行采样。
49+
50+
``` py
51+
# set input 1D-geometry([-π, π])
52+
l_limit, r_limit = -np.pi, np.pi
53+
x_domain = ppsci.geometry.Interval(l_limit, r_limit)
54+
geom = {"domain": x_domain}
55+
```
56+
57+
然后定义一个简单的 3 层 MLP 模型。
58+
59+
``` py
60+
# set model to 3-layer MLP
61+
model = ppsci.arch.MLP(("x",), ("u",), 3, 64)
62+
```
63+
64+
上述代码表示模型接受自变量 $x$ 作为输入,输出预测结果 $\hat{u}$
65+
66+
然后我们定义已知的 $u=sin(x)$ 计算函数,作为 `ppsci.constraint.InteriorConstraint` 的参数,用于生成标签数据,`InteriorConstraint` 表示以给定的几何形状或数据集中的数据作为输入,联合给定的标签数据,指导模型进行优化。
67+
68+
``` py
69+
# set constraint on 1D-geometry([-π, π])
70+
iters_per_epoch = 100
71+
interior_constraint = ppsci.constraint.InteriorConstraint(
72+
output_expr={"u": lambda out: out["u"]},
73+
label_dict={"u": sin_compute_func},
74+
geom=geom["domain"],
75+
dataloader_cfg={
76+
"dataset": "NamedArrayDataset",
77+
"iters_per_epoch": iters_per_epoch,
78+
"sampler": {
79+
"name": "BatchSampler",
80+
"shuffle": True,
81+
},
82+
"batch_size": 32,
83+
},
84+
loss=ppsci.loss.MSELoss(),
85+
)
86+
# wrap constraint(s) into one dict
87+
constraint = {interior_constraint.name: interior_constraint}
88+
```
89+
90+
此处的 `interior_constraint` 表示一个训练目标,即我们希望在 $[-\pi, \pi]$ 这段区间内,优化模型让模型的预测结果 $\hat{u}$ 尽可能地接近它的标签值 $u$。
91+
92+
接下来就可以开始定义模型训练相关的内容,比如训练轮数、优化器
93+
94+
``` py
95+
# set training hyper-parameters
96+
epochs = 10
97+
# set optimizer
98+
optimizer = ppsci.optimizer.Adam(1e-3)((model,))
99+
```
100+
101+
当训练完成,我们希望在 $[-\pi, \pi]$ 上取 1000 个点进行预测并将结果可视化,以此查看训练完毕的模型是否具备一定的预测能力。
102+
103+
``` py
104+
# set visualizer
105+
visualize_input_dict = {"x": paddle.linspace(l_limit, r_limit, 1000).reshape([1000, 1])}
106+
visualize_input_dict["u_ref"] = paddle.sin(visualize_input_dict["x"])
107+
visualizer = {
108+
"visualize_u": ppsci.visualize.VisualizerScatter1D(
109+
visualize_input_dict,
110+
("x",),
111+
{"u_pred": lambda out: out["u"], "u_ref": lambda out: out["u_ref"]},
112+
prefix="u=sin(x)",
113+
),
114+
}
115+
```
116+
117+
最后将上述定义的对象传递给训练调度类 `Solver`,即可开始模型训练
118+
119+
``` py
120+
# initialize solver
121+
solver = ppsci.solver.Solver(
122+
model,
123+
constraint,
124+
output_dir,
125+
optimizer,
126+
epochs=epochs,
127+
iters_per_epoch=iters_per_epoch,
128+
geom=geom,
129+
visualizer=visualizer,
130+
)
131+
# train model
132+
solver.train()
133+
```
134+
135+
训练完毕后再用刚才取的 1000 个点进行可视化
136+
137+
``` py
138+
# visualize prediction after finished training
139+
solver.visualize()
140+
```
141+
142+
训练记录下所示
143+
144+
``` log
145+
...
146+
...
147+
ppsci INFO: [Train][Epoch 10/10][Iter: 60/100] lr: 0.00100000, loss: 0.00084, EQ: 0.00084, batch_cost: 0.00193s, reader_cost: 0.00017s, ips: 16607.08697 samples/s, eta: 0:00:00
148+
ppsci INFO: [Train][Epoch 10/10][Iter: 70/100] lr: 0.00100000, loss: 0.00082, EQ: 0.00082, batch_cost: 0.00193s, reader_cost: 0.00016s, ips: 16603.29541 samples/s, eta: 0:00:00
149+
ppsci INFO: [Train][Epoch 10/10][Iter: 80/100] lr: 0.00100000, loss: 0.00078, EQ: 0.00078, batch_cost: 0.00193s, reader_cost: 0.00016s, ips: 16612.34228 samples/s, eta: 0:00:00
150+
ppsci INFO: [Train][Epoch 10/10][Iter: 90/100] lr: 0.00100000, loss: 0.00076, EQ: 0.00076, batch_cost: 0.00193s, reader_cost: 0.00015s, ips: 16616.61847 samples/s, eta: 0:00:00
151+
ppsci INFO: [Train][Epoch 10/10][Iter: 100/100] lr: 0.00100000, loss: 0.00075, EQ: 0.00075, batch_cost: 0.00191s, reader_cost: 0.00015s, ips: 16715.53436 samples/s, eta: 0:00:00
152+
ppsci INFO: [Train][Epoch 10/10][Avg] loss: 0.00075, EQ: 0.00075
153+
ppsci INFO: Finish saving checkpoint to ./output_quick_start/checkpoints/latest
154+
ppsci INFO: 1D result is saved to ./output_quick_start/visual/epoch_0/u=sin(x).png
155+
ppsci INFO: [Visualize][Epoch 0] Finished visualization.
156+
```
157+
158+
预测结果如下所示
159+
160+
![u=sin(x) prediction](../images/quickstart/u_pred_case1.png)
161+
162+
## 3. 场景二
163+
164+
可以看到场景一的监督训练方式能较好地解决函数拟合问题,但一般情况下我们是无法得知拟合函数本身的解析式的,因此也无法直接构造因变量的监督数据。
165+
166+
虽然无法求出解析式直接构造监督数据,但往往可以利用相关数学知识,推导出目标拟合函数符合的某种数学关系,以训练模型以满足这种数学关系的方式,达到“间接”优化模型的目的。
167+
168+
假设我们不再使用 $u=sin(x)$ 这一先验公式,因而无法生成标签数据 $u$。因此我们使用 $\dfrac{\partial u} {\partial x}=cos(x)$ 这一方程,构造数据对 $(x_i, cos(x_i)), i=1,...,N$。
169+
这意味着我们仍然能保持模型的输入、输出不变,但优化目标变成了:让 $\dfrac{\partial \hat{u}} {\partial x}$ 尽可能地接近 $cos(x)$。即
170+
171+
基于以上理论,我们对场景一的代码进行少量的改写即可得到本场景二的代码。
172+
173+
首先由于我们需要使用一阶微分这一操作,因此在代码开头处需导入一阶微分 API
174+
175+
``` py hl_lines="5"
176+
import numpy as np
177+
import paddle
178+
179+
import ppsci
180+
from ppsci.autodiff import jacobian
181+
from ppsci.utils import logger
182+
```
183+
184+
然后将原来的标签生成函数改为微分关系标签生成函数
185+
186+
``` py
187+
# standard solution of cos(x)
188+
def cos_compute_func(data: dict):
189+
return np.cos(data["x"])
190+
```
191+
192+
最后将 `interior_constraint` 这一约束条件从约束“模型输出”,改为约束“模型输出对输入的一阶微分”
193+
194+
``` py hl_lines="2 3"
195+
interior_constraint = ppsci.constraint.InteriorConstraint(
196+
output_expr={"du_dx": lambda out: jacobian(out["u"], out["x"])},
197+
label_dict={"du_dx": cos_compute_func},
198+
geom=geom["domain"],
199+
dataloader_cfg={
200+
"dataset": "NamedArrayDataset",
201+
"iters_per_epoch": iters_per_epoch,
202+
"sampler": {
203+
"name": "BatchSampler",
204+
"shuffle": True,
205+
},
206+
"batch_size": 32,
207+
},
208+
loss=ppsci.loss.MSELoss(),
209+
)
210+
```
211+
212+
修改完毕后执行训练,训练日志如下所示
213+
214+
``` log
215+
...
216+
...
217+
ppsci INFO: [Train][Epoch 10/10][Iter: 70/100] lr: 0.00100000, loss: 0.00035, EQ: 0.00035, batch_cost: 0.01183s, reader_cost: 0.00017s, ips: 2705.18917 samples/s, eta: 0:00:00
218+
ppsci INFO: [Train][Epoch 10/10][Iter: 80/100] lr: 0.00100000, loss: 0.00035, EQ: 0.00035, batch_cost: 0.01133s, reader_cost: 0.00017s, ips: 2823.74760 samples/s, eta: 0:00:00
219+
ppsci INFO: [Train][Epoch 10/10][Iter: 90/100] lr: 0.00100000, loss: 0.00036, EQ: 0.00036, batch_cost: 0.01141s, reader_cost: 0.00017s, ips: 2803.77351 samples/s, eta: 0:00:00
220+
ppsci INFO: [Train][Epoch 10/10][Iter: 100/100] lr: 0.00100000, loss: 0.00036, EQ: 0.00036, batch_cost: 0.01106s, reader_cost: 0.00016s, ips: 2892.93859 samples/s, eta: 0:00:00
221+
ppsci INFO: [Train][Epoch 10/10][Avg] loss: 0.00036, EQ: 0.00036
222+
ppsci INFO: Finish saving checkpoint to ./output_quick_start_2/checkpoints/latest
223+
ppsci INFO: 1D result is saved to ./output_quick_start_2/visual/epoch_0/u=sin(x).png
224+
ppsci INFO: [Visualize][Epoch 0] Finished visualization.
225+
```
226+
227+
预测结果如下所示
228+
229+
![u=sin(x) prediction](../images/quickstart/u_pred_case2.png)
230+
231+
可以发现利用微分关系训练的模型仍然具备良好的预测能力。

mkdocs.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ copyright: Copyright &copy; 2022 - 2023 PaddlePaddle
3030
nav:
3131
- PaddleScience:
3232
- 主页: index.md
33-
- 功能介绍: overview.md
34-
- 安装使用: install_setup.md
33+
- 功能介绍: zh/overview.md
34+
- 安装使用: zh/install_setup.md
35+
- 快速开始: zh/quickstart.md
3536
- 经典案例:
3637
- PINNs:
3738
- ViV: zh/examples/viv.md

0 commit comments

Comments
 (0)