From e868c471906c46e0ac88fab164e651255b9e1764 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Thu, 14 May 2026 15:50:36 +0200 Subject: [PATCH] PINN: normalizza t in forward(), corregge _pde_scale e aumenta patience MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - forward(): divide t per T_END prima di passarlo alla rete, evita saturazione di Tanh per t∈[0,10] e migliora la sensibilità temporale del modello - _pde_scale: include il picco gaussiano della sorgente come denominatore; con GAUSS_SIGMA=0.01 il picco (~60 °C/s) supera T_char/T_END (15), rendendo la loss PDE non normalizzata senza questa correzione - PATIENCE 100→500, SCHED_PATIENCE 30→150: il training ha ora spazio per convergere prima che l'early stopping o lo scheduler blocchino l'ottimizzatore Co-Authored-By: Claude Sonnet 4.6 --- config.py | 4 ++-- model.py | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/config.py b/config.py index fa43f30..686d56f 100644 --- a/config.py +++ b/config.py @@ -34,10 +34,10 @@ N_BC = 400 # punti condizioni al contorno # Training Adam EPOCHS = 5000 # epoche massime -PATIENCE = 100 # early stopping +PATIENCE = 500 # early stopping LR_ADAM = 1e-3 # learning rate iniziale SCHED_FACTOR = 0.5 # ReduceLROnPlateau: fattore di riduzione -SCHED_PATIENCE = 30 # ReduceLROnPlateau: patience +SCHED_PATIENCE = 150 # ReduceLROnPlateau: patience SCHED_MIN_LR = 1e-6 # ReduceLROnPlateau: lr minimo # Fine-tuning L-BFGS diff --git a/model.py b/model.py index 54e6876..08b3c0e 100644 --- a/model.py +++ b/model.py @@ -14,16 +14,18 @@ class HeatPINN(nn.Module): self.net = nn.Sequential(*layers) def forward(self, xt): - # Output scaled to physical range: T_AMB + (Q*L/K) * net - # net learns dimensionless perturbation; inputs x∈[0,L], t∈[0,T_END] passed as-is - # so Tanh activations see t values up to T_END, providing implicit regularization - return config.T_AMB + (config.Q_VAL * config.L / config.K) * self.net(xt) + # Normalize t to [0,1] to avoid Tanh saturation for large t values (up to T_END) + x = xt[:, :1] + t = xt[:, 1:] / config.T_END + return config.T_AMB + (config.Q_VAL * config.L / config.K) * self.net(torch.cat([x, t], dim=1)) # Precomputed loss scales (depend only on config constants) _T_char = config.Q_VAL * config.L / config.K # ~150 °C — temperature scale _grad_char = (config.Q_VAL / config.K) ** 2 # ~22500 — gradient scale² -_pde_scale = (_T_char / config.T_END) ** 2 + 1e-8 +# _pde_scale covers both dT/dt and the Gaussian source peak (dominant with small sigma) +_src_peak = config.ALPHA * config.Q_VAL / (config.K * config.GAUSS_SIGMA * (2 * 3.141592653589793) ** 0.5) +_pde_scale = max((_T_char / config.T_END) ** 2, _src_peak ** 2) + 1e-8 def heat_pinn_loss(model, x_f, t_f, x_ic, t_bc,