@@ -6,15 +6,15 @@ PaddleScience 相关的论文复现、API 开发任务开始之前需提交 RFC
66
77## 1. 准备工作
88
9- 1 . 将 PaddleScience fork 到** 自己的仓库**
9+ 1 . 在网页上将 PaddleScience fork 到** 自己的仓库**
10102 . 克隆** 自己仓库** 里的 PaddleScience 到本地,并进入该目录
1111
1212 ``` sh
1313 git clone -b develop https://github.com/USER_NAME/PaddleScience.git
1414 cd PaddleScience
1515 ```
1616
17- 上方 ` clone` 命令中的 ` USER_NAME` 字段请填入的自己的用户名 。
17+ 上方 ` clone` 命令中的 ` USER_NAME` 字段请填入自己的 github 用户名 。
1818
19193. 安装必要的依赖包
2020
@@ -602,23 +602,191 @@ solver = ppsci.solver.Solver(
602602)
603603` ` `
604604
605- # ## 2.12 训练
605+ # ## 2.12 编写配置文件[重要]
606+
607+ ??? info " 内容较长,点击展开"
608+
609+ 经过上述步骤的开发,案例代码的主要部分已经完成。
610+ 当我们想基于这份代码运行一些调优实验,从而得到更好的结果,或更好地对运行参数设置进行管理,
611+ 则可以利用 PaddleScience 提供的配置管理系统,将实验运行参数从代码中分离出来,写到 ` yaml` 格式的配置文件中,从而更好的管理、记录、调优实验。
612+
613+ 以 ` viv` 案例代码为例,在运行时我们需要在适当的位置设置方程参数、STL 文件路径、训练轮数、` batch_size` 、随机种子、学习率等超参数,如下所示。
614+
615+ ` ` ` py
616+ ...
617+ # set dataloader config
618+ train_dataloader_cfg = {
619+ " dataset" : {
620+ " name" : " MatDataset" ,
621+ " file_path" : cfg.VIV_DATA_PATH,
622+ " input_keys" : (" t_f" ,),
623+ " label_keys" : (" eta" , " f" ),
624+ " weight_dict" : {" eta" : 100},
625+ },
626+ " batch_size" : cfg.TRAIN.batch_size,
627+ " sampler" : {
628+ " name" : " BatchSampler" ,
629+ " drop_last" : False,
630+ " shuffle" : True,
631+ },
632+ }
633+ ...
634+ ...
635+ # set optimizer
636+ lr_scheduler = ppsci.optimizer.lr_scheduler.Step(**cfg.TRAIN.lr_scheduler) ()
637+ ...
638+ ` ` `
639+
640+ 这些参数在实验过程中随时可能作为变量而被手动调整,在调整过程中如何避免频繁修改源代码导致试验记录混乱、保障记录完整可追溯便是一大问题,因此 PaddleScience 提供了基于 hydra + omegaconf 的
641+ 配置文件管理系统来解决这一问题。
642+
643+ 将已有的代码修改成配置文件控制的方式非常简单,只需要将必要的参数写到 ` yaml` 文件中,然后通过 hydra 在程序运行时读取、解析该文件,通过其内容控制实验运行即可,以 ` viv` 案例为例,具体包含以下几个步骤。
644+
645+ 1. 则需在代码文件 ` viv.py` 所在目录下新建 ` conf` 文件夹,并在 ` conf` 下新建与 ` viv.py` 同名的 ` viv.yaml` 文件,如下所示。
646+
647+ ` ` ` sh hl_lines=" 3-4"
648+ PaddleScience/examples/fsi/
649+ ├── viv.py
650+ └── conf
651+ └── viv.yaml
652+ ` ` `
653+
654+ 2. 将 ` viv.py` 中必要的超参数按照其语义填写到 ` viv.yaml` 的各个层级的配置中,如通用参数 ` mode` 、` output_dir` 、` seed` 、方程参数、文件路径等,直接填写在一级层级;而只与模型、训练相关的模型结构参数、训练轮数等,只需分别填写在 ` MODEL` 、` TRAIN` 层级下即可(` EVAL` 层级同理)。
655+ 3. 将已有的 ` train` 和 ` evaluate` 函数修改为接受一个参数 ` cfg` (` cfg` 即为读取进来的 ` yaml` 文件里的内容,并以字典的形式存储),并将其内部的超参数统一改为通过 ` cfg.xxx` 获取而非原先的直接设置为数字或字符串,如下所示。
656+
657+ ` ` ` py
658+ from omegaconf import DictConfig
659+
660+ def train(cfg: DictConfig):
661+ # 训练代码...
662+
663+ def evaluate(cfg: DictConfig):
664+ # 评估代码...
665+ ` ` `
666+
667+ 4. 新建一个 ` main` 函数(同样接受且只接受一个 ` cfg` 参数),它负责根据 ` cfg.mode` 来调用 ` train` 或 ` evaluate` 函数,并 ` main` 函数加上装饰器 ` @hydra.main(version_base=None, config_path=" ./conf" , config_name=" viv.yaml" )` ,如下所示。
668+
669+ ` ` ` py
670+ @hydra.main(version_base=None, config_path=" ./conf" , config_name=" viv.yaml" )
671+ def main(cfg: DictConfig):
672+ if cfg.mode == " train" :
673+ train(cfg)
674+ elif cfg.mode == " eval" :
675+ evaluate(cfg)
676+ else:
677+ raise ValueError(f" cfg.mode should in ['train', 'eval'], but got '{cfg.mode}'" )
678+
679+ ` ` `
680+
681+ 5. 在主程序的启动入口 ` if __name__ == " __main__" :` 中启动 ` main()` 即可,如下所示。
682+
683+ ` ` ` py
684+ if __name__ == " __main__" :
685+ main ()
686+ ` ` `
687+
688+ 全部改造完毕后,` viv.py` 和 ` viv.yaml` 如下所示。
689+
690+ === " examples/fsi/viv.py"
691+
692+ ` ` ` py linenums=" 1"
693+ --8< --
694+ examples/fsi/viv.py
695+ --8< --
696+ ` ` `
697+
698+ === " examples/fsi/conf/viv.yaml"
699+
700+ ` ` ` yaml linenums=" 1" hl_lines=" 1 4 19 25 31 34 42 59"
701+ hydra: # (1)
702+ run:
703+ # dynamic output directory according to running time and override name
704+ dir: outputs_VIV/${now:% Y-% m-% d} /${now:% H-% M-% S} /${hydra.job.override_dirname}
705+ job:
706+ name: ${mode} # name of logfile
707+ chdir: false # keep current working direcotry unchaned
708+ config:
709+ override_dirname:
710+ exclude_keys:
711+ - TRAIN.checkpoint_path
712+ - TRAIN.pretrained_model_path
713+ - EVAL.pretrained_model_path
714+ - mode
715+ - output_dir
716+ - log_freq
717+ callbacks:
718+ init_callback:
719+ _target_: ppsci.utils.callbacks.InitCallback # (2)
720+ sweep:
721+ # output directory for multirun
722+ dir: ${hydra.run.dir}
723+ subdir: ./
724+
725+ # general settings (3)
726+ mode: train # running mode: train/eval
727+ seed: 42
728+ output_dir: ${hydra: run.dir}
729+ log_freq: 20
730+
731+ # set data file path (4)
732+ VIV_DATA_PATH: " ./VIV_Training_Neta100.mat"
733+
734+ # model settings (5)
735+ MODEL:
736+ input_keys: [" t_f" ]
737+ output_keys: [" eta" ]
738+ num_layers: 5
739+ hidden_size: 50
740+ activation: " tanh"
741+
742+ # training settings (6)
743+ TRAIN:
744+ epochs: 100000
745+ iters_per_epoch: 1
746+ save_freq: 10000
747+ eval_during_train: true
748+ eval_freq: 1000
749+ batch_size: 100
750+ lr_scheduler:
751+ epochs: ${TRAIN.epochs}
752+ iters_per_epoch: ${TRAIN.iters_per_epoch}
753+ learning_rate: 0.001
754+ step_size: 20000
755+ gamma: 0.9
756+ pretrained_model_path: null
757+ checkpoint_path: null
758+
759+ # evaluation settings (7)
760+ EVAL:
761+ pretrained_model_path: null
762+ batch_size: 32
763+ ` ` `
764+
765+ 1. ` hydra:` 下的配置段用于控制 hydra 运行时的一些行为,如输出目录、回调函数等,用户只需要修改 ` dir:` 后的内容,即可控制输出目录,其余的字段一般不需关注。
766+ 2. ` callbacks:` 下的配置段用于控制回调函数,如此处添加了负责程序运行前自动固定随机种子、初始化 logger 并创建输出目录的回调函数 ` InitCallback` ,一般不需要修改这里。
767+ 3. ` general settings` 下的四个通用设置,包括运行模式 ` mode` 、随机数种子 ` seed` 、输出目录 ` output_dir` 和日志记录频率 ` log_freq` 。
768+ 4. ` set XXX file path` 下的字段,用于控制数据集的路径,如 ` VIV_DATA_PATH` 等。
769+ 5. ` MODEL` 下的字段,用于控制模型结构,如 ` disp_net` 、` stress_net` 等。
770+ 6. ` TRAIN:` 下的字段,用于控制训练过程,如 ` epochs` 、` iters_per_epoch` 等
771+ 7. ` EVAL:` 下的字段,用于控制评估过程,如 ` pretrained_model_path` 、` eval_with_no_grad` 等
772+
773+ # ## 2.13 训练
606774
607775PaddleScience 模型的训练只需调用一行代码。
608776
609777` ` ` py title=" examples/demo/demo.py"
610778solver.train ()
611779` ` `
612780
613- # ## 2.13 评估
781+ # ## 2.14 评估
614782
615783PaddleScience 模型的评估只需调用一行代码。
616784
617785` ` ` py title=" examples/demo/demo.py"
618786solver.eval ()
619787` ` `
620788
621- # ## 2.14 可视化[可选]
789+ # ## 2.15 可视化[可选]
622790
623791若 ` Solver` 实例化时传入了 ` visualizer` 参数,则 PaddleScience 模型的可视化只需调用一行代码。
624792
@@ -632,7 +800,7 @@ solver.visualize()
632800
633801# # 3. 编写文档
634802
635- 除了案例代码,PaddleScience 同时存放了对应案例的详细文档,使用 Markdown + [Mkdocs-Material](https://squidfunk.github.io/mkdocs-material/) 进行编写和渲染,撰写文档步骤如下。
803+ 除了案例代码,PaddleScience 同时存放了对应案例的详细文档,使用 Markdown + [Mkdocs](https://www.mkdocs.org/) + [Mkdocs -Material](https://squidfunk.github.io/mkdocs-material/) 进行编写和渲染,撰写文档步骤如下。
636804
637805# ## 3.1 安装必要依赖包
638806
@@ -686,7 +854,7 @@ PaddleScience 是一个开源的代码库,由多人共同参与开发,因此
686854PaddleScience 使用了包括 [isort](https://github.com/PyCQA/isort#installing-isort)、[black](https://github.com/psf/black) 等自动化代码检查、格式化插件,
687855让 commit 的代码遵循 python [PEP8](https://pep8.org/) 代码风格规范。
688856
689- 因此在 commit 您的代码之前,请务必先执行以下命令安装 ` pre-commit` 。
857+ 因此在 commit 您的代码之前,请务必先执行以下命令安装 ` pre-commit` ,否则提交的 PR 会被 code-style 检测到代码未格式化而无法合入 。
690858
691859` ` ` sh
692860pip install pre-commit
0 commit comments