yushuang88 commited on
Commit
eac1b4e
·
verified ·
1 Parent(s): ff611ed

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,9 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ results/figures/pipe_case_000.png filter=lfs diff=lfs merge=lfs -text
37
+ results/figures/pipe_case_001.png filter=lfs diff=lfs merge=lfs -text
38
+ results/figures/pipe_case_002.png filter=lfs diff=lfs merge=lfs -text
39
+ results/figures/pipe_case_004.png filter=lfs diff=lfs merge=lfs -text
40
+ results/figures/pipe_case_050.png filter=lfs diff=lfs merge=lfs -text
41
+ results/figures/pipe_case_076.png filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ language:
4
+ - en
5
+ tags:
6
+ - OneScience
7
+ - computational-fluid-dynamics
8
+ - neural-operator
9
+ - pipe-flow
10
+ ---
11
+ # HO-FNO-Pipe-Flow
12
+
13
+ This package reproduces the Pipe experiment of [Higher-Order Fourier Neural Operator](https://arxiv.org/abs/2606.28122). An eight-layer, second-order spectral operator maps two pipe-coordinate channels to horizontal velocity on a 129 x 129 grid.
14
+
15
+ ## Download
16
+
17
+ ```bash
18
+ hf download OneScience-Group/HO-FNO-Pipe-Flow --local-dir ./HO-FNO-Pipe-Flow
19
+ cd HO-FNO-Pipe-Flow
20
+ ```
21
+
22
+ Install PyTorch, NumPy, PyYAML and Matplotlib in a compatible GPU/DCU environment. The original 2310-sample Pipe dataset is available from the [paper's official repository](https://github.com/AlexColagrande/HO-FNO) and as the [OneScience ModelScope dataset](https://www.modelscope.cn/datasets/OneScience/HO-FNO-Pipe). Download `Pipe_X.npy`, `Pipe_Y.npy`, and `Pipe_Q.npy` into `data/`; no dataset files are included in this Hugging Face model repository.
23
+
24
+ ## Run
25
+
26
+ ```bash
27
+ python scripts/inference.py
28
+ python scripts/result.py
29
+ # To repeat the 500-epoch training run on an accelerator:
30
+ python scripts/train.py
31
+ ```
32
+
33
+ The included `weight/best_model.pth` is from epoch 494. Its 200-case test mean relative L2 is 0.004887735; the paper reports 0.0049 for the Pipe setting. The weight SHA256 is `9d71053c64b62a6fc6f867108c29d2cc0d277d667a3504dc073a6b56072981d4`. See `results/` for the recorded metrics and plots.
34
+
35
+ ## Source and license
36
+
37
+ Model code in this reproduction is distributed under Apache 2.0. The underlying Pipe data has separate source terms; consult the [original project](https://github.com/AlexColagrande/HO-FNO) before reuse.
config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "model_type": "ho-fno-pipe",
3
+ "architectures": ["HOFNOPipe"],
4
+ "framework": "pytorch",
5
+ "task": "pipe-flow-field-regression",
6
+ "paper": "https://arxiv.org/abs/2606.28122"
7
+ }
config/config.yaml ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ experiment:
2
+ name: HO-FNO-Pipe-Flow
3
+ seed: 2026
4
+ paper: "Higher-Order Fourier Neural Operator: Explicit Mode Mixer for Nonlinear PDEs"
5
+ task: "Pipe horizontal fluid velocity prediction"
6
+
7
+ paths:
8
+ data_dir: data
9
+ output_dir: .
10
+ checkpoint: weight/best_model.pth
11
+ results_dir: results
12
+
13
+ data:
14
+ x_file: Pipe_X.npy
15
+ y_file: Pipe_Y.npy
16
+ q_file: Pipe_Q.npy
17
+ train_size: 1000
18
+ test_size: 200
19
+ total_used: 1200
20
+ input_channels: 2
21
+ output_channel_index: 0
22
+ resolution: [129, 129]
23
+ downsample: [1, 1]
24
+ normalizer_axes: [0, 1]
25
+ pin_memory: true
26
+ num_workers: 2
27
+
28
+ model:
29
+ class_name: HOFNOPipe
30
+ order: 2
31
+ layers: 8
32
+ width: 128
33
+ modes: [50, 24]
34
+ input_channels: 2
35
+ output_channels: 1
36
+ add_unit_grid: true
37
+ mlp_expansion: 4
38
+ mlp_dropout: 0.0
39
+ drop_path_rate: 0.0
40
+
41
+ training:
42
+ epochs: 500
43
+ batch_size: 8
44
+ optimizer: AdamW
45
+ learning_rate: 1.0e-3
46
+ final_learning_rate: 5.0e-5
47
+ weight_decay: 1.0e-5
48
+ scheduler: CosineAnnealingLR
49
+ loss: relative_l2
50
+ save_best_metric: test_mean_relative_l2
51
+ print_every: 1
52
+
53
+ runtime:
54
+ device: auto
55
+ require_accelerator: true
56
+ accelerator_kind: dcu
57
+ slurm:
58
+ partition: hx1hdnormal01
59
+ nodes: 1
60
+ gres: dcu:1
61
+ cpus_per_task: 8
62
+ memory: 30G
63
+ time_limit: "24:00:00"
64
+ module: compiler/dtk/25.04
65
+ conda_activate: /public/software/sghpc_sdk/Linux_x86_64/25.6/das/conda/bin/activate
66
+ conda_env: onescience
model/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .ho_fno_pipe import HOFNOPipe, count_parameters
2
+
3
+ __all__ = ["HOFNOPipe", "count_parameters"]
model/ho_fno_pipe.py ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """HO-FNO model for the Pipe horizontal velocity experiment.
2
+
3
+ This module implements the order-2 higher-order spectral mixer described in
4
+ the HO-FNO paper. The model uses channel-last tensors at the public interface:
5
+ ``[batch, height, width, channels]``.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Sequence
11
+
12
+ import torch
13
+ from torch import nn
14
+
15
+
16
+ class RMSNorm2d(nn.Module):
17
+ """RMS normalization over the channel dimension for channel-last fields."""
18
+
19
+ def __init__(self, channels: int, eps: float = 1e-6) -> None:
20
+ super().__init__()
21
+ self.weight = nn.Parameter(torch.ones(channels))
22
+ self.eps = eps
23
+
24
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
25
+ scale = torch.rsqrt(x.pow(2).mean(dim=-1, keepdim=True) + self.eps)
26
+ return x * scale * self.weight.view(1, 1, 1, -1)
27
+
28
+
29
+ class DropPath(nn.Module):
30
+ def __init__(self, probability: float = 0.0) -> None:
31
+ super().__init__()
32
+ self.probability = float(probability)
33
+
34
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
35
+ if not self.training or self.probability <= 0.0:
36
+ return x
37
+ keep = 1.0 - self.probability
38
+ mask_shape = (x.shape[0],) + (1,) * (x.ndim - 1)
39
+ mask = torch.empty(mask_shape, device=x.device, dtype=x.dtype).bernoulli_(keep)
40
+ return x * mask / keep
41
+
42
+
43
+ class DepthwiseSpectralConv2d(nn.Module):
44
+ """Depthwise complex Fourier convolution on retained low modes."""
45
+
46
+ def __init__(self, channels: int, modes: Sequence[int]) -> None:
47
+ super().__init__()
48
+ if len(modes) != 2:
49
+ raise ValueError("modes must contain exactly two integers")
50
+ self.channels = int(channels)
51
+ self.modes1 = int(modes[0])
52
+ self.modes2 = int(modes[1])
53
+ scale = 1.0 / max(1, self.channels)
54
+ self.weights_pos = nn.Parameter(
55
+ scale * torch.randn(self.channels, self.modes1, self.modes2, dtype=torch.cfloat)
56
+ )
57
+ self.weights_neg = nn.Parameter(
58
+ scale * torch.randn(self.channels, self.modes1, self.modes2, dtype=torch.cfloat)
59
+ )
60
+
61
+ @staticmethod
62
+ def _mul_modes(x_ft: torch.Tensor, weights: torch.Tensor) -> torch.Tensor:
63
+ return torch.einsum("bchw,chw->bchw", x_ft, weights)
64
+
65
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
66
+ batch, channels, height, width = x.shape
67
+ if channels != self.channels:
68
+ raise ValueError(f"expected {self.channels} channels, got {channels}")
69
+ x_ft = torch.fft.rfft2(x.float())
70
+ out_ft = torch.zeros(
71
+ batch,
72
+ self.channels,
73
+ height,
74
+ width // 2 + 1,
75
+ device=x.device,
76
+ dtype=torch.cfloat,
77
+ )
78
+ m1 = min(self.modes1, height)
79
+ m2 = min(self.modes2, width // 2 + 1)
80
+ out_ft[:, :, :m1, :m2] = self._mul_modes(
81
+ x_ft[:, :, :m1, :m2], self.weights_pos[:, :m1, :m2]
82
+ )
83
+ out_ft[:, :, -m1:, :m2] = self._mul_modes(
84
+ x_ft[:, :, -m1:, :m2], self.weights_neg[:, :m1, :m2]
85
+ )
86
+ return torch.fft.irfft2(out_ft, s=(height, width))
87
+
88
+
89
+ class HigherOrderSpectralMixer2d(nn.Module):
90
+ """Order-m HO spectral mixer.
91
+
92
+ The input is projected by ``m`` independent 1x1 maps, their outputs are
93
+ multiplied channelwise in physical space, then a retained-mode spectral
94
+ convolution is applied.
95
+ """
96
+
97
+ def __init__(self, channels: int, modes: Sequence[int], order: int = 2) -> None:
98
+ super().__init__()
99
+ if order < 1:
100
+ raise ValueError("order must be positive")
101
+ self.order = int(order)
102
+ self.factor_projection = nn.Conv2d(channels, channels * self.order, kernel_size=1)
103
+ self.spectral = DepthwiseSpectralConv2d(channels, modes)
104
+
105
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
106
+ x_cf = x.permute(0, 3, 1, 2).contiguous()
107
+ factors = self.factor_projection(x_cf).chunk(self.order, dim=1)
108
+ product = factors[0]
109
+ for factor in factors[1:]:
110
+ product = product * factor
111
+ mixed = self.spectral(product)
112
+ return mixed.permute(0, 2, 3, 1).contiguous()
113
+
114
+
115
+ class HOFNOBlock(nn.Module):
116
+ def __init__(
117
+ self,
118
+ width: int,
119
+ modes: Sequence[int],
120
+ order: int,
121
+ mlp_expansion: int = 4,
122
+ mlp_dropout: float = 0.0,
123
+ drop_path: float = 0.0,
124
+ ) -> None:
125
+ super().__init__()
126
+ self.norm_mixer = RMSNorm2d(width)
127
+ self.mixer = HigherOrderSpectralMixer2d(width, modes, order)
128
+ self.norm_ffn = RMSNorm2d(width)
129
+ hidden = int(width * mlp_expansion)
130
+ self.ffn = nn.Sequential(
131
+ nn.Linear(width, hidden),
132
+ nn.GELU(),
133
+ nn.Dropout(mlp_dropout),
134
+ nn.Linear(hidden, width),
135
+ nn.Dropout(mlp_dropout),
136
+ )
137
+ self.drop_path = DropPath(drop_path)
138
+
139
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
140
+ x = x + self.drop_path(self.mixer(self.norm_mixer(x)))
141
+ x = x + self.drop_path(self.ffn(self.norm_ffn(x)))
142
+ return x
143
+
144
+
145
+ class HOFNOPipe(nn.Module):
146
+ """HO-FNO Pipe model with paper Table 13 defaults."""
147
+
148
+ def __init__(
149
+ self,
150
+ input_channels: int = 2,
151
+ output_channels: int = 1,
152
+ order: int = 2,
153
+ layers: int = 8,
154
+ width: int = 128,
155
+ modes: Sequence[int] = (50, 24),
156
+ add_unit_grid: bool = True,
157
+ mlp_expansion: int = 4,
158
+ mlp_dropout: float = 0.0,
159
+ drop_path_rate: float = 0.0,
160
+ ) -> None:
161
+ super().__init__()
162
+ self.add_unit_grid = bool(add_unit_grid)
163
+ lift_channels = int(input_channels) + (2 if self.add_unit_grid else 0)
164
+ self.lift = nn.Linear(lift_channels, width)
165
+ if layers <= 1:
166
+ drop_rates = [0.0] * layers
167
+ else:
168
+ drop_rates = torch.linspace(0.0, float(drop_path_rate), layers).tolist()
169
+ self.blocks = nn.ModuleList(
170
+ [
171
+ HOFNOBlock(
172
+ width=width,
173
+ modes=modes,
174
+ order=order,
175
+ mlp_expansion=mlp_expansion,
176
+ mlp_dropout=mlp_dropout,
177
+ drop_path=drop_rates[idx],
178
+ )
179
+ for idx in range(layers)
180
+ ]
181
+ )
182
+ self.project = nn.Linear(width, output_channels)
183
+
184
+ @staticmethod
185
+ def unit_grid(batch: int, height: int, width: int, device: torch.device, dtype: torch.dtype) -> torch.Tensor:
186
+ gx = torch.linspace(0.0, 1.0, height, device=device, dtype=dtype).view(1, height, 1, 1)
187
+ gy = torch.linspace(0.0, 1.0, width, device=device, dtype=dtype).view(1, 1, width, 1)
188
+ gx = gx.expand(batch, height, width, 1)
189
+ gy = gy.expand(batch, height, width, 1)
190
+ return torch.cat((gx, gy), dim=-1)
191
+
192
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
193
+ if x.ndim != 4:
194
+ raise ValueError("HOFNOPipe expects [batch, height, width, channels]")
195
+ if self.add_unit_grid:
196
+ grid = self.unit_grid(x.shape[0], x.shape[1], x.shape[2], x.device, x.dtype)
197
+ x = torch.cat((x, grid), dim=-1)
198
+ x = self.lift(x)
199
+ for block in self.blocks:
200
+ x = block(x)
201
+ return self.project(x)
202
+
203
+
204
+ def count_parameters(model: nn.Module) -> int:
205
+ return sum(param.numel() for param in model.parameters() if param.requires_grad)
results/best_metrics.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "best_epoch": 494,
3
+ "test_mean_relative_l2": 0.004887734765652567,
4
+ "checkpoint": "/public/home/liuyushuang/zhaomingsi/onescience-cfd-repro-packages/HO-FNO-Pipe-Flow/weight/best_model.pth"
5
+ }
results/figures/pipe_case_000.png ADDED

Git LFS Details

  • SHA256: d9a34f6994427f5789cbed7ba45d160c8677157f33706e90febfebf044f734ba
  • Pointer size: 131 Bytes
  • Size of remote file: 168 kB
results/figures/pipe_case_001.png ADDED

Git LFS Details

  • SHA256: bcd94506a79ba9efc407c761c4169160ebb4c8a51ee4020f03dd2ddaa7e8bf0c
  • Pointer size: 131 Bytes
  • Size of remote file: 132 kB
results/figures/pipe_case_002.png ADDED

Git LFS Details

  • SHA256: 885e662890294b488d9c98f26a56898075ff72de366bc4635ace2d963ad0f1d0
  • Pointer size: 131 Bytes
  • Size of remote file: 185 kB
results/figures/pipe_case_003.png ADDED
results/figures/pipe_case_004.png ADDED

Git LFS Details

  • SHA256: da8a8678fd8f3536641c8d84d5e1b752a29715f80bb17b3b2e4193e496cdba28
  • Pointer size: 131 Bytes
  • Size of remote file: 157 kB
results/figures/pipe_case_050.png ADDED

Git LFS Details

  • SHA256: 9111018a17aa4c9a9d41b93a5a936cbf9c5e2c9f0a22fab32de6d82db772c4b6
  • Pointer size: 131 Bytes
  • Size of remote file: 129 kB
results/figures/pipe_case_076.png ADDED

Git LFS Details

  • SHA256: 57881806daabffe0133d22d8e527fc541697310f89b32d3ed73a3309a62c2797
  • Pointer size: 131 Bytes
  • Size of remote file: 121 kB
results/figures/pipe_case_193.png ADDED
results/inference_metrics.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "checkpoint": "/public/home/liuyushuang/zhaomingsi/onescience-cfd-repro-packages/HO-FNO-Pipe-Flow/weight/best_model.pth",
3
+ "test_samples": 200,
4
+ "mean_relative_l2": 0.00488773500546813,
5
+ "median_relative_l2": 0.0007863331120461226,
6
+ "max_relative_l2": 0.07080713659524918,
7
+ "min_relative_l2": 0.0002587482158560306
8
+ }
results/inputs.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4d727a1b4081fa15a2c56edc913f1c86e7229cf3436078e8e51e68d2a6f10b4b
3
+ size 26625728
results/predictions.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9f0c6082b7adf5943503cf446a1c7e934e05d4bae9a638d13a3aad69bd81c46b
3
+ size 13312928
results/relative_l2_per_sample.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7dc9ef72e3aa8cdff35f6680ea2ca331ed1e55720b8e6c8ea56cd5bc4b882222
3
+ size 928
results/result_summary.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "figure_count": 8,
3
+ "figures": [
4
+ "/public/home/liuyushuang/zhaomingsi/onescience-cfd-repro-packages/HO-FNO-Pipe-Flow/results/figures/pipe_case_076.png",
5
+ "/public/home/liuyushuang/zhaomingsi/onescience-cfd-repro-packages/HO-FNO-Pipe-Flow/results/figures/pipe_case_050.png",
6
+ "/public/home/liuyushuang/zhaomingsi/onescience-cfd-repro-packages/HO-FNO-Pipe-Flow/results/figures/pipe_case_193.png",
7
+ "/public/home/liuyushuang/zhaomingsi/onescience-cfd-repro-packages/HO-FNO-Pipe-Flow/results/figures/pipe_case_000.png",
8
+ "/public/home/liuyushuang/zhaomingsi/onescience-cfd-repro-packages/HO-FNO-Pipe-Flow/results/figures/pipe_case_001.png",
9
+ "/public/home/liuyushuang/zhaomingsi/onescience-cfd-repro-packages/HO-FNO-Pipe-Flow/results/figures/pipe_case_002.png",
10
+ "/public/home/liuyushuang/zhaomingsi/onescience-cfd-repro-packages/HO-FNO-Pipe-Flow/results/figures/pipe_case_003.png",
11
+ "/public/home/liuyushuang/zhaomingsi/onescience-cfd-repro-packages/HO-FNO-Pipe-Flow/results/figures/pipe_case_004.png"
12
+ ],
13
+ "mean_relative_l2": 0.00488773500546813,
14
+ "best_case": 76,
15
+ "median_case": 50,
16
+ "worst_case": 193
17
+ }
results/targets.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ee13aeee2d26f69fb80e364a47c016181312395326440148b27af8ce04ebb442
3
+ size 13312928
results/train_history.csv ADDED
@@ -0,0 +1,501 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ epoch,train_loss,test_mean_relative_l2,lr,seconds
2
+ 1,0.11291970175504684,0.07250297993421555,0.0009999906239066651,65.52439618110657
3
+ 2,0.05830034160614014,0.04976464286446571,0.0009999624959968127,41.879584550857544
4
+ 3,0.03538096110522747,0.03133390031754971,0.0009999156173808841,41.92104697227478
5
+ 4,0.025720175594091416,0.025593900829553606,0.0009998499899095672,41.93910264968872
6
+ 5,0.020908757470548153,0.02247545689344406,0.0009997656161737222,41.911678075790405
7
+ 6,0.01939347142726183,0.020575364604592323,0.0009996624995042794,42.22549605369568
8
+ 7,0.018543298564851284,0.021780321076512336,0.0009995406439721089,41.93345093727112
9
+ 8,0.017061021491885184,0.018202204070985318,0.0009994000543878578,41.98210334777832
10
+ 9,0.015849185436964036,0.017221610732376574,0.0009992407363017626,41.94684195518494
11
+ 10,0.014240952655673027,0.016498840413987637,0.0009990626960034283,41.95461654663086
12
+ 11,0.01390158961713314,0.017138588316738604,0.0009988659405215812,41.934826374053955
13
+ 12,0.013718998312950134,0.014713243879377842,0.0009986504776237908,41.99436664581299
14
+ 13,0.013701715305447578,0.015135787017643452,0.0009984163158161632,41.88865923881531
15
+ 14,0.012541784338653088,0.01605796184390783,0.000998163464343006,41.912806034088135
16
+ 15,0.01340049333125353,0.014824212081730365,0.000997891933186462,41.84580659866333
17
+ 16,0.012782515924423933,0.012666468974202871,0.0009976017330661166,41.85552382469177
18
+ 17,0.012563287105411292,0.018198666274547578,0.0009972928754385733,41.884132623672485
19
+ 18,0.012014073494821786,0.012824328355491162,0.0009969653724970027,49.6302490234375
20
+ 19,0.012764241375029087,0.014479510448873044,0.00099661923717066,55.82055974006653
21
+ 20,0.012251562848687171,0.014265533946454525,0.0009962544831243756,53.10058522224426
22
+ 21,0.011210481364279986,0.012499415464699268,0.0009958711247580142,55.87479209899902
23
+ 22,0.01107466036453843,0.013519823625683785,0.0009954691772059078,56.58713960647583
24
+ 23,0.011320454064756631,0.011948362626135349,0.0009950486563362576,55.66096091270447
25
+ 24,0.010537416953593493,0.012030495814979076,0.0009946095787505074,54.95785713195801
26
+ 25,0.010526666868478059,0.01297727134078741,0.0009941519617826886,44.318777322769165
27
+ 26,0.010800369441509246,0.012140801008790732,0.0009936758234987354,41.968586444854736
28
+ 27,0.011358561180531978,0.012270162478089333,0.0009931811826957722,41.96820855140686
29
+ 28,0.009424976691603661,0.010192368905991315,0.0009926680589013707,41.967328786849976
30
+ 29,0.010481927767395973,0.012572709023952484,0.0009921364723727796,41.98795199394226
31
+ 30,0.01049389423802495,0.011397665329277516,0.0009915864440961251,42.00072693824768
32
+ 31,0.009863101571798325,0.010905089061707259,0.0009910179957855817,42.04599976539612
33
+ 32,0.009753849972039461,0.011488913968205451,0.0009904311498825152,42.13008141517639
34
+ 33,0.009709974754601718,0.011755682975053788,0.000989825929554597,42.03392052650452
35
+ 34,0.010038154412060976,0.011424730438739062,0.0009892023586948898,42.070560455322266
36
+ 35,0.009404071379452943,0.01030907778069377,0.0009885604619209029,42.08303928375244
37
+ 36,0.009385162193328142,0.010499760750681162,0.000987900264573622,42.109002113342285
38
+ 37,0.009673079997301102,0.010110676754266024,0.0009872217927165078,42.120468616485596
39
+ 38,0.009504360228776931,0.010808106549084186,0.0009865250731344677,42.07768177986145
40
+ 39,0.009298167921602726,0.010502159148454666,0.0009858101333327977,42.05328917503357
41
+ 40,0.009134764079004527,0.010111679174005985,0.0009850770015360972,42.89881634712219
42
+ 41,0.009038474693894386,0.011346078831702472,0.000984325706687154,42.297070264816284
43
+ 42,0.008752755720168353,0.010474571697413922,0.0009835562784458022,42.08916902542114
44
+ 43,0.008919069647789001,0.010031743720173836,0.0009827687471877517,42.186537981033325
45
+ 44,0.009278567761182785,0.010789141207933426,0.0009819631440033877,42.080761432647705
46
+ 45,0.008653905384242535,0.011422246508300305,0.0009811395006965448,42.017802715301514
47
+ 46,0.008908406138420104,0.010698201321065425,0.0009802978497832503,42.02315306663513
48
+ 47,0.009108484480530024,0.010443722866475581,0.0009794382244904412,41.975441455841064
49
+ 48,0.008717344738543034,0.011118278801441193,0.000978560658754652,42.00052762031555
50
+ 49,0.008664798114448785,0.01022038472816348,0.0009776651872206756,42.10853433609009
51
+ 50,0.007909150429069995,0.01018995525315404,0.0009767518452401946,44.42242789268494
52
+ 51,0.00832929887995124,0.010272335186600685,0.0009758206688703865,55.18754982948303
53
+ 52,0.008334879785776138,0.012126089576631784,0.0009748716948724999,52.96343994140625
54
+ 53,0.008481525119394064,0.009731230065226555,0.0009739049607104037,54.305851459503174
55
+ 54,0.008146047901362181,0.010424152929335833,0.0009729205045491071,56.94318437576294
56
+ 55,0.007768041394650936,0.011362780556082726,0.0009719183652532536,56.19422960281372
57
+ 56,0.008278970442712306,0.010404851920902729,0.0009708985823855868,52.71536731719971
58
+ 57,0.008576061107218265,0.009735295623540878,0.000969861196205388,47.4219765663147
59
+ 58,0.007889347661286593,0.010743018798530101,0.0009688062476668873,42.19862723350525
60
+ 59,0.0086157332547009,0.01028655629605055,0.0009677337784176467,42.21479821205139
61
+ 60,0.008311465080827475,0.010834571924060583,0.000966643830796916,42.18119692802429
62
+ 61,0.007935918431729078,0.01065324692055583,0.0009655364478339606,42.23293328285217
63
+ 62,0.007627867203205824,0.009336154367774725,0.0009644116732463639,42.194478034973145
64
+ 63,0.00794882356375456,0.009424117896705865,0.0009632695514383009,42.1726496219635
65
+ 64,0.008837581291794776,0.011245293170213699,0.0009621101274987848,42.22317862510681
66
+ 65,0.008145604696124792,0.01078525848686695,0.0009609334471998874,42.225329637527466
67
+ 66,0.008060674421489238,0.01193482467904687,0.0009597395569949322,42.19996190071106
68
+ 67,0.008113784965127706,0.010601120628416538,0.0009585285040166603,42.21585822105408
69
+ 68,0.007427346531301737,0.010660959146916867,0.0009573003360753694,42.215760231018066
70
+ 69,0.0076420923583209515,0.01119160307571292,0.000956055101657027,42.206406354904175
71
+ 70,0.007412316743284464,0.009863906651735305,0.0009547928499213557,42.259146213531494
72
+ 71,0.006943403135985136,0.009778977353125811,0.0009535136306998927,42.222739696502686
73
+ 72,0.006626209177076817,0.010901956129819155,0.0009522174944940227,42.18370723724365
74
+ 73,0.007235152296721935,0.01064685519784689,0.0009509044924729835,42.178571939468384
75
+ 74,0.006947579395025968,0.009821610916405916,0.0009495746764718468,42.18664073944092
76
+ 75,0.006749508876353502,0.011660437565296888,0.0009482280989894711,42.183600425720215
77
+ 76,0.0074516448006033895,0.009511092137545347,0.00094686481318643,42.18205499649048
78
+ 77,0.006826808430254459,0.011049247216433286,0.0009454848728829127,42.11896634101868
79
+ 78,0.006468866223469377,0.009184386469423772,0.0009440883325565993,42.142399311065674
80
+ 79,0.00616564223729074,0.009248237535357475,0.0009426752473405106,42.1336088180542
81
+ 80,0.006229185301810503,0.010400569289922714,0.0009412456730208316,42.0780827999115
82
+ 81,0.006820377673953772,0.011357558462768792,0.0009397996660347085,42.09624099731445
83
+ 82,0.00587925292365253,0.009659212063997984,0.0009383372834680211,42.19998478889465
84
+ 83,0.006704993681982159,0.009744439050555229,0.0009368585830531292,42.26294732093811
85
+ 84,0.006499042831361294,0.01105725821107626,0.0009353636231665931,42.31238317489624
86
+ 85,0.005837777273729443,0.009544560965150595,0.0009338524628268697,42.221484661102295
87
+ 86,0.005806935233995319,0.009438671544194222,0.0009323251616919813,42.27266788482666
88
+ 87,0.005244618378579617,0.009007267914712428,0.0009307817800571617,42.21052694320679
89
+ 88,0.006103223279118538,0.010759318675845862,0.0009292223788524752,42.23101782798767
90
+ 89,0.006368336044251919,0.009624629467725753,0.000927647019640411,42.24658703804016
91
+ 90,0.006430458500981331,0.00932341517880559,0.0009260557646134536,42.19326448440552
92
+ 91,0.007169719438999891,0.008829848114401103,0.0009244486765916267,42.20094442367554
93
+ 92,0.0066339023131877185,0.010970470365136861,0.0009228258190200138,42.209601640701294
94
+ 93,0.006097638968378305,0.011622661855071784,0.0009211872559662527,42.24300456047058
95
+ 94,0.006013243027031422,0.009803424049168825,0.0009195330521180074,42.215238094329834
96
+ 95,0.005941387766972184,0.009375530350953341,0.0009178632727804133,42.18448543548584
97
+ 96,0.0054127784129232165,0.009217141214758157,0.0009161779838734994,42.237643241882324
98
+ 97,0.005592054169625044,0.009058780111372471,0.0009144772519295864,42.186150312423706
99
+ 98,0.00541948426142335,0.010255483277142048,0.0009127611440906589,42.230363607406616
100
+ 99,0.00590827789530158,0.009770643208175897,0.0009110297281057161,42.20335054397583
101
+ 100,0.005756610011681915,0.009400064740329981,0.0009092830723280965,42.184356451034546
102
+ 101,0.0048430434260517356,0.008983943928033113,0.0009075212457127793,42.2368483543396
103
+ 102,0.004608579449355602,0.009441528506577014,0.0009057443178136629,42.20143699645996
104
+ 103,0.0047166847605258225,0.010004132986068726,0.0009039523587808176,42.2073335647583
105
+ 104,0.004716853734105826,0.008897268157452344,0.0009021454393577181,42.175814390182495
106
+ 105,0.004909767597913742,0.008518827818334103,0.0009003236308784493,42.202489376068115
107
+ 106,0.004379852097481489,0.009759288989007473,0.0008984870052648904,42.206876039505005
108
+ 107,0.004783677026629448,0.008709999453276395,0.0008966356350238758,42.197070598602295
109
+ 108,0.004454217875376343,0.008495995830744505,0.0008947695932443327,42.18863916397095
110
+ 109,0.004443804083392024,0.009210851173847914,0.0008928889535943952,42.202499866485596
111
+ 110,0.005298669133335352,0.009136468069627882,0.0008909937903184964,42.163124561309814
112
+ 111,0.0048673268128186465,0.009742431119084358,0.0008890841782344378,42.123464822769165
113
+ 112,0.0045864863879978655,0.008376055471599102,0.0008871601927304344,42.100314140319824
114
+ 113,0.004446226069703698,0.0086821464356035,0.0008852219097621396,42.12679719924927
115
+ 114,0.004199819464236498,0.009034799430519342,0.0008832694058496461,42.12305307388306
116
+ 115,0.004323724357411266,0.008670403752475977,0.000881302758074465,42.11105227470398
117
+ 116,0.004282426599413157,0.008616385161876678,0.0008793220440764833,42.101210832595825
118
+ 117,0.004581970004364848,0.0091158801689744,0.0008773273420508979,42.10874962806702
119
+ 118,0.004599647490307689,0.009044027607887983,0.0008753187307451294,42.13164973258972
120
+ 119,0.005637400032952428,0.00890607362613082,0.0008732962894557128,42.14069104194641
121
+ 120,0.005929299663752318,0.009570312425494195,0.0008712600980251673,42.094080686569214
122
+ 121,0.005231391286477447,0.008893793020397424,0.0008692102368388439,42.15407347679138
123
+ 122,0.005475481865927577,0.010350515227764845,0.0008671467868217525,42.10262203216553
124
+ 123,0.005353459345176816,0.009257194157689809,0.0008650698294353665,42.1045823097229
125
+ 124,0.004550219776108861,0.008855136353522539,0.0008629794466744074,42.120529651641846
126
+ 125,0.004326888768002391,0.008390316395089031,0.0008608757210636067,42.13597774505615
127
+ 126,0.003916226482018829,0.008292315304279327,0.0008587587356544502,42.13399124145508
128
+ 127,0.004075985569506883,0.008023834628984332,0.0008566285740218963,42.10024690628052
129
+ 128,0.004267417300492525,0.011246925182640553,0.0008544853202610791,42.152366161346436
130
+ 129,0.005915552461519837,0.009087254926562309,0.0008523290589839874,42.166067600250244
131
+ 130,0.005326934685930609,0.00908179273828864,0.000850159875316124,42.14435076713562
132
+ 131,0.0044030729252845045,0.008856607163324952,0.0008479778548931459,42.09207510948181
133
+ 132,0.003985843891277909,0.009570827037096023,0.0008457830838574835,42.12112855911255
134
+ 133,0.004090129887685179,0.008907469771802425,0.0008435756488549389,42.11670231819153
135
+ 134,0.0039004442989826202,0.007929845852777362,0.0008413556370312664,42.108344078063965
136
+ 135,0.0037517113089561463,0.00822199372574687,0.0008391231360287315,42.10684609413147
137
+ 136,0.003954554485157132,0.0093433553352952,0.0008368782339826512,42.09490776062012
138
+ 137,0.003663641409948468,0.008687755297869445,0.0008346210195179143,42.150046586990356
139
+ 138,0.003748288590461016,0.008393004890531302,0.000832351581745483,42.132883071899414
140
+ 139,0.003650543499737978,0.008385616345331073,0.0008300700102588745,42.10776472091675
141
+ 140,0.0036058688294142486,0.008254857212305068,0.0008277763951306245,42.117310523986816
142
+ 141,0.0037889692783355713,0.008467727052047848,0.0008254708269087311,42.127418994903564
143
+ 142,0.003421628413721919,0.008142628511413931,0.0008231533966130797,42.135170459747314
144
+ 143,0.003703205466270447,0.008530060173943638,0.0008208241957318505,42.15837740898132
145
+ 144,0.003796797389164567,0.008272219114005566,0.0008184833162179059,42.13823175430298
146
+ 145,0.0033943072129040954,0.008487405134364962,0.000816130850485161,42.1796178817749
147
+ 146,0.0036441946011036633,0.009439632501453162,0.0008137668914049347,42.15298271179199
148
+ 147,0.004006889939308166,0.008258373271673917,0.0008113915323022839,42.16857147216797
149
+ 148,0.003857340507209301,0.008575311740860342,0.0008090048669523186,42.188151359558105
150
+ 149,0.003811946403235197,0.007932042609900236,0.0008066069895765004,42.198785066604614
151
+ 150,0.003477983009070158,0.008120080353692175,0.000804197994838922,42.16120648384094
152
+ 151,0.003802522387355566,0.007840559268370271,0.0008017779778425708,42.149800539016724
153
+ 152,0.0037814930137246845,0.008517087334766985,0.0007993470341255743,42.20494198799133
154
+ 153,0.0036182336546480656,0.008817214574664832,0.0007969052596574278,42.19130253791809
155
+ 154,0.0036591443195939065,0.008298613596707582,0.0007944527508352066,42.16030192375183
156
+ 155,0.003245102742686868,0.0077921478543430565,0.0007919896044797592,42.16040277481079
157
+ 156,0.0031980573646724223,0.008559518540278078,0.0007895159178318865,42.18310904502869
158
+ 157,0.003558604883030057,0.007908730432391167,0.0007870317885485017,42.172234773635864
159
+ 158,0.003545317804440856,0.008044731495901942,0.000784537314698775,42.16741347312927
160
+ 159,0.0033887369893491268,0.008006559843197465,0.0007820325947602632,42.12939763069153
161
+ 160,0.0032759516313672064,0.0074727430567145346,0.0007795177276150205,42.14423489570618
162
+ 161,0.003148985160514712,0.007949597435072064,0.0007769928125456959,42.17855906486511
163
+ 162,0.003376713667064905,0.009664089027792215,0.0007744579492316127,42.17045855522156
164
+ 163,0.003702496903017163,0.007714663371443748,0.0007719132377448342,42.12031650543213
165
+ 164,0.0031937688942998647,0.008003626074641943,0.0007693587785462129,42.12786865234375
166
+ 165,0.00328164897672832,0.008724665334448219,0.0007667946724814236,42.144694805145264
167
+ 166,0.003466707555577159,0.008547073137015105,0.0007642210207769836,42.12130641937256
168
+ 167,0.0033254217747598885,0.0074824765976518395,0.0007616379250362554,42.14989185333252
169
+ 168,0.003222027812153101,0.007343165054917336,0.0007590454872354358,42.13365292549133
170
+ 169,0.003155067089945078,0.007767007611691952,0.0007564438097195301,42.184733867645264
171
+ 170,0.0034300925526767967,0.007842857073992491,0.000753832995198312,42.16740131378174
172
+ 171,0.0031759348809719088,0.0075411321595311165,0.0007512131467422683,42.164406061172485
173
+ 172,0.003015428837388754,0.007974874498322605,0.0007485843677785302,42.153785943984985
174
+ 173,0.003359351985156536,0.007193451281636953,0.00074594676208679,42.11957097053528
175
+ 174,0.003117678912356496,0.007256294060498476,0.0007433004337952041,42.15063405036926
176
+ 175,0.0029869782384485005,0.007730052527040243,0.000740645487376282,42.16540598869324
177
+ 176,0.003066325336694717,0.0074354276154190305,0.0007379820276427627,42.176910161972046
178
+ 177,0.0031740277726203204,0.007694573504850268,0.0007353101597434755,42.124900817871094
179
+ 178,0.0029313206896185873,0.008021413162350655,0.0007326299891591904,42.163395404815674
180
+ 179,0.002954913990572095,0.008578075356781482,0.0007299416216984528,42.1265549659729
181
+ 180,0.0031102133933454752,0.007324225464835763,0.0007272451634934068,42.17985272407532
182
+ 181,0.0031030936632305385,0.007269433373585344,0.0007245407209956052,42.18455648422241
183
+ 182,0.003276889305561781,0.007967284228652716,0.0007218284009718073,42.14915156364441
184
+ 183,0.0031409364454448225,0.007561635514721274,0.000719108310499763,42.1492133140564
185
+ 184,0.002941989030689001,0.007290520770475269,0.000716380556963987,42.13275718688965
186
+ 185,0.0028719786182045937,0.0071548762917518615,0.0007136452480515182,42.11782383918762
187
+ 186,0.0026742426585406064,0.007624149937182665,0.0007109024917476685,42.12734270095825
188
+ 187,0.0029906245321035386,0.007685516607016325,0.0007081523963317607,42.12509846687317
189
+ 188,0.0028232300467789175,0.008058640286326408,0.000705395070372853,42.13945817947388
190
+ 189,0.0028212647531181572,0.007590855825692415,0.0007026306227254526,42.13403272628784
191
+ 190,0.0030002748686820267,0.007106297230347991,0.0006998591625252195,42.13364601135254
192
+ 191,0.0028575280010700228,0.007693022163584829,0.0006970807991846567,42.116652488708496
193
+ 192,0.0027682694373652337,0.007484338134527206,0.0006942956423887915,42.128509283065796
194
+ 193,0.003407703747972846,0.008999006096273661,0.0006915038020908456,42.13645935058594
195
+ 194,0.003127182448282838,0.007574656354263425,0.0006887053885078932,42.15012168884277
196
+ 195,0.0028855961207300425,0.008007864104583859,0.0006859005121165111,42.14242172241211
197
+ 196,0.0028171774661168458,0.007133533284068108,0.0006830892836484163,42.126824378967285
198
+ 197,0.002621236895211041,0.0070194235630333425,0.0006802718140860955,42.13852548599243
199
+ 198,0.002909461124800146,0.007485019629821181,0.0006774482146584222,42.13237023353577
200
+ 199,0.0027371058622375133,0.007163543859496713,0.0006746185968362675,42.146196365356445
201
+ 200,0.0027795584443956614,0.007625001464039088,0.0006717830723280977,42.145318031311035
202
+ 201,0.0026876576580107214,0.007515016170218587,0.0006689417530755654,42.160496950149536
203
+ 202,0.0025995066380128263,0.007554650278761983,0.0006660947512490893,42.167235136032104
204
+ 203,0.002528567143715918,0.007161353612318635,0.0006632421792434269,42.15837287902832
205
+ 204,0.002781585075892508,0.0075508195348083975,0.0006603841496732364,42.157448291778564
206
+ 205,0.002688173517584801,0.006970407254993915,0.0006575207753686318,42.12920427322388
207
+ 206,0.002498594319447875,0.007154414979740977,0.0006546521693707273,42.159613609313965
208
+ 207,0.002644781952723861,0.007278433637693525,0.0006517784449271763,42.14893364906311
209
+ 208,0.0026390877878293396,0.007089090999215841,0.0006488997154876988,42.175097703933716
210
+ 209,0.00238381302729249,0.007173620834946632,0.0006460160946996044,42.147977352142334
211
+ 210,0.002693177537061274,0.007063130671158433,0.0006431276964033038,42.14453053474426
212
+ 211,0.0025401666779071093,0.007094812551513314,0.0006402346346278164,42.17984437942505
213
+ 212,0.0025200333893299104,0.007004930675029755,0.0006373370235862671,42.15505266189575
214
+ 213,0.0026503468146547677,0.007049634978175163,0.0006344349776713784,42.17092514038086
215
+ 214,0.0024824798740446566,0.007012555440887809,0.0006315286114509539,42.18608570098877
216
+ 215,0.0022947878297418355,0.006783183990046382,0.0006286180396633557,42.13872766494751
217
+ 216,0.0024507187251001598,0.007126442063599825,0.0006257033772129739,42.18064570426941
218
+ 217,0.0026322647565975785,0.007355325873941183,0.0006227847391656915,42.149593353271484
219
+ 218,0.0024312174953520296,0.006913491655141115,0.0006198622407443412,42.1766152381897
220
+ 219,0.0025523678753525017,0.0066960109584033485,0.0006169359973241565,42.14200186729431
221
+ 220,0.002333197201602161,0.007174705388024449,0.0006140061244282171,42.1726336479187
222
+ 221,0.002280046842060983,0.006832148255780339,0.0006110727377228883,42.14658832550049
223
+ 222,0.002389767024666071,0.006729408679530024,0.0006081359530132542,42.1393301486969
224
+ 223,0.002384213709272444,0.006769644096493721,0.0006051958862385466,42.1670982837677
225
+ 224,0.0023337005311623218,0.007262925179675222,0.0006022526534675679,42.150354623794556
226
+ 225,0.0025277434196323157,0.007088149413466454,0.0005993063708941078,42.17193007469177
227
+ 226,0.002500075263902545,0.0069843391329050064,0.0005963571548323577,42.16856575012207
228
+ 227,0.0024446571553125977,0.006528989616781473,0.0005934051217123179,42.16573882102966
229
+ 228,0.00234212950989604,0.006863241977989674,0.0005904503880752013,42.16375470161438
230
+ 229,0.002352673529647291,0.0067721445858478545,0.0005874930705688324,42.12953591346741
231
+ 230,0.0022567430390045048,0.0069993397872895,0.0005845332859430426,42.153923749923706
232
+ 231,0.0024692613538354635,0.006681864010170102,0.0005815711510450612,42.17379713058472
233
+ 232,0.002371984934434295,0.006754398755729199,0.0005786067828149018,42.175777435302734
234
+ 233,0.0022688418542966245,0.00667944603599608,0.0005756402982807465,42.155993938446045
235
+ 234,0.0024618573617190124,0.006586356721818447,0.0005726718145543251,42.1636176109314
236
+ 235,0.0021524778697639703,0.006438714629039169,0.0005697014488262924,42.14340829849243
237
+ 236,0.0020113014187663793,0.006692732945084572,0.0005667293183616012,42.143359422683716
238
+ 237,0.0020490419548004866,0.006991984136402607,0.000563755540494873,42.175628423690796
239
+ 238,0.0022961163874715565,0.006679160576313734,0.0005607802326257662,42.15565299987793
240
+ 239,0.002203094887547195,0.006527257775887847,0.000557803512214341,42.15673041343689
241
+ 240,0.0021724185179919004,0.006714070085436106,0.000554825496776422,42.17497205734253
242
+ 241,0.002153705052100122,0.00632386414334178,0.0005518463038789597,42.14381146430969
243
+ 242,0.0021870013941079377,0.00638367060571909,0.0005488660511353886,42.161818981170654
244
+ 243,0.0020947828786447645,0.006536545744165778,0.0005458848562009839,42.162593841552734
245
+ 244,0.002061746398918331,0.007209485610947013,0.0005429028367682169,42.12910842895508
246
+ 245,0.001949265175499022,0.006660043615847826,0.000539920110562109,42.14690947532654
247
+ 246,0.002099892469123006,0.006743258712813258,0.0005369367953355833,42.15112853050232
248
+ 247,0.002079335288144648,0.0063218945171684025,0.000533953008864817,42.152891397476196
249
+ 248,0.0021357617983594535,0.00634973565582186,0.0005309688689445906,42.141151905059814
250
+ 249,0.002206177283078432,0.006626067636534572,0.0005279844933836386,42.140106201171875
251
+ 250,0.0021128319976851345,0.00689857603982091,0.000524999999999998,42.19824695587158
252
+ 251,0.0021892564073204995,0.00667907758615911,0.0005220155066163575,42.182302951812744
253
+ 252,0.002015864393673837,0.006391495168209076,0.0005190311310554054,42.14570999145508
254
+ 253,0.0020598149336874486,0.006650176160037518,0.000516046991135179,42.16291356086731
255
+ 254,0.0018417955795302988,0.00629407700151205,0.0005130632046644126,42.14233875274658
256
+ 255,0.0017921537961810828,0.006583956023678184,0.0005100798894378869,42.15020728111267
257
+ 256,0.0020015523275360467,0.006789485402405262,0.0005070971632317789,42.138859033584595
258
+ 257,0.0018759650392457842,0.006370405042544007,0.000504115143799012,42.19922065734863
259
+ 258,0.001895657593384385,0.006573736555874348,0.0005011339488646073,42.15921354293823
260
+ 259,0.0019535453310236335,0.006323027573525906,0.0004981536961210361,42.20323848724365
261
+ 260,0.00199010503385216,0.006399954855442047,0.0004951745032235741,42.13456654548645
262
+ 261,0.001883729314431548,0.006166646513156593,0.0004921964877856552,42.16352152824402
263
+ 262,0.0019782137954607606,0.006539005390368402,0.0004892197673742297,42.183865547180176
264
+ 263,0.0018185445675626397,0.006423173770308495,0.000486244459505123,42.17266583442688
265
+ 264,0.0018449555234983563,0.00621243804693222,0.00048327068163839487,42.15282464027405
266
+ 265,0.0018546377774327993,0.006462193783372641,0.0004802985511737036,42.14321947097778
267
+ 266,0.0018743496565148234,0.006329376013018191,0.00047732818544567087,42.15680813789368
268
+ 267,0.001978785214945674,0.007328763660043478,0.00047435970171924943,42.14131808280945
269
+ 268,0.0019468353940173984,0.006243623527698219,0.0004713932171850941,42.13767862319946
270
+ 269,0.0017538173086941243,0.006456256853416562,0.0004684288489549349,42.138068437576294
271
+ 270,0.0017034090496599675,0.00631677963770926,0.0004654667140569535,42.149085521698
272
+ 271,0.0017258798768743872,0.006143259722739458,0.00046250692943116377,42.14425754547119
273
+ 272,0.0017741792937740683,0.006458342811092734,0.0004595496119247949,42.17982578277588
274
+ 273,0.0018525060713291167,0.006332822903059423,0.00045659487828767815,42.17778253555298
275
+ 274,0.001942713930271566,0.006063738917000592,0.0004536428451676383,42.14189052581787
276
+ 275,0.0017533617140725254,0.00605435504578054,0.0004506936291058883,42.17078375816345
277
+ 276,0.0017019570535048842,0.006225380240939557,0.00044774734653242826,42.15065836906433
278
+ 277,0.0017586587090045213,0.006114432676695287,0.0004448041137614494,42.15136528015137
279
+ 278,0.0017262807423248888,0.006242326428182423,0.00044186404698674195,42.15107083320618
280
+ 279,0.0016182241532951593,0.006051964489743113,0.00043892726227710784,42.161882638931274
281
+ 280,0.0016918656788766384,0.006349132843315602,0.00043599387557177884,42.15557146072388
282
+ 281,0.00178700683824718,0.0060454958723858,0.0004330640026758395,42.14179611206055
283
+ 282,0.0014786973549053074,0.006202881843782961,0.00043013775925565474,42.17470741271973
284
+ 283,0.0018426093459129333,0.006426888173446059,0.00042721526083430435,42.154672145843506
285
+ 284,0.0016392324771732092,0.006310731535777449,0.00042429662278702215,42.15300464630127
286
+ 285,0.0014354429123923183,0.005930057601071894,0.0004213819603366404,42.1396324634552
287
+ 286,0.001613622642122209,0.0061535666231065985,0.000418471388549042,42.1704306602478
288
+ 287,0.0015003571035340428,0.0061339681129902604,0.00041556502232861764,42.15615463256836
289
+ 288,0.0014774750461801886,0.005953207248821855,0.0004126629764137289,42.150455951690674
290
+ 289,0.0015755195347592235,0.006048492901027202,0.0004097653653721796,42.154799699783325
291
+ 290,0.0015252400217577815,0.005965335383079946,0.0004068723035966922,42.143898010253906
292
+ 291,0.0016361389541998505,0.006373094022274017,0.0004039839053003917,42.16185998916626
293
+ 292,0.0017600573562085628,0.006268746014684439,0.0004011002845122971,42.13796377182007
294
+ 293,0.0016444287737831472,0.006238544755615294,0.0003982215550728199,42.172258377075195
295
+ 294,0.0014932709019631148,0.00613183131441474,0.00039534783062926865,42.142133951187134
296
+ 295,0.0014810651307925581,0.0060424465127289296,0.00039247922463136423,42.135069608688354
297
+ 296,0.001451825144700706,0.005824477793648839,0.00038961585032675953,42.14678597450256
298
+ 297,0.001359691908583045,0.00608757259324193,0.0003867578207565691,42.148927211761475
299
+ 298,0.0014596429197117687,0.005826153350062669,0.0003839052487509066,42.1699001789093
300
+ 299,0.0014352803342044353,0.005851823748089373,0.0003810582469244307,42.14897108078003
301
+ 300,0.0014189834604039788,0.005805884613655507,0.0003782169276718983,42.14655017852783
302
+ 301,0.0014398533999919892,0.006108633866533637,0.0003753814031637285,42.150089740753174
303
+ 302,0.0014794708834961056,0.0062555954372510315,0.0003725517853415739,42.13305950164795
304
+ 303,0.001483822542242706,0.005896107219159603,0.00036972818591390075,42.174325466156006
305
+ 304,0.0014258198509924113,0.005905657135881484,0.00036691071635157975,42.15308666229248
306
+ 305,0.0014099170928820967,0.005942928595468402,0.00036409948788348497,42.135355949401855
307
+ 306,0.0014993411293253303,0.005700381253845989,0.0003612946114921028,42.14886522293091
308
+ 307,0.0013933886364102363,0.006246662465855479,0.00035849619790915036,42.1618926525116
309
+ 308,0.0014347240524366497,0.005966983414255083,0.0003557043576112044,42.170936584472656
310
+ 309,0.0013018991602584719,0.005800144230015576,0.0003529192008153393,42.149249792099
311
+ 310,0.0014284086795523763,0.0057510767504572865,0.00035014083747477646,42.16345715522766
312
+ 311,0.0014951869659125805,0.005931897340342402,0.00034736937727454335,42.148942708969116
313
+ 312,0.001381469233892858,0.005785109270364046,0.000344604929627143,42.146360874176025
314
+ 313,0.0013984901355579495,0.006043918300420046,0.00034184760366823513,42.142902851104736
315
+ 314,0.0013183432519435882,0.006016129623167217,0.00033909750825232744,42.15414381027222
316
+ 315,0.0011748405559919774,0.005784870148636401,0.00033635475194847763,42.16751456260681
317
+ 316,0.0013413424626924097,0.005663507091812789,0.0003336194430360087,42.12975478172302
318
+ 317,0.001422054812312126,0.005824714689515531,0.0003308916895002328,42.14488077163696
319
+ 318,0.0013890892886556684,0.0057678255764767525,0.0003281715990281886,42.14603042602539
320
+ 319,0.001258905558846891,0.005663060019724071,0.00032545927900439056,42.13534927368164
321
+ 320,0.001251953513827175,0.0058133324887603526,0.000322754836506589,42.183977127075195
322
+ 321,0.0012007684749551118,0.005689186081290245,0.0003200583783015432,42.163496017456055
323
+ 322,0.0011875874679535628,0.005542515921406448,0.00031737001084080555,42.17989540100098
324
+ 323,0.0011923256888985634,0.005664793192408979,0.00031468984025652044,42.1583514213562
325
+ 324,0.0012740317839197814,0.005685654850676656,0.00031201797235723335,42.1533727645874
326
+ 325,0.0012337772636674344,0.00581255778670311,0.0003093545126237139,42.16801309585571
327
+ 326,0.0012861111098900438,0.005571498479694128,0.00030669956620479194,42.147196531295776
328
+ 327,0.0011336896615102886,0.005643135099671781,0.00030405323791320594,42.17997145652771
329
+ 328,0.001131731504574418,0.005522553846240044,0.00030141563222146585,42.18202209472656
330
+ 329,0.0011455843010917306,0.005717333746142686,0.00029878685325772754,42.135847091674805
331
+ 330,0.0012802089150063694,0.005727066164836287,0.0002961670048016841,42.141037940979004
332
+ 331,0.0011547363004647195,0.005651083295233548,0.00029355619028046596,42.15127420425415
333
+ 332,0.0012137028770521283,0.00561604954302311,0.00029095451276456015,42.16386270523071
334
+ 333,0.0011359821753576399,0.005743327336385846,0.00028836207496374063,42.180307149887085
335
+ 334,0.001149183983914554,0.005641659474931658,0.0002857789792230124,42.14588785171509
336
+ 335,0.0012013267665170132,0.005532979993149638,0.0002832053275185724,42.12929677963257
337
+ 336,0.0011228126734495164,0.005556737426668405,0.0002806412214537832,42.139588832855225
338
+ 337,0.001207778315525502,0.005676322467625141,0.0002780867622551619,42.16767120361328
339
+ 338,0.0011089936685748398,0.005627961093559861,0.0002755420507683833,42.14484643936157
340
+ 339,0.0011262540286406874,0.005535308769904077,0.00027300718745430026,42.142333030700684
341
+ 340,0.0010950425607152282,0.005616132882423699,0.0002704822723849756,42.16416144371033
342
+ 341,0.0010285463407635688,0.005472129317931831,0.0002679674052397329,42.154940128326416
343
+ 342,0.0009988611922599375,0.005518076629377902,0.00026546268530122115,42.144511222839355
344
+ 343,0.0010593230416998268,0.005506300400011242,0.00026296821145149464,42.13844394683838
345
+ 344,0.0010991978985257446,0.005526706413365901,0.0002604840821681097,42.15572214126587
346
+ 345,0.0009927011718973517,0.005516530615277588,0.00025801039552023693,42.157177448272705
347
+ 346,0.0010494161238893867,0.005555574633181095,0.0002555472491647898,42.13720631599426
348
+ 347,0.0010944811794906856,0.005463537885807454,0.0002530947403425683,42.13668656349182
349
+ 348,0.000995776901487261,0.005548257222399116,0.0002506529658744221,42.15412974357605
350
+ 349,0.0010082315891049801,0.0055446630017831925,0.00024822202215742556,42.146079778671265
351
+ 350,0.0010215971074067057,0.005375199005939067,0.00024580200516107446,42.153315782547
352
+ 351,0.0009962058155797422,0.0057278323266655206,0.00024339301042349603,42.16267418861389
353
+ 352,0.0009957950320094824,0.005488911152351648,0.0002409951330476779,42.16830325126648
354
+ 353,0.0009214289793744683,0.005401083396282047,0.00023860846769771242,42.155444860458374
355
+ 354,0.0009429763182997703,0.005634815078228712,0.0002362331085950616,42.15266036987305
356
+ 355,0.0009347751811146736,0.005492067639715969,0.0002338691495148355,42.21178364753723
357
+ 356,0.0009484309121035039,0.005404185689985752,0.00023151668378209033,42.160770654678345
358
+ 357,0.0009870026176795363,0.005621108803898096,0.00022917580426814587,42.17944312095642
359
+ 358,0.0008971082814969122,0.005477433493360877,0.00022684660338691658,42.1559624671936
360
+ 359,0.0009119903082028031,0.005473259813152253,0.00022452917309126515,42.16820168495178
361
+ 360,0.0008853274490684271,0.005495551219210029,0.00022222360486937165,42.1544086933136
362
+ 361,0.0008988673803396523,0.005489456043578684,0.00021992998974112185,42.145888566970825
363
+ 362,0.0008788427468389273,0.005394712020643055,0.0002176484182545132,42.15781283378601
364
+ 363,0.0009815336223691702,0.005540766706690192,0.00021537898048208182,42.18550729751587
365
+ 364,0.0009422779027372599,0.005353906350210309,0.00021312176601734505,42.13848376274109
366
+ 365,0.0008869103016331792,0.005381524595431984,0.00021087686397126457,42.14133930206299
367
+ 366,0.000852799738291651,0.005402576178312302,0.0002086443629687298,42.14723038673401
368
+ 367,0.0009191015507094562,0.005282475659623742,0.0002064243511450573,42.170644760131836
369
+ 368,0.0008233746946789324,0.005327226463705302,0.0002042169161425127,42.14095950126648
370
+ 369,0.0008490832420065999,0.005395285724662244,0.0002020221451068502,42.146767139434814
371
+ 370,0.0008804545202292502,0.005423372811637819,0.00019984012468387237,42.144816398620605
372
+ 371,0.0008363953414373099,0.005400729328393936,0.0001976709410160088,42.14867687225342
373
+ 372,0.0008531210590153932,0.005414677783846855,0.0001955146797389171,42.165897369384766
374
+ 373,0.0007948162509128451,0.005351722673512995,0.00019337142597809995,42.15456247329712
375
+ 374,0.0007905877525918185,0.005322384652681649,0.00019124126434554592,42.15564250946045
376
+ 375,0.0008084532022476196,0.005311542567797005,0.00018912427893638935,42.14628791809082
377
+ 376,0.0007664066222496331,0.005346867046318949,0.00018702055332558886,42.150744915008545
378
+ 377,0.000789409342687577,0.005382901248522103,0.00018493017056462957,42.173824310302734
379
+ 378,0.0007699201358482242,0.0052062290953472255,0.0001828532131782436,42.18563628196716
380
+ 379,0.0007612495860084891,0.005339970884378999,0.00018078976316115232,42.20571255683899
381
+ 380,0.0007904163165949285,0.005328515528235584,0.00017873990197482886,42.18472743034363
382
+ 381,0.0007857253011316061,0.0053206708980724216,0.0001767037105442835,42.154693603515625
383
+ 382,0.0007951456452719867,0.0052870500832796095,0.00017468126925486685,42.17419147491455
384
+ 383,0.000801172613631934,0.0053232831554487344,0.00017267265794909835,42.14831590652466
385
+ 384,0.0007740125535055995,0.005266394459176808,0.00017067795592351292,42.15592575073242
386
+ 385,0.0007559758289717137,0.005231287120841444,0.00016869724192553114,42.1945436000824
387
+ 386,0.0007585050100460648,0.005235266850795597,0.00016673059415035012,42.15575456619263
388
+ 387,0.0007144342693500221,0.005262999697588384,0.00016477809023785658,42.14698028564453
389
+ 388,0.0007119012330658734,0.005254017119295895,0.00016283980726956184,42.19232511520386
390
+ 389,0.0007619464038871229,0.005282347602769732,0.00016091582176555827,42.15988302230835
391
+ 390,0.0008377386042848229,0.005318576414138079,0.00015900620968149968,42.152982234954834
392
+ 391,0.0007027176502160728,0.005236193367745727,0.00015711104640560102,42.179189682006836
393
+ 392,0.0007233173628337681,0.00518192691495642,0.00015523040675566346,42.15418362617493
394
+ 393,0.0006800160012207925,0.005162809218745679,0.0001533643649761202,42.12351727485657
395
+ 394,0.0007358493027277291,0.005167380520142615,0.00015151299473510572,42.14858388900757
396
+ 395,0.0006495707714930177,0.005193230509757995,0.00014967636912154662,42.13934564590454
397
+ 396,0.0006457943893037737,0.005184728691820056,0.00014785456064227777,42.16289043426514
398
+ 397,0.0006902191140688956,0.005357355014421045,0.00014604764121917843,42.15189266204834
399
+ 398,0.0006925381175242365,0.00521846940740943,0.00014425568218633315,42.1678786277771
400
+ 399,0.000606785248266533,0.00513556218938902,0.00014247875428721673,42.149487018585205
401
+ 400,0.0006412174957804382,0.005176208866760135,0.00014071692767189965,42.14545965194702
402
+ 401,0.0006504643489606679,0.005269009829498827,0.00013897027189428002,42.13450074195862
403
+ 402,0.0006259702872484922,0.005167051339522004,0.00013723885590933728,42.14614224433899
404
+ 403,0.0006882322509773075,0.005201489725150168,0.0001355227480704099,42.142101526260376
405
+ 404,0.0006650580414570868,0.0052480962267145515,0.00013382201612649664,42.168331146240234
406
+ 405,0.000636717815650627,0.00515716961119324,0.00013213672721958288,42.137391090393066
407
+ 406,0.0006022769508417696,0.005158397108316421,0.00013046694788198873,42.15442991256714
408
+ 407,0.0006362093423958868,0.005179179734550416,0.00012881274403374332,42.17393398284912
409
+ 408,0.0006114725184161216,0.005111824951600283,0.00012717418097998244,42.13360548019409
410
+ 409,0.0005949152384418994,0.005181857859715819,0.00012555132340836943,42.15500020980835
411
+ 410,0.0006107385475188494,0.005141563536599278,0.00012394423538654258,42.140730142593384
412
+ 411,0.0006162793089170009,0.005126228258013725,0.0001223529803595852,42.1779522895813
413
+ 412,0.0005811577537097037,0.00510922878747806,0.0001207776211475212,42.15800070762634
414
+ 413,0.0006045320963021368,0.005129445781931281,0.00011921821994283452,42.15102934837341
415
+ 414,0.0006095961753744632,0.005116977537982166,0.00011767483830801503,42.152981996536255
416
+ 415,0.0005973727148957551,0.005193659053184092,0.0001161475371731266,42.18889379501343
417
+ 416,0.00058086555195041,0.005059030645061285,0.00011463637683340293,42.14637064933777
418
+ 417,0.0005479211595375091,0.0051021050126291816,0.00011314141694686704,42.15383577346802
419
+ 418,0.0005602591580245644,0.005067833114881068,0.00011166271653197511,42.1487603187561
420
+ 419,0.0005460878070443868,0.005102802955079823,0.00011020033396528777,42.13915777206421
421
+ 420,0.0005486795904580503,0.00507248355075717,0.00010875432697916463,42.13200783729553
422
+ 421,0.0005442759131547064,0.00511849201284349,0.00010732475265948569,42.144142150878906
423
+ 422,0.0005571733161341399,0.005130676992703229,0.00010591166744339697,42.13882088661194
424
+ 423,0.0005343274869956076,0.0050836849235929545,0.00010451512711708365,42.13605284690857
425
+ 424,0.0005643928542267531,0.005079786132555455,0.00010313518681356621,42.15080165863037
426
+ 425,0.0005280657382681966,0.005045115421526134,0.00010177190101052515,42.14947700500488
427
+ 426,0.0005231346790678799,0.005055409995839,0.00010042532352814957,42.15471315383911
428
+ 427,0.0005247649832163006,0.005081499787047505,9.909550752701282e-05,42.140175104141235
429
+ 428,0.0005371226530987769,0.005071519035845995,9.778250550597361e-05,42.14337110519409
430
+ 429,0.0005453378765378148,0.005045232803095132,9.648636930010353e-05,42.153175592422485
431
+ 430,0.0005222005231771619,0.0050695834844373166,9.520715007864069e-05,42.151262521743774
432
+ 431,0.0005325271328911186,0.005064349742606282,9.394489834296932e-05,42.13772916793823
433
+ 432,0.0005159716946072876,0.005004133027978241,9.269966392462696e-05,42.170111417770386
434
+ 433,0.0005069857595954091,0.005059001289773732,9.147149598333609e-05,42.14159440994263
435
+ 434,0.0005254864001180976,0.005145963777322322,9.026044300506408e-05,42.150636196136475
436
+ 435,0.0005017112481873482,0.005031144504901022,8.906655280010886e-05,42.18002772331238
437
+ 436,0.0004959030214231461,0.005028060923796147,8.788987250121158e-05,42.15946316719055
438
+ 437,0.0005099203295540064,0.005065623610280454,8.673044856169533e-05,42.16259407997131
439
+ 438,0.0005014459292870015,0.005023209992796183,8.558832675363228e-05,42.14714860916138
440
+ 439,0.00048753408063203097,0.005033429749310017,8.44635521660358e-05,42.15175747871399
441
+ 440,0.0004789673062041402,0.005029221309814602,8.335616920308045e-05,42.16646933555603
442
+ 441,0.00047840877901762725,0.0050008495151996615,8.226622158234969e-05,42.16409921646118
443
+ 442,0.00046466006617993115,0.005013435408473015,8.119375233310919e-05,42.189634561538696
444
+ 443,0.00048372200201265514,0.005048174317926169,8.013880379460856e-05,42.15875864028931
445
+ 444,0.00048252617218531667,0.004995608574245125,7.910141761440972e-05,42.16175055503845
446
+ 445,0.0004816301257815212,0.005025347454939037,7.808163474674286e-05,42.14081430435181
447
+ 446,0.000472392792114988,0.004999157381244004,7.707949545088926e-05,42.131165504455566
448
+ 447,0.00046654685260728,0.005023023320827633,7.609503928959268e-05,42.142634868621826
449
+ 448,0.00047430248535238205,0.005018748219590634,7.51283051274964e-05,42.19651651382446
450
+ 449,0.00045132332411594687,0.005000915459822864,7.417933112960993e-05,42.144909620285034
451
+ 450,0.00046855803439393637,0.00496990253450349,7.324815475980199e-05,42.13889002799988
452
+ 451,0.0004366779918782413,0.004960437621921301,7.233481277932102e-05,42.147295236587524
453
+ 452,0.00044212720193900166,0.004995690893847496,7.143934124534453e-05,42.17310857772827
454
+ 453,0.00046936872275546193,0.004979713056236505,7.056177550955542e-05,42.153655767440796
455
+ 454,0.0004348635252099484,0.004989741309545934,6.970215021674641e-05,42.14102602005005
456
+ 455,0.00043968118401244285,0.004983714916743338,6.886049930345198e-05,42.14832401275635
457
+ 456,0.0004467770499177277,0.005021367822773754,6.803685599660918e-05,42.1541485786438
458
+ 457,0.00043745909468270836,0.004950231388211251,6.723125281224533e-05,42.1549072265625
459
+ 458,0.00042749845306389034,0.004967715498059988,6.644372155419485e-05,42.149338245391846
460
+ 459,0.00043316312064416705,0.004970081308856606,6.567429331284333e-05,42.13941192626953
461
+ 460,0.00046097931382246317,0.00499007863458246,6.49229984639002e-05,42.146636724472046
462
+ 461,0.0004232672124635428,0.00498042618855834,6.418986666719971e-05,42.17229247093201
463
+ 462,0.0004380541180726141,0.004984405273571611,6.347492686552982e-05,42.180989027023315
464
+ 463,0.0004377285779919475,0.004966925985645503,6.277820728348987e-05,42.17451572418213
465
+ 464,0.00042692235694266855,0.004969094223342836,6.209973542637578e-05,42.160496950149536
466
+ 465,0.00042911868053488434,0.004945675653871149,6.143953807909499e-05,42.16932988166809
467
+ 466,0.0004230662367772311,0.004951206701807678,6.0797641305108065e-05,42.16595149040222
468
+ 467,0.00042714771302416923,0.004948933648411185,6.017407044540074e-05,42.16274356842041
469
+ 468,0.0004378965345676988,0.004968965826556086,5.956885011748271e-05,42.145270109176636
470
+ 469,0.0004322976158000529,0.004953726432286203,5.898200421441633e-05,42.153756856918335
471
+ 470,0.0004278975399211049,0.004941550642251968,5.841355590387283e-05,42.153528451919556
472
+ 471,0.0004055895230267197,0.00493796466384083,5.7863527627218356e-05,42.15631318092346
473
+ 472,0.0004265498979948461,0.004994546854868531,5.7331941098627444e-05,42.15065884590149
474
+ 473,0.00041287607001140716,0.004942715987563133,5.681881730422591e-05,42.14630889892578
475
+ 474,0.00040591336344368757,0.004948565163649618,5.6324176501262666e-05,42.16002678871155
476
+ 475,0.0004188445024192333,0.0049334951303899284,5.58480382173096e-05,42.19707202911377
477
+ 476,0.00044001062726601957,0.004976346914190799,5.539042124949086e-05,42.14699339866638
478
+ 477,0.00040927774948067966,0.004929947634227574,5.495134366374079e-05,42.17240262031555
479
+ 478,0.00040689810435287654,0.0049399118567816916,5.4530822794090674e-05,42.121259450912476
480
+ 479,0.0004006803943775594,0.004958913750015199,5.412887524198436e-05,42.185892820358276
481
+ 480,0.00040248095290735365,0.004949218032415956,5.374551687562305e-05,42.19987893104553
482
+ 481,0.0004055983368307352,0.0049281998048536476,5.3380762829338536e-05,42.14647173881531
483
+ 482,0.0003978742565959692,0.00492363867117092,5.3034627502996004e-05,42.15740442276001
484
+ 483,0.0004035429654177278,0.004949421093333513,5.27071245614255e-05,42.17440128326416
485
+ 484,0.00040057370672002434,0.004944873622152954,5.239826693388241e-05,42.19263815879822
486
+ 485,0.0004084925639908761,0.004937545035500079,5.210806681353699e-05,42.18154573440552
487
+ 486,0.00042293321201577783,0.004943623554427176,5.1836535656993055e-05,42.151302337646484
488
+ 487,0.00039891794323921204,0.004929787213914096,5.158368418383581e-05,42.18571496009827
489
+ 488,0.00039165858761407434,0.004919838574714959,5.134952237620838e-05,42.1658079624176
490
+ 489,0.00039790015830658374,0.004939576806500554,5.113405947841802e-05,42.16103911399841
491
+ 490,0.0003970611463300884,0.004966765330173075,5.0937303996571016e-05,42.14169979095459
492
+ 491,0.0004072226514108479,0.004924789506476373,5.075926369823687e-05,42.139729499816895
493
+ 492,0.0003984558309894055,0.004915200604591519,5.059994561214171e-05,42.14606523513794
494
+ 493,0.0003879048149101436,0.004909393424168229,5.045935602789077e-05,42.13826060295105
495
+ 494,0.0003945765143726021,0.004887734765652567,5.0337500495720134e-05,42.15134048461914
496
+ 495,0.0003898573338519782,0.004919080082327127,5.02343838262775e-05,42.18497061729431
497
+ 496,0.00040039386018179355,0.004915929664857686,5.015001009043254e-05,42.154250144958496
498
+ 497,0.000414175134152174,0.004896453395485878,5.008438261911575e-05,42.13798475265503
499
+ 498,0.0003980997314210981,0.004912928100675344,5.003750400318735e-05,42.136327028274536
500
+ 499,0.0003975559438113123,0.004891343340277672,5.0009376093334876e-05,42.15986752510071
501
+ 500,0.0003921014731749892,0.004918747302144766,5e-05,42.16036343574524
results/training_summary.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "epochs": 500,
3
+ "best_epoch": 494,
4
+ "best_test_mean_relative_l2": 0.004887734765652567,
5
+ "total_seconds": 21283.793029546738,
6
+ "checkpoint": "/public/home/liuyushuang/zhaomingsi/onescience-cfd-repro-packages/HO-FNO-Pipe-Flow/weight/best_model.pth"
7
+ }
scripts/common.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import os
5
+ import random
6
+ import sys
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ import numpy as np
11
+ import torch
12
+ import yaml
13
+
14
+
15
+ ROOT = Path(__file__).resolve().parents[1]
16
+ if str(ROOT) not in sys.path:
17
+ sys.path.insert(0, str(ROOT))
18
+
19
+ from model.ho_fno_pipe import HOFNOPipe, count_parameters # noqa: E402
20
+
21
+
22
+ class UnitTransformer:
23
+ def __init__(self, tensor: torch.Tensor, axes: tuple[int, ...] = (0, 1), eps: float = 1e-8) -> None:
24
+ self.axes = axes
25
+ self.eps = eps
26
+ self.mean = tensor.mean(dim=axes, keepdim=True)
27
+ self.std = tensor.std(dim=axes, keepdim=True) + eps
28
+
29
+ def encode(self, tensor: torch.Tensor) -> torch.Tensor:
30
+ return (tensor - self.mean) / self.std
31
+
32
+ def decode(self, tensor: torch.Tensor) -> torch.Tensor:
33
+ return tensor * self.std + self.mean
34
+
35
+ def to(self, device: torch.device) -> "UnitTransformer":
36
+ self.mean = self.mean.to(device)
37
+ self.std = self.std.to(device)
38
+ return self
39
+
40
+ def state_dict(self) -> dict[str, Any]:
41
+ return {"mean": self.mean.cpu(), "std": self.std.cpu(), "axes": self.axes, "eps": self.eps}
42
+
43
+ @classmethod
44
+ def from_state_dict(cls, state: dict[str, Any]) -> "UnitTransformer":
45
+ obj = cls.__new__(cls)
46
+ obj.mean = state["mean"]
47
+ obj.std = state["std"]
48
+ obj.axes = tuple(state.get("axes", (0, 1)))
49
+ obj.eps = float(state.get("eps", 1e-8))
50
+ return obj
51
+
52
+
53
+ def load_config(path: str | os.PathLike[str] | None = None) -> dict[str, Any]:
54
+ cfg_path = Path(path) if path else ROOT / "config" / "config.yaml"
55
+ with cfg_path.open("r", encoding="utf-8") as handle:
56
+ cfg = yaml.safe_load(handle)
57
+ cfg["_config_path"] = str(cfg_path)
58
+ return cfg
59
+
60
+
61
+ def set_seed(seed: int) -> None:
62
+ random.seed(seed)
63
+ np.random.seed(seed)
64
+ torch.manual_seed(seed)
65
+ if torch.cuda.is_available():
66
+ torch.cuda.manual_seed_all(seed)
67
+
68
+
69
+ def resolve(path: str | os.PathLike[str], base: Path | None = None) -> Path:
70
+ p = Path(path)
71
+ if p.is_absolute():
72
+ return p
73
+ return (base or ROOT) / p
74
+
75
+
76
+ def select_device(require_accelerator: bool = False) -> torch.device:
77
+ if torch.cuda.is_available():
78
+ return torch.device("cuda")
79
+ if require_accelerator:
80
+ raise RuntimeError("accelerator is required, but torch.cuda.is_available() is False")
81
+ return torch.device("cpu")
82
+
83
+
84
+ def load_pipe_tensors(cfg: dict[str, Any]) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
85
+ data_cfg = cfg["data"]
86
+ data_dir = Path(cfg["paths"]["data_dir"])
87
+ train_size = int(data_cfg["train_size"])
88
+ test_size = int(data_cfg["test_size"])
89
+ total_used = int(data_cfg["total_used"])
90
+ r1, r2 = (int(v) for v in data_cfg.get("downsample", [1, 1]))
91
+ s1 = int(((int(data_cfg["resolution"][0]) - 1) / r1) + 1)
92
+ s2 = int(((int(data_cfg["resolution"][1]) - 1) / r2) + 1)
93
+
94
+ x_raw = np.load(data_dir / data_cfg["x_file"], mmap_mode="r")[:total_used, ::r1, ::r2][:, :s1, :s2]
95
+ y_raw = np.load(data_dir / data_cfg["y_file"], mmap_mode="r")[:total_used, ::r1, ::r2][:, :s1, :s2]
96
+ q_raw = np.load(data_dir / data_cfg["q_file"], mmap_mode="r")[
97
+ :total_used, int(data_cfg["output_channel_index"]), ::r1, ::r2
98
+ ][:, :s1, :s2]
99
+
100
+ coords = np.stack((np.asarray(x_raw, dtype=np.float32), np.asarray(y_raw, dtype=np.float32)), axis=-1)
101
+ target = np.asarray(q_raw, dtype=np.float32)[..., None]
102
+ x_all = torch.from_numpy(coords.copy())
103
+ y_all = torch.from_numpy(target.copy())
104
+ return x_all[:train_size], y_all[:train_size], x_all[-test_size:], y_all[-test_size:]
105
+
106
+
107
+ def make_normalized_loaders(cfg: dict[str, Any]):
108
+ x_train, y_train, x_test, y_test = load_pipe_tensors(cfg)
109
+ axes = tuple(int(v) for v in cfg["data"].get("normalizer_axes", [0, 1]))
110
+ x_normalizer = UnitTransformer(x_train, axes=axes)
111
+ y_normalizer = UnitTransformer(y_train, axes=axes)
112
+ x_train_n = x_normalizer.encode(x_train)
113
+ x_test_n = x_normalizer.encode(x_test)
114
+ y_train_n = y_normalizer.encode(y_train)
115
+ y_test_n = y_normalizer.encode(y_test)
116
+
117
+ batch_size = int(cfg["training"]["batch_size"])
118
+ loader_kwargs = {
119
+ "batch_size": batch_size,
120
+ "num_workers": int(cfg["data"].get("num_workers", 0)),
121
+ "pin_memory": bool(cfg["data"].get("pin_memory", False)),
122
+ }
123
+ train_ds = torch.utils.data.TensorDataset(x_train_n, y_train_n)
124
+ test_ds = torch.utils.data.TensorDataset(x_test_n, y_test_n)
125
+ train_loader = torch.utils.data.DataLoader(train_ds, shuffle=True, **loader_kwargs)
126
+ test_loader = torch.utils.data.DataLoader(test_ds, shuffle=False, **loader_kwargs)
127
+ return train_loader, test_loader, x_normalizer, y_normalizer
128
+
129
+
130
+ def build_model(cfg: dict[str, Any]) -> HOFNOPipe:
131
+ m = cfg["model"]
132
+ return HOFNOPipe(
133
+ input_channels=int(m["input_channels"]),
134
+ output_channels=int(m["output_channels"]),
135
+ order=int(m["order"]),
136
+ layers=int(m["layers"]),
137
+ width=int(m["width"]),
138
+ modes=tuple(int(v) for v in m["modes"]),
139
+ add_unit_grid=bool(m.get("add_unit_grid", True)),
140
+ mlp_expansion=int(m.get("mlp_expansion", 4)),
141
+ mlp_dropout=float(m.get("mlp_dropout", 0.0)),
142
+ drop_path_rate=float(m.get("drop_path_rate", 0.0)),
143
+ )
144
+
145
+
146
+ def relative_l2_per_sample(pred: torch.Tensor, target: torch.Tensor) -> torch.Tensor:
147
+ pred_f = pred.reshape(pred.shape[0], -1)
148
+ target_f = target.reshape(target.shape[0], -1)
149
+ denom = torch.linalg.vector_norm(target_f, dim=1).clamp_min(1e-12)
150
+ return torch.linalg.vector_norm(pred_f - target_f, dim=1) / denom
151
+
152
+
153
+ def relative_l2_sum(pred: torch.Tensor, target: torch.Tensor) -> torch.Tensor:
154
+ return relative_l2_per_sample(pred, target).sum()
155
+
156
+
157
+ def save_json(path: Path, payload: dict[str, Any]) -> None:
158
+ path.parent.mkdir(parents=True, exist_ok=True)
159
+ with path.open("w", encoding="utf-8") as handle:
160
+ json.dump(payload, handle, indent=2)
161
+
162
+
163
+ __all__ = [
164
+ "ROOT",
165
+ "UnitTransformer",
166
+ "build_model",
167
+ "count_parameters",
168
+ "load_config",
169
+ "make_normalized_loaders",
170
+ "relative_l2_per_sample",
171
+ "relative_l2_sum",
172
+ "resolve",
173
+ "save_json",
174
+ "select_device",
175
+ "set_seed",
176
+ ]
scripts/inference.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ from pathlib import Path
5
+
6
+ import numpy as np
7
+ import torch
8
+
9
+ from common import (
10
+ ROOT,
11
+ UnitTransformer,
12
+ build_model,
13
+ load_config,
14
+ load_pipe_tensors,
15
+ relative_l2_per_sample,
16
+ resolve,
17
+ save_json,
18
+ select_device,
19
+ )
20
+
21
+
22
+ def main() -> None:
23
+ parser = argparse.ArgumentParser(description="Run HO-FNO Pipe inference with the best checkpoint.")
24
+ parser.add_argument("--config", default=str(ROOT / "config" / "config.yaml"))
25
+ parser.add_argument("--checkpoint", default=None)
26
+ args = parser.parse_args()
27
+
28
+ cfg = load_config(args.config)
29
+ output_dir = resolve(cfg["paths"]["output_dir"])
30
+ results_dir = resolve(cfg["paths"]["results_dir"], output_dir)
31
+ results_dir.mkdir(parents=True, exist_ok=True)
32
+ checkpoint = resolve(args.checkpoint or cfg["paths"]["checkpoint"], output_dir)
33
+ device = select_device(require_accelerator=False)
34
+
35
+ payload = torch.load(checkpoint, map_location=device)
36
+ ckpt_cfg = payload.get("config", cfg)
37
+ model = build_model(ckpt_cfg).to(device)
38
+ model.load_state_dict(payload["model_state"])
39
+ model.eval()
40
+ x_norm = UnitTransformer.from_state_dict(payload["x_normalizer"]).to(device)
41
+ y_norm = UnitTransformer.from_state_dict(payload["y_normalizer"]).to(device)
42
+
43
+ _, _, x_test, y_test = load_pipe_tensors(ckpt_cfg)
44
+ batch_size = int(ckpt_cfg["training"]["batch_size"])
45
+ predictions = []
46
+ targets = []
47
+ inputs = []
48
+ rel_values = []
49
+ with torch.no_grad():
50
+ for start in range(0, x_test.shape[0], batch_size):
51
+ x = x_test[start : start + batch_size].to(device)
52
+ y = y_test[start : start + batch_size].to(device)
53
+ pred = y_norm.decode(model(x_norm.encode(x)))
54
+ rel = relative_l2_per_sample(pred, y)
55
+ predictions.append(pred.cpu().numpy())
56
+ targets.append(y.cpu().numpy())
57
+ inputs.append(x.cpu().numpy())
58
+ rel_values.append(rel.cpu().numpy())
59
+
60
+ pred_arr = np.concatenate(predictions, axis=0)
61
+ target_arr = np.concatenate(targets, axis=0)
62
+ input_arr = np.concatenate(inputs, axis=0)
63
+ rel_arr = np.concatenate(rel_values, axis=0)
64
+ np.save(results_dir / "predictions.npy", pred_arr)
65
+ np.save(results_dir / "targets.npy", target_arr)
66
+ np.save(results_dir / "inputs.npy", input_arr)
67
+ np.save(results_dir / "relative_l2_per_sample.npy", rel_arr)
68
+ metrics = {
69
+ "checkpoint": str(checkpoint),
70
+ "test_samples": int(rel_arr.shape[0]),
71
+ "mean_relative_l2": float(rel_arr.mean()),
72
+ "median_relative_l2": float(np.median(rel_arr)),
73
+ "max_relative_l2": float(rel_arr.max()),
74
+ "min_relative_l2": float(rel_arr.min()),
75
+ }
76
+ save_json(results_dir / "inference_metrics.json", metrics)
77
+ print(
78
+ "inference_complete "
79
+ f"mean_relative_l2={metrics['mean_relative_l2']:.8f} "
80
+ f"predictions={results_dir / 'predictions.npy'}",
81
+ flush=True,
82
+ )
83
+
84
+
85
+ if __name__ == "__main__":
86
+ main()
scripts/result.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ from pathlib import Path
5
+
6
+ import matplotlib
7
+
8
+ matplotlib.use("Agg")
9
+ import matplotlib.pyplot as plt
10
+ import numpy as np
11
+
12
+ from common import ROOT, load_config, resolve, save_json
13
+
14
+
15
+ def plot_case(xy: np.ndarray, pred: np.ndarray, target: np.ndarray, out_path: Path, title: str) -> None:
16
+ x = xy[..., 0]
17
+ y = xy[..., 1]
18
+ p = pred[..., 0]
19
+ t = target[..., 0]
20
+ err = p - t
21
+ vmin = float(min(p.min(), t.min()))
22
+ vmax = float(max(p.max(), t.max()))
23
+ fig, axes = plt.subplots(1, 3, figsize=(13, 3.6), constrained_layout=True)
24
+ for ax, field, name, lo, hi, cmap in [
25
+ (axes[0], t, "target", vmin, vmax, "coolwarm"),
26
+ (axes[1], p, "prediction", vmin, vmax, "coolwarm"),
27
+ (axes[2], err, "error", float(-np.max(np.abs(err))), float(np.max(np.abs(err))), "coolwarm"),
28
+ ]:
29
+ mesh = ax.pcolormesh(x, y, field, shading="auto", cmap=cmap, vmin=lo, vmax=hi)
30
+ ax.set_aspect("equal", adjustable="box")
31
+ ax.set_title(name)
32
+ ax.set_xticks([])
33
+ ax.set_yticks([])
34
+ fig.colorbar(mesh, ax=ax, fraction=0.046, pad=0.02)
35
+ fig.suptitle(title)
36
+ fig.savefig(out_path, dpi=180)
37
+ plt.close(fig)
38
+
39
+
40
+ def main() -> None:
41
+ parser = argparse.ArgumentParser(description="Create HO-FNO Pipe visualizations from inference arrays.")
42
+ parser.add_argument("--config", default=str(ROOT / "config" / "config.yaml"))
43
+ parser.add_argument("--num-cases", type=int, default=8)
44
+ args = parser.parse_args()
45
+
46
+ cfg = load_config(args.config)
47
+ output_dir = resolve(cfg["paths"]["output_dir"])
48
+ results_dir = resolve(cfg["paths"]["results_dir"], output_dir)
49
+ pred_path = results_dir / "predictions.npy"
50
+ target_path = results_dir / "targets.npy"
51
+ input_path = results_dir / "inputs.npy"
52
+ rel_path = results_dir / "relative_l2_per_sample.npy"
53
+ for path in [pred_path, target_path, input_path, rel_path]:
54
+ if not path.exists():
55
+ raise FileNotFoundError(f"missing required inference artifact: {path}")
56
+
57
+ pred = np.load(pred_path)
58
+ target = np.load(target_path)
59
+ inputs = np.load(input_path)
60
+ rel = np.load(rel_path)
61
+ fig_dir = results_dir / "figures"
62
+ fig_dir.mkdir(parents=True, exist_ok=True)
63
+ order = np.argsort(rel)
64
+ chosen = []
65
+ if len(order) > 0:
66
+ chosen.extend([int(order[0]), int(order[len(order) // 2]), int(order[-1])])
67
+ for idx in range(min(args.num_cases, len(rel))):
68
+ if idx not in chosen:
69
+ chosen.append(idx)
70
+ chosen = chosen[: max(1, args.num_cases)]
71
+ figures = []
72
+ for idx in chosen:
73
+ out_path = fig_dir / f"pipe_case_{idx:03d}.png"
74
+ plot_case(inputs[idx], pred[idx], target[idx], out_path, f"Pipe case {idx} | rel L2={rel[idx]:.6f}")
75
+ figures.append(str(out_path))
76
+
77
+ summary = {
78
+ "figure_count": len(figures),
79
+ "figures": figures,
80
+ "mean_relative_l2": float(rel.mean()),
81
+ "best_case": int(order[0]) if len(order) else None,
82
+ "median_case": int(order[len(order) // 2]) if len(order) else None,
83
+ "worst_case": int(order[-1]) if len(order) else None,
84
+ }
85
+ save_json(results_dir / "result_summary.json", summary)
86
+ print(f"result_complete figures={len(figures)} summary={results_dir / 'result_summary.json'}", flush=True)
87
+
88
+
89
+ if __name__ == "__main__":
90
+ main()
scripts/train.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import csv
5
+ import time
6
+ from pathlib import Path
7
+
8
+ import torch
9
+
10
+ from common import (
11
+ ROOT,
12
+ build_model,
13
+ count_parameters,
14
+ load_config,
15
+ make_normalized_loaders,
16
+ relative_l2_per_sample,
17
+ relative_l2_sum,
18
+ resolve,
19
+ save_json,
20
+ select_device,
21
+ set_seed,
22
+ )
23
+
24
+
25
+ def evaluate(model, loader, y_normalizer, device):
26
+ model.eval()
27
+ total = 0.0
28
+ count = 0
29
+ with torch.no_grad():
30
+ for x, y_norm in loader:
31
+ x = x.to(device, non_blocking=True)
32
+ y_norm = y_norm.to(device, non_blocking=True)
33
+ pred = y_normalizer.decode(model(x))
34
+ target = y_normalizer.decode(y_norm)
35
+ rel = relative_l2_per_sample(pred, target)
36
+ total += float(rel.sum().item())
37
+ count += int(rel.numel())
38
+ return total / max(1, count)
39
+
40
+
41
+ def main() -> None:
42
+ parser = argparse.ArgumentParser(description="Train HO-FNO on Pipe horizontal velocity.")
43
+ parser.add_argument("--config", default=str(ROOT / "config" / "config.yaml"))
44
+ args = parser.parse_args()
45
+
46
+ cfg = load_config(args.config)
47
+ set_seed(int(cfg["experiment"].get("seed", 2026)))
48
+ output_dir = resolve(cfg["paths"]["output_dir"])
49
+ weight_path = resolve(cfg["paths"]["checkpoint"], output_dir)
50
+ results_dir = resolve(cfg["paths"]["results_dir"], output_dir)
51
+ weight_path.parent.mkdir(parents=True, exist_ok=True)
52
+ results_dir.mkdir(parents=True, exist_ok=True)
53
+
54
+ require_accelerator = bool(cfg["runtime"].get("require_accelerator", False))
55
+ device = select_device(require_accelerator=require_accelerator)
56
+ print(f"device={device}", flush=True)
57
+
58
+ train_loader, test_loader, x_normalizer, y_normalizer = make_normalized_loaders(cfg)
59
+ x_normalizer.to(device)
60
+ y_normalizer.to(device)
61
+
62
+ model = build_model(cfg).to(device)
63
+ print(f"parameters={count_parameters(model)}", flush=True)
64
+
65
+ train_cfg = cfg["training"]
66
+ optimizer = torch.optim.AdamW(
67
+ model.parameters(),
68
+ lr=float(train_cfg["learning_rate"]),
69
+ weight_decay=float(train_cfg.get("weight_decay", 0.0)),
70
+ )
71
+ scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
72
+ optimizer,
73
+ T_max=int(train_cfg["epochs"]),
74
+ eta_min=float(train_cfg["final_learning_rate"]),
75
+ )
76
+
77
+ history_path = results_dir / "train_history.csv"
78
+ best_metric = float("inf")
79
+ best_epoch = -1
80
+ train_size = int(cfg["data"]["train_size"])
81
+ epochs = int(train_cfg["epochs"])
82
+ start_time = time.time()
83
+
84
+ with history_path.open("w", newline="", encoding="utf-8") as handle:
85
+ writer = csv.DictWriter(handle, fieldnames=["epoch", "train_loss", "test_mean_relative_l2", "lr", "seconds"])
86
+ writer.writeheader()
87
+ for epoch in range(1, epochs + 1):
88
+ model.train()
89
+ epoch_start = time.time()
90
+ train_loss_sum = 0.0
91
+ for x, y_norm in train_loader:
92
+ x = x.to(device, non_blocking=True)
93
+ y_norm = y_norm.to(device, non_blocking=True)
94
+ optimizer.zero_grad(set_to_none=True)
95
+ pred = y_normalizer.decode(model(x))
96
+ target = y_normalizer.decode(y_norm)
97
+ loss = relative_l2_sum(pred, target)
98
+ loss.backward()
99
+ optimizer.step()
100
+ train_loss_sum += float(loss.item())
101
+
102
+ scheduler.step()
103
+ train_loss = train_loss_sum / train_size
104
+ test_l2 = evaluate(model, test_loader, y_normalizer, device)
105
+ lr = float(optimizer.param_groups[0]["lr"])
106
+ seconds = time.time() - epoch_start
107
+ writer.writerow(
108
+ {
109
+ "epoch": epoch,
110
+ "train_loss": train_loss,
111
+ "test_mean_relative_l2": test_l2,
112
+ "lr": lr,
113
+ "seconds": seconds,
114
+ }
115
+ )
116
+ handle.flush()
117
+ print(
118
+ f"epoch={epoch:04d} train_loss={train_loss:.8f} "
119
+ f"test_mean_relative_l2={test_l2:.8f} lr={lr:.8e}",
120
+ flush=True,
121
+ )
122
+
123
+ if test_l2 < best_metric:
124
+ best_metric = test_l2
125
+ best_epoch = epoch
126
+ torch.save(
127
+ {
128
+ "model_state": model.state_dict(),
129
+ "config": cfg,
130
+ "epoch": epoch,
131
+ "best_metric": best_metric,
132
+ "x_normalizer": x_normalizer.state_dict(),
133
+ "y_normalizer": y_normalizer.state_dict(),
134
+ },
135
+ weight_path,
136
+ )
137
+ save_json(
138
+ results_dir / "best_metrics.json",
139
+ {"best_epoch": best_epoch, "test_mean_relative_l2": best_metric, "checkpoint": str(weight_path)},
140
+ )
141
+
142
+ torch.save(
143
+ {
144
+ "model_state": model.state_dict(),
145
+ "config": cfg,
146
+ "epoch": epochs,
147
+ "best_metric": best_metric,
148
+ "x_normalizer": x_normalizer.state_dict(),
149
+ "y_normalizer": y_normalizer.state_dict(),
150
+ },
151
+ weight_path.parent / "last_model.pth",
152
+ )
153
+ save_json(
154
+ results_dir / "training_summary.json",
155
+ {
156
+ "epochs": epochs,
157
+ "best_epoch": best_epoch,
158
+ "best_test_mean_relative_l2": best_metric,
159
+ "total_seconds": time.time() - start_time,
160
+ "checkpoint": str(weight_path),
161
+ },
162
+ )
163
+ print(f"best_checkpoint={weight_path}", flush=True)
164
+ print(f"best_epoch={best_epoch} best_test_mean_relative_l2={best_metric:.8f}", flush=True)
165
+
166
+
167
+ if __name__ == "__main__":
168
+ main()
weight/best_model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9d71053c64b62a6fc6f867108c29d2cc0d277d667a3504dc073a6b56072981d4
3
+ size 24981730