Download code/bifurcation/methods/cascaded_si/method.py from coarse-grained-forecasting-benchmark/forecasting-models: direct link, hf CLI and curl.
- Browser
- Download file 2.79 kB
-
https://huggingface.co/coarse-grained-forecasting-benchmark/forecasting-models/resolve/main/code/bifurcation/methods/cascaded_si/method.py
- Command line
-
hf download hf://coarse-grained-forecasting-benchmark/forecasting-models/code/bifurcation/methods/cascaded_si/method.py
-
curl -L -o method.py https://huggingface.co/coarse-grained-forecasting-benchmark/forecasting-models/resolve/main/code/bifurcation/methods/cascaded_si/method.py
2.79 kB
| from __future__ import annotations | |
| import torch | |
| from ..base import Method | |
| from . import core | |
| class CascadedSIMethod(Method): | |
| def __init__(self, sigma_train, t_eps, sampling, beta_power=1, | |
| eval_noise_scales=None, optimizer_cfg=None): | |
| self.sigma_train = float(sigma_train) | |
| self.t_eps = float(t_eps) | |
| self.beta_power = int(beta_power) | |
| self.n_sde_steps_per_seg = int(sampling["n_sde_steps_per_seg"]) | |
| self.n_segments = int(sampling.get("n_segments", 10)) | |
| self.noise_scale = float(sampling.get("noise_scale", 1.0)) | |
| # Segment boundaries — uniform partition of [0, 1] by default, matching | |
| # the normalized physical forecast horizon. | |
| if "t_values" in sampling: | |
| self.t_values = list(sampling["t_values"]) | |
| else: | |
| self.t_values = [k / self.n_segments for k in range(self.n_segments + 1)] | |
| self.eval_noise_scales = ([float(s) for s in eval_noise_scales] | |
| if eval_noise_scales is not None else [self.noise_scale]) | |
| self.optimizer_cfg = optimizer_cfg or {} | |
| def from_config(cls, cfg): | |
| if cfg.get("anchor_ic", False): | |
| raise ValueError("This release supports the paper's SI models without retained initial-state inputs") | |
| return cls( | |
| sigma_train=cfg["sigma_train"], | |
| t_eps=cfg.get("t_eps", 0.0), | |
| sampling=cfg["sampling"], | |
| beta_power=cfg.get("beta_power", 1), | |
| eval_noise_scales=cfg.get("eval_noise_scales"), | |
| optimizer_cfg=cfg.get("optimizer"), | |
| ) | |
| def variants_for_eval(self): | |
| return {f"noise_scale_{_fmt(s)}": {"noise_scale": s} for s in self.eval_noise_scales} | |
| def loss(self, model, batch): | |
| x_tk, x_tk1, t_k, t_k1 = batch | |
| return core.local_si_loss(model, x_tk, x_tk1, t_k, t_k1, | |
| sigma=self.sigma_train, t_eps=self.t_eps, | |
| beta_power=self.beta_power) | |
| def sample(self, model, x_0, n_samples, noise_scale=None): | |
| if noise_scale is None: | |
| noise_scale = self.noise_scale | |
| if x_0.ndim == 1: | |
| x_0 = x_0.unsqueeze(0) | |
| B = x_0.shape[0] | |
| out = [] | |
| for i in range(B): | |
| cloud = core.rollout(model, x_0[i], n_samples=n_samples, | |
| t_values=self.t_values, | |
| n_sde_steps_per_seg=self.n_sde_steps_per_seg, | |
| sigma=self.sigma_train, | |
| noise_scale=noise_scale) | |
| out.append(cloud) | |
| return torch.stack(out, dim=0) | |
| def _fmt(s): | |
| if s == int(s): | |
| return f"{int(s)}p0" | |
| return f"{s}".replace(".", "p") | |