PINN: normalizza t in forward(), corregge _pde_scale e aumenta patience

- 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 <noreply@anthropic.com>
This commit is contained in:
2026-05-14 15:50:36 +02:00
parent 649d26cfd4
commit e868c47190
2 changed files with 9 additions and 7 deletions
+2 -2
View File
@@ -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
+7 -5
View File
@@ -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,