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:
@@ -34,10 +34,10 @@ N_BC = 400 # punti condizioni al contorno
|
|||||||
|
|
||||||
# Training Adam
|
# Training Adam
|
||||||
EPOCHS = 5000 # epoche massime
|
EPOCHS = 5000 # epoche massime
|
||||||
PATIENCE = 100 # early stopping
|
PATIENCE = 500 # early stopping
|
||||||
LR_ADAM = 1e-3 # learning rate iniziale
|
LR_ADAM = 1e-3 # learning rate iniziale
|
||||||
SCHED_FACTOR = 0.5 # ReduceLROnPlateau: fattore di riduzione
|
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
|
SCHED_MIN_LR = 1e-6 # ReduceLROnPlateau: lr minimo
|
||||||
|
|
||||||
# Fine-tuning L-BFGS
|
# Fine-tuning L-BFGS
|
||||||
|
|||||||
@@ -14,16 +14,18 @@ class HeatPINN(nn.Module):
|
|||||||
self.net = nn.Sequential(*layers)
|
self.net = nn.Sequential(*layers)
|
||||||
|
|
||||||
def forward(self, xt):
|
def forward(self, xt):
|
||||||
# Output scaled to physical range: T_AMB + (Q*L/K) * net
|
# Normalize t to [0,1] to avoid Tanh saturation for large t values (up to T_END)
|
||||||
# net learns dimensionless perturbation; inputs x∈[0,L], t∈[0,T_END] passed as-is
|
x = xt[:, :1]
|
||||||
# so Tanh activations see t values up to T_END, providing implicit regularization
|
t = xt[:, 1:] / config.T_END
|
||||||
return config.T_AMB + (config.Q_VAL * config.L / config.K) * self.net(xt)
|
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)
|
# Precomputed loss scales (depend only on config constants)
|
||||||
_T_char = config.Q_VAL * config.L / config.K # ~150 °C — temperature scale
|
_T_char = config.Q_VAL * config.L / config.K # ~150 °C — temperature scale
|
||||||
_grad_char = (config.Q_VAL / config.K) ** 2 # ~22500 — gradient 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,
|
def heat_pinn_loss(model, x_f, t_f, x_ic, t_bc,
|
||||||
|
|||||||
Reference in New Issue
Block a user