From 3c0cedc043bdd0e0ef2e67e7eba047c6feb93996 Mon Sep 17 00:00:00 2001 From: HydrogenSulfate <490868991@qq.com> Date: Thu, 23 Nov 2023 07:26:20 +0000 Subject: [PATCH 1/4] fix(test=document_fix) --- docs/zh/examples/phylstm.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/docs/zh/examples/phylstm.md b/docs/zh/examples/phylstm.md index 2ee189cc7b..007dd738ee 100644 --- a/docs/zh/examples/phylstm.md +++ b/docs/zh/examples/phylstm.md @@ -44,21 +44,6 @@ python phylstm3.py mode=eval EVAL.pretrained_model_path=https://paddle-org.bj.bcebos.com/paddlescience/models/phylstm/phylstm3_pretrained.pdparams ``` -| 预训练模型 | 指标 | -|:--| :--| -| [phylstm2_pretrained.pdparams](https://paddle-org.bj.bcebos.com/paddlescience/models/phylstm/phylstm2_pretrained.pdparams) | loss(sup_valid): 0.00799 | -| [phylstm3_pretrained.pdparams](https://paddle-org.bj.bcebos.com/paddlescience/models/phylstm/phylstm3_pretrained.pdparams) | loss(sup_valid): 0.03098 | - - === phylstm3 - - ``` sh - # linux - wget https://paddle-org.bj.bcebos.com/paddlescience/datasets/PhyLSTM/data_boucwen.mat - # windows - # curl https://paddle-org.bj.bcebos.com/paddlescience/datasets/PhyLSTM/data_boucwen.mat --output data_boucwen.mat - python phylstm3.py mode=eval EVAL.pretrained_model_path=https://paddle-org.bj.bcebos.com/paddlescience/models/phylstm/phylstm3_pretrained.pdparams - ``` - | 预训练模型 | 指标 | |:--| :--| | [phylstm2_pretrained.pdparams](https://paddle-org.bj.bcebos.com/paddlescience/models/phylstm/phylstm2_pretrained.pdparams) | loss(sup_valid): 0.00799 | From 7930574ab87bd1985eba60c5ffb889824cd8461d Mon Sep 17 00:00:00 2001 From: HydrogenSulfate <490868991@qq.com> Date: Fri, 24 Nov 2023 15:56:44 +0000 Subject: [PATCH 2/4] pretty evaluation output with prettytable --- examples/darcy/darcy2d.py | 2 +- ppsci/solver/solver.py | 18 +++++++++++++++--- ppsci/utils/misc.py | 6 ++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/examples/darcy/darcy2d.py b/examples/darcy/darcy2d.py index 7f0a3646f8..9c004c157d 100644 --- a/examples/darcy/darcy2d.py +++ b/examples/darcy/darcy2d.py @@ -246,7 +246,7 @@ def poisson_ref_compute_func(_in): cfg.NPOINT_PDE + cfg.NPOINT_BC, evenly=True ) visualizer = { - "visualize_p": ppsci.visualize.VisualizerVtu( + "visualize_p_ux_uy": ppsci.visualize.VisualizerVtu( vis_points, { "p": lambda d: d["p"], diff --git a/ppsci/solver/solver.py b/ppsci/solver/solver.py index 812be1ba68..3edfbb6af8 100644 --- a/ppsci/solver/solver.py +++ b/ppsci/solver/solver.py @@ -29,6 +29,7 @@ import numpy as np import paddle import paddle.distributed as dist +import prettytable import sympy as sp import visualdl as vdl from packaging import version @@ -461,10 +462,21 @@ def eval(self, epoch_id: int = 0) -> Tuple[float, Dict[str, Dict[str, float]]]: self.eval_func = ppsci.solver.eval.eval_func result = self.eval_func(self, epoch_id, self.log_freq) - metric_msg = ", ".join( - [self.eval_output_info[key].avg_info for key in self.eval_output_info] + metric_table = prettytable.PrettyTable( + ["Name", "Value"], + title=f"Evaluation Metric(s){'' if epoch_id == 0 else f' at epoch {epoch_id}'}", + align="l", ) - logger.info(f"[Eval][Epoch {epoch_id}][Avg] {metric_msg}") + + loss_msg = [] + for name, value in self.eval_output_info.items(): + if name.startswith("loss"): + loss_msg.append(f"{name}: {value.avg_fmt}") + else: + metric_table.add_row([name, value.avg_fmt]) + loss_msg = ", ".join(loss_msg) + + logger.info(f"[Eval][Epoch {epoch_id}][Avg] {loss_msg}\n{metric_table}") self.eval_output_info.clear() return result diff --git a/ppsci/utils/misc.py b/ppsci/utils/misc.py index f21004f816..c6f3e7f187 100644 --- a/ppsci/utils/misc.py +++ b/ppsci/utils/misc.py @@ -90,6 +90,12 @@ def avg_info(self): self.avg = float(self.avg) return f"{self.name}: {self.avg:.5f}" + @property + def avg_fmt(self): + if isinstance(self.avg, paddle.Tensor): + self.avg = float(self.avg) + return f"{self.avg:.5e}" + @property def total(self): return f"{self.name}_sum: {self.sum:{self.fmt}}{self.postfix}" From 9e88bf16dacffaac4953552844a90850210db86f Mon Sep 17 00:00:00 2001 From: HydrogenSulfate <490868991@qq.com> Date: Wed, 24 Apr 2024 02:20:38 +0800 Subject: [PATCH 3/4] remove epoch id when ony evaluating --- ppsci/solver/eval.py | 13 +++++++------ ppsci/solver/printer.py | 16 +++++++++++----- ppsci/solver/solver.py | 20 ++++++++++++++------ ppsci/solver/visu.py | 9 ++++++--- ppsci/utils/download.py | 1 + ppsci/utils/ema.py | 2 +- 6 files changed, 40 insertions(+), 21 deletions(-) diff --git a/ppsci/solver/eval.py b/ppsci/solver/eval.py index 8087d45ced..82016c06a1 100644 --- a/ppsci/solver/eval.py +++ b/ppsci/solver/eval.py @@ -17,6 +17,7 @@ import time from typing import TYPE_CHECKING from typing import Dict +from typing import Optional from typing import Tuple from typing import Union @@ -59,7 +60,7 @@ def _get_dataset_length( def _eval_by_dataset( - solver: "solver.Solver", epoch_id: int, log_freq: int + solver: "solver.Solver", epoch_id: Optional[int], log_freq: int ) -> Tuple[float, Dict[str, Dict[str, float]]]: """Evaluate with computing metric on total samples(default process). @@ -68,7 +69,7 @@ def _eval_by_dataset( Args: solver (solver.Solver): Main Solver. - epoch_id (int): Epoch id. + epoch_id (Optional[int]): Epoch id. log_freq (int): Log evaluation information every `log_freq` steps. Returns: @@ -189,7 +190,7 @@ def _eval_by_dataset( def _eval_by_batch( - solver: "solver.Solver", epoch_id: int, log_freq: int + solver: "solver.Solver", epoch_id: Optional[int], log_freq: int ) -> Tuple[float, Dict[str, Dict[str, float]]]: """Evaluate with computing metric by batch, which is memory-efficient. @@ -199,7 +200,7 @@ def _eval_by_batch( Args: solver (solver.Solver): Main Solver. - epoch_id (int): Epoch id. + epoch_id (Optional[int]): Epoch id. log_freq (int): Log evaluation information every `log_freq` steps. Returns: @@ -303,13 +304,13 @@ def _eval_by_batch( def eval_func( - solver: "solver.Solver", epoch_id: int, log_freq: int + solver: "solver.Solver", epoch_id: Optional[int], log_freq: int ) -> Tuple[float, Dict[str, Dict[str, float]]]: """Evaluation function. Args: solver (solver.Solver): Main Solver. - epoch_id (int): Epoch id. + epoch_id (Optional[int]): Epoch id. log_freq (int): Log evaluation information every `log_freq` steps. Returns: diff --git a/ppsci/solver/printer.py b/ppsci/solver/printer.py index 1ccab50eeb..acc3caf900 100644 --- a/ppsci/solver/printer.py +++ b/ppsci/solver/printer.py @@ -132,11 +132,17 @@ def log_eval_info( epoch_width = len(str(solver.epochs)) iters_width = len(str(iters_per_epoch)) - logger.info( - f"[Eval][Epoch {epoch_id:>{epoch_width}}/{solver.epochs}]" - f"[Iter {iter_id:>{iters_width}}/{iters_per_epoch}] " - f"{metric_msg}, {time_msg}, {ips_msg}, {eta_msg}" - ) + if isinstance(epoch_id, int): + logger.info( + f"[Eval][Epoch {epoch_id:>{epoch_width}}/{solver.epochs}]" + f"[Iter {iter_id:>{iters_width}}/{iters_per_epoch}] " + f"{metric_msg}, {time_msg}, {ips_msg}, {eta_msg}" + ) + else: + logger.info( + f"[Eval] [Iter {iter_id:>{iters_width}}/{iters_per_epoch}] " + f"{metric_msg}, {time_msg}, {ips_msg}, {eta_msg}" + ) # logger.scalar( # { diff --git a/ppsci/solver/solver.py b/ppsci/solver/solver.py index 2fea206c6c..5e521de497 100644 --- a/ppsci/solver/solver.py +++ b/ppsci/solver/solver.py @@ -619,11 +619,13 @@ def finetune(self, pretrained_model_path: str) -> None: self.train() @misc.run_on_eval_mode - def eval(self, epoch_id: int = 0) -> Tuple[float, Dict[str, Dict[str, float]]]: + def eval( + self, epoch_id: Optional[int] = None + ) -> Tuple[float, Dict[str, Dict[str, float]]]: """Evaluation. Args: - epoch_id (int, optional): Epoch id. Defaults to 0. + epoch_id (Optional[int]): Epoch id. Defaults to None. Returns: Tuple[float, Dict[str, Dict[str, float]]]: A targe metric value(float) and @@ -636,23 +638,29 @@ def eval(self, epoch_id: int = 0) -> Tuple[float, Dict[str, Dict[str, float]]]: metric_msg = ", ".join( [self.eval_output_info[key].avg_info for key in self.eval_output_info] ) - logger.info(f"[Eval][Epoch {epoch_id}][Avg] {metric_msg}") + if isinstance(epoch_id, int): + logger.info(f"[Eval][Epoch {epoch_id}][Avg] {metric_msg}") + else: + logger.info(f"[Eval][Avg] {metric_msg}") self.eval_output_info.clear() return result @misc.run_on_eval_mode - def visualize(self, epoch_id: int = 0): + def visualize(self, epoch_id: Optional[int] = None): """Visualization. Args: - epoch_id (int, optional): Epoch id. Defaults to 0. + epoch_id (Optional[int]): Epoch id. Defaults to None. """ # set visualize func self.visu_func = ppsci.solver.visu.visualize_func self.visu_func(self, epoch_id) - logger.info(f"[Visualize][Epoch {epoch_id}] Finish visualization") + if isinstance(epoch_id, int): + logger.info(f"[Visualize][Epoch {epoch_id}] Finish visualization") + else: + logger.info("[Visualize] Finish visualization") @misc.run_on_eval_mode def predict( diff --git a/ppsci/solver/visu.py b/ppsci/solver/visu.py index 2b00ed421d..80e11abe75 100644 --- a/ppsci/solver/visu.py +++ b/ppsci/solver/visu.py @@ -17,6 +17,7 @@ import os import os.path as osp from typing import TYPE_CHECKING +from typing import Optional import paddle @@ -26,12 +27,12 @@ from ppsci import solver -def visualize_func(solver: "solver.Solver", epoch_id: int): +def visualize_func(solver: "solver.Solver", epoch_id: Optional[int]): """Visualization program. Args: solver (solver.Solver): Main Solver. - epoch_id (int): Epoch id. + epoch_id (Optional[int]): Epoch id. """ for _, _visualizer in solver.visualizer.items(): all_input = misc.Prettydefaultdict(list) @@ -87,7 +88,9 @@ def visualize_func(solver: "solver.Solver", epoch_id: int): # save visualization with misc.RankZeroOnly(solver.rank) as is_master: if is_master: - visual_dir = osp.join(solver.output_dir, "visual", f"epoch_{epoch_id}") + visual_dir = osp.join(solver.output_dir, "visual") + if epoch_id: + visual_dir = osp.join(visual_dir, f"epoch_{epoch_id}") os.makedirs(visual_dir, exist_ok=True) _visualizer.save( osp.join(visual_dir, _visualizer.prefix), diff --git a/ppsci/utils/download.py b/ppsci/utils/download.py index 78d33f82cd..a5f00aca62 100644 --- a/ppsci/utils/download.py +++ b/ppsci/utils/download.py @@ -157,6 +157,7 @@ def _download(url, path, md5sum=None): if chunk: f.write(chunk) shutil.move(tmp_fullname, fullname) + logger.message(f"Finished downloading pretrained model and saved to {fullname}") return fullname diff --git a/ppsci/utils/ema.py b/ppsci/utils/ema.py index 2664b2184b..690ee6fda8 100644 --- a/ppsci/utils/ema.py +++ b/ppsci/utils/ema.py @@ -41,7 +41,7 @@ def __init__(self, model: nn.Layer, decay: Optional[float] = None): self.model = model # As a quick reference to online model self.decay = decay - self.params_shadow: Dict[str, paddle.Tensor] = {} # ema param or bufer + self.params_shadow: Dict[str, paddle.Tensor] = {} # ema param or buffer self.params_backup: Dict[str, paddle.Tensor] = {} # used for apply and restore for name, param_or_buffer in itertools.chain( self.model.named_parameters(), self.model.named_buffers() From 8100f9195d9b5714b69142d7c1647aef781dc254 Mon Sep 17 00:00:00 2001 From: HydrogenSulfate <490868991@qq.com> Date: Wed, 24 Apr 2024 05:08:26 +0000 Subject: [PATCH 4/4] hidden epoch information when not evaluating on flying --- examples/darcy/darcy2d.py | 2 +- ppsci/solver/printer.py | 2 +- ppsci/solver/solver.py | 19 ++++--------------- ppsci/utils/misc.py | 6 ------ 4 files changed, 6 insertions(+), 23 deletions(-) diff --git a/examples/darcy/darcy2d.py b/examples/darcy/darcy2d.py index 9c004c157d..8937235dd7 100644 --- a/examples/darcy/darcy2d.py +++ b/examples/darcy/darcy2d.py @@ -109,7 +109,7 @@ def poisson_ref_compute_func(_in): cfg.NPOINT_PDE + cfg.NPOINT_BC, evenly=True ) visualizer = { - "visualize_p": ppsci.visualize.VisualizerVtu( + "visualize_p_ux_uy": ppsci.visualize.VisualizerVtu( vis_points, { "p": lambda d: d["p"], diff --git a/ppsci/solver/printer.py b/ppsci/solver/printer.py index acc3caf900..6439b16b9a 100644 --- a/ppsci/solver/printer.py +++ b/ppsci/solver/printer.py @@ -140,7 +140,7 @@ def log_eval_info( ) else: logger.info( - f"[Eval] [Iter {iter_id:>{iters_width}}/{iters_per_epoch}] " + f"[Eval][Iter {iter_id:>{iters_width}}/{iters_per_epoch}] " f"{metric_msg}, {time_msg}, {ips_msg}, {eta_msg}" ) diff --git a/ppsci/solver/solver.py b/ppsci/solver/solver.py index f32c734957..f7a00aa8fc 100644 --- a/ppsci/solver/solver.py +++ b/ppsci/solver/solver.py @@ -33,7 +33,6 @@ import numpy as np import paddle import paddle.distributed as dist -import prettytable import sympy as sp import visualdl as vdl from omegaconf import DictConfig @@ -636,24 +635,14 @@ def eval( self.eval_func = ppsci.solver.eval.eval_func result = self.eval_func(self, epoch_id, self.log_freq) - metric_table = prettytable.PrettyTable( - ["Name", "Value"], - title=f"Evaluation Metric(s){'' if epoch_id else f' at epoch {epoch_id}'}", - align="l", + metric_msg = ", ".join( + [self.eval_output_info[key].avg_info for key in self.eval_output_info] ) - loss_msg = [] - for name, value in self.eval_output_info.items(): - if name.startswith("loss"): - loss_msg.append(f"{name}: {value.avg_fmt}") - else: - metric_table.add_row([name, value.avg_fmt]) - loss_msg = ", ".join(loss_msg) - if isinstance(epoch_id, int): - logger.info(f"[Eval][Epoch {epoch_id}][Avg] {loss_msg}\n{metric_table}") + logger.info(f"[Eval][Epoch {epoch_id}][Avg] {metric_msg}") else: - logger.info(f"[Eval][Avg] {loss_msg}\n{metric_table}") + logger.info(f"[Eval][Avg] {metric_msg}") self.eval_output_info.clear() return result diff --git a/ppsci/utils/misc.py b/ppsci/utils/misc.py index 011d8d8f04..df29db3037 100644 --- a/ppsci/utils/misc.py +++ b/ppsci/utils/misc.py @@ -90,12 +90,6 @@ def avg_info(self): self.avg = float(self.avg) return f"{self.name}: {self.avg:.5f}" - @property - def avg_fmt(self): - if isinstance(self.avg, paddle.Tensor): - self.avg = float(self.avg) - return f"{self.avg:.5e}" - @property def total(self): return f"{self.name}_sum: {self.sum:{self.fmt}}{self.postfix}"