From 256945ada3c3df703f77c8d7012022be26d6a62b Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Thu, 14 May 2026 14:50:18 +0200 Subject: [PATCH] PINN: ripristina forward() originale, aumenta LBFGS_STEPS e corregge pesi loss MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Il training collassava alla soluzione banale T=T_AMB perché W_BC=10 spingeva Adam a soddisfare le Robin BC (trivialmente, con gradiente zero) sacrificando la PDE. Fix: W_PDE=10, W_BC=1 così la PDE domina il gradiente fin dal primo epoch. LBFGS_STEPS: 20→200 perché L-BFGS era l'unico ottimizzatore a fare progressi reali. forward(): rimossa moltiplicazione t_norm che causava vanishing gradient su dT/dx e d²T/dx². Co-Authored-By: Claude Sonnet 4.6 --- config.py | 6 +++--- model.py | 12 ++++-------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/config.py b/config.py index f3c1ef5..c173ccd 100644 --- a/config.py +++ b/config.py @@ -42,9 +42,9 @@ SCHED_MIN_LR = 1e-6 # ReduceLROnPlateau: lr minimo # Fine-tuning L-BFGS LR_LBFGS = 0.1 # learning rate L-BFGS -LBFGS_STEPS = 20 # numero di step L-BFGS +LBFGS_STEPS = 200 # numero di step L-BFGS # Pesi della loss -W_PDE = 1.0 # peso residuo PDE +W_PDE = 10.0 # peso residuo PDE W_IC = 1.0 # peso condizione iniziale -W_BC = 10.0 # peso condizioni al contorno +W_BC = 1.0 # peso condizioni al contorno diff --git a/model.py b/model.py index 65c9a4f..54e6876 100644 --- a/model.py +++ b/model.py @@ -14,14 +14,10 @@ class HeatPINN(nn.Module): self.net = nn.Sequential(*layers) def forward(self, xt): - # Normalize inputs to [0,1]x[0,1] so both dimensions share the same scale - x_norm = xt[:, 0:1] / config.L - t_norm = xt[:, 1:2] / config.T_END - xt_norm = torch.cat([x_norm, t_norm], dim=1) - # Multiply by t_norm to enforce IC as hard constraint: T(x,0) = T_AMB exactly. - # This eliminates the trivial solution (net=0) and forces non-trivial learning for t>0. - T_char = config.Q_VAL * config.L / config.K - return config.T_AMB + T_char * t_norm.squeeze(1) * self.net(xt_norm).squeeze(1) + # 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) # Precomputed loss scales (depend only on config constants)