Skip to content

About

Inverse PINN in PyTorch that recovers thermal diffusivity from sparse, noisy temperature data — benchmarked against least-squares and a data-only MLP on a 1-D heat equation with ground truth.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

ThermalLens

Inverse thermal diffusivity estimation with a physics-informed neural network.

Can a neural network recover a material's thermal diffusivity from sparse, noisy temperature measurements — and how does it compare with conventional parameter fitting?

This repository implements an inverse PINN in PyTorch on a 1-D heat-conduction problem with a known closed-form solution, so that every claim can be checked against ground truth. It compares the PINN against a nonlinear least-squares fit on the analytical solution and against a matched network trained without physics constraints.

Headline result

With 50 noisy observations at 5% noise, the PINN recovered the thermal diffusivity to 1.39 ± 0.54 % (3 seeds), against 1.16 ± 0.94 % for a nonlinear least-squares fit on the closed-form solution. The two methods are statistically indistinguishable here — and the PINN is about 190,000× more expensive.

The more interesting finding is why they agree: across all nine runs their signed errors match in sign every time, with a Pearson correlation of 0.975. Both methods are limited by the same thing — the particular noise realisation — rather than by any property of the method. The PINN is extracting essentially all the information the measurements contain.

A matched network trained on the same data with the physics terms switched off reaches 60 ± 22 % field error and produces no parameter estimate at all.


The problem

A 1-D slab held at the reference temperature at both ends, with no internal heat source:

$$\frac{\partial \theta}{\partial t} = \alpha \frac{\partial^2 \theta}{\partial x^2}$$

Quantity Symbol Value
Slab length $L$ 0.01 m
Observation duration $t_{\max}$ 0.5 s
True diffusivity (synthetic) $\alpha$ $1\times10^{-5}$ m²/s

Normalised coordinates

Training directly in SI units is badly conditioned: $\alpha \sim 10^{-5}$ while $x \sim 10^{-2}$, so the second derivative lives around $10^{4}$ and the loss terms differ by many orders of magnitude. Rescaling onto the unit square with $\xi = x/L$ and $\tau = t/t_{\max}$ gives

$$\frac{\partial\theta}{\partial\tau} = \mu \frac{\partial^{2}\theta}{\partial\xi^{2}}, \qquad \mu = \frac{\alpha, t_{\max}}{L^{2}} = 0.05$$

The network learns $\mu$, not $\alpha$. The physical diffusivity is recovered with $\hat\alpha = \hat\mu L^{2}/t_{\max}$, a factor of $2\times10^{-4}$. This is the easiest thing in the project to get wrong, so test_conversion_factor_is_not_one asserts it explicitly.

Initial and boundary conditions

$$\theta(\xi,0) = \sin(\pi\xi) + 0.5\sin(2\pi\xi), \qquad \theta(0,\tau) = \theta(1,\tau) = 0$$

Both terms are eigenfunctions of $\partial^2/\partial\xi^2$ that vanish at the walls, so the problem has an exact solution:

$$\theta^{*}(\xi,\tau) = e^{-\mu\pi^{2}\tau}\sin(\pi\xi) + 0.5,e^{-4\mu\pi^{2}\tau}\sin(2\pi\xi)$$

Mode $n$ decays at rate $n^2\mu\pi^2$. That rate gap is what makes $\mu$ identifiable: over the observation window mode 1 decays to 0.610 of its initial amplitude and mode 2 to 0.139, so the shape of the profile — not just its amplitude — changes measurably with time.

The analytical solution generates the synthetic observations and scores the results. It is never shown to the PINN during training.


Method

A tanh MLP (3 hidden layers, 48 units, 4,898 parameters) maps $(\xi,\tau) \to \theta$. The normalised diffusivity is a trainable scalar optimised jointly with the network weights.

Positivity by construction. $\mu = e^{\eta}$ with $\eta$ unconstrained. A negative diffusivity is not merely a wrong value — the backwards heat equation is ill-posed, and high-frequency components grow without bound. The exponential makes negative values unreachable rather than forbidden, and keeps the gradient smooth where a clamp would not.

The residual is computed by automatic differentiation, not finite differences:

$$r(\xi,\tau) = \frac{\partial\theta}{\partial\tau} - \hat\mu\frac{\partial^{2}\theta}{\partial\xi^{2}}$$

The first torch.autograd.grad call passes create_graph=True, which makes the first derivative a differentiable expression rather than a plain number, so it can be differentiated again.

The loss has four mean-squared-error terms:

$$\mathcal{L} = w_d \mathcal{L}{\rm data} + w_f \mathcal{L}{\rm PDE}

  • w_i \mathcal{L}{\rm IC} + w_b \mathcal{L}{\rm BC}$$
Term Points Weight
Data — fit the noisy measurements 20 / 50 / 100 sensors 1
PDE — satisfy the heat equation 4,000 collocation points 1
IC — match the known initial profile 200 at $\tau=0$ 10
BC — hold the walls at zero 200 at $\xi=0,1$ 10

The initial and boundary conditions are weighted above the data because they are known exactly while the measurements are noisy. The value 10 is a round number that worked, not a tuned optimum — see Limitations.

The PDE term is the only one containing $\mu$, so it is the only source of gradient for the parameter.

Optimisation is Adam (8,000 iterations, lr 2e-3 halving every 2,000) followed by L-BFGS with a strong-Wolfe line search. The second stage is not optional: inverse PINNs frequently stall under Adam alone, and a stalled optimiser is indistinguishable from a failed method.

Experimental design

  • Observations are drawn away from the boundaries ($\xi \in [0.05, 0.95]$) and after the initial instant ($\tau \geq 0.02$). A sensor on a boundary would only restate something the model is already told exactly.
  • Noise is additive and homoscedastic: $\sigma = 0.05 \times 1.2990 = 0.0650$, a fixed fraction of the initial-profile peak, not a percentage of each reading. Scaling per reading would make measurements near zero almost exact and quietly make the problem easier. Late in the window the effective noise is around 10%.
  • Evaluation is on a dense, clean 101×101 grid — not at the sensor locations — so the reported errors measure the field between the sensors.
  • Three seeds per setting. The seed determines the data draw, the network initialisation and the collocation points.
  • Failed runs are kept. results/metrics.csv contains every run; nothing is filtered.

Results

All numbers below are printed from results/metrics.csv by scripts/results_tables.py. Nothing is transcribed by hand.

Per-seed runs at 50 observations

Seed Method alpha_hat (m^2/s) alpha error (%) field L2 (%) time (s)
0 PINN 9.8218e-06 1.78 0.567 377.0
0 Analytical least squares 9.9088e-06 0.91 0.275 0.0
0 Data-only MLP — — 80.065 14.9
1 PINN 1.0162e-05 1.62 0.681 386.6
1 Analytical least squares 1.0220e-05 2.20 0.658 0.0
1 Data-only MLP — — 36.421 16.0
2 PINN 9.9216e-06 0.78 0.332 382.8
2 Analytical least squares 9.9627e-06 0.37 0.112 0.0
2 Data-only MLP — — 63.481 15.3

Sensor-count study (mean ± sd over 3 seeds)

Observations Method alpha error (%) field L2 error (%) time (s)
20 PINN 5.62 ± 4.26 1.873 ± 1.462 380.4 ± 2.3
20 Analytical least squares 5.32 ± 5.23 1.638 ± 1.649 0.0 ± 0.0
20 Data-only MLP n/a 40.383 ± 1.062 10.1 ± 0.4
50 PINN 1.39 ± 0.54 0.526 ± 0.178 382.1 ± 4.8
50 Analytical least squares 1.16 ± 0.94 0.348 ± 0.280 0.0 ± 0.0
50 Data-only MLP n/a 59.989 ± 22.031 15.4 ± 0.6
100 PINN 2.92 ± 1.01 0.949 ± 0.156 378.9 ± 5.5
100 Analytical least squares 2.98 ± 0.29 0.896 ± 0.095 0.0 ± 0.0
100 Data-only MLP n/a 61.306 ± 21.302 17.6 ± 1.0

All metrics at 50 observations

Metric PINN Analytical least squares Data-only MLP
Relative alpha error (%) 1.39 ± 0.54 1.16 ± 0.94 n/a
Relative L2 field error (%) 0.526 ± 0.178 0.348 ± 0.280 59.989 ± 22.031
Field MAE 0.00245 ± 0.00075 0.00153 ± 0.00123 0.23153 ± 0.08543
Max absolute field error 0.00698 ± 0.00326 0.00439 ± 0.00352 1.96637 ± 0.84160
PDE residual RMSE 0.00647 ± 0.00074 0.00000 ± 0.00000 5.61991 ± 3.07276
Time (s) 382.13 ± 4.81 0.00 ± 0.00 15.42 ± 0.56

Temperature field: analytical, PINN, and their difference

Absolute error over the domain, and profile slices

Loss components and the recovery of the diffusivity

Diffusivity error and field accuracy against sensor count

Reading the results

The PINN matches the analytical baseline, and that is the point. At every sensor count the two agree within the seed-to-seed spread. Given that the least-squares fit is handed the exact modal form of the solution and has one scalar left to fit, matching it means the PINN — which is told only the differential equation — is recovering close to all the information available in the data.

Both methods make the same errors. Across all nine runs the signed errors of the PINN and the least-squares fit agree in sign every time, with a Pearson correlation of 0.975. When the PINN is 10.5% low, the baseline is 11.2% low on the same data. The error is therefore set by the noise realisation, not by the method.

The error is not monotonic in sensor count — 5.62% at 20 observations, 1.39% at 50, 2.92% at 100 — and the honest reading is that this study cannot resolve the trend. The near-optimal baseline shows the same non-monotonic pattern (5.32%, 1.16%, 2.98%), which rules out a defect in the PINN and points at the obvious cause: with only three seeds, the variation between noise realisations is larger than the effect of sensor count over this range. Resolving it would need tens of seeds. The jump from 20 to 50 observations is large enough to survive that caveat; the difference between 50 and 100 is not.

The physics constraints are doing the work. The data-only MLP reaches 40–61% relative field error against 0.5–1.9% for the PINN, and its PDE residual RMSE is about 6.0 against 0.0065 — roughly three orders of magnitude worse. With the same architecture, the same data and the same optimiser budget, the only difference is the physics terms. It also cannot estimate the diffusivity at all: with no PDE term, nothing in the objective depends on the parameter.

The data loss stops at the noise floor. In the reference run it converged to 3.86×10⁻³ against a noise variance of σ² = 4.22×10⁻³ — visible as the dotted line in the loss figure. A model memorising the individual noise draws would have driven it toward zero. This is the clearest evidence that the network learned the field rather than the measurements.

Where the error lives. The error field shows a near-zero band at ξ ≈ 0.5 and two lobes either side, which is the node of the second sine mode. Error grows toward late times, where the signal has decayed and the effective noise is largest.


Baselines

Baseline What it is What it tests
Analytical least squares scipy.optimize.least_squares fitting $\mu$ in the closed-form solution to the same noisy data Parameter recovery
Data-only MLP Identical architecture, optimiser and budget; PDE/IC/BC terms switched off What the physics constraints buy
Exact solution Closed form at the true $\mu$ Ground truth, not a trained baseline

The least-squares baseline is deliberately stronger than the PINN, and this comparison is not apples-to-apples. It is handed the exact modal form of the solution — two sine modes, the right wavenumbers, the right exponential structure — and has a single scalar left to fit. The PINN is told only the differential equation and must discover the field shape as well as the coefficient.

Its role is therefore as a yardstick for the data, not a competitor: it indicates how much information about $\mu$ the measurements contain at all. It also only exists because this problem has a closed-form solution. Make the diffusivity temperature-dependent, change the geometry, or go to two dimensions, and it has nothing to fit.

The data-only MLP cannot estimate $\mu$ at all — with no physics term, nothing in the objective depends on the parameter. Its $\mu$ columns in the CSV are empty, and that emptiness is the result.


Reproducing

Tested on Python 3.12, CPU only. No GPU required.

git clone https://github.com/dd1o7/ThermalLens.git
cd ThermalLens

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt   # required before the tests will import

# 38 tests, a few seconds
pytest -q

# the full study: ~70 minutes on two CPU cores
python run_experiments.py

# regenerate the README's results tables from the CSV
python scripts/results_tables.py

run_experiments.py writes results/metrics.csv, results/summary.json, results/reference_run.npz and all four figures. Every number in this README is printed from those files by scripts/results_tables.py — none is transcribed by hand.

Layout

thermallens/
  physics.py      analytical solution, unit conversions
  data.py         synthetic observations, collocation/IC/BC sampling
  model.py        the MLP and the trainable positive mu
  train.py        PDE residual, the four losses, Adam + L-BFGS
  baselines.py    analytical least-squares fit
  experiments.py  the sweep, metrics, CSV output
  figures.py      the four figures
tests/            38 tests
scripts/          results tables generated from the CSV
results/          metrics.csv, summary.json, figures/

Tests worth knowing about

The most important test is test_autograd_residual_matches_closed_form_when_mu_is_wrong. A wrong second derivative raises no error — it silently produces a plausible wrong answer — so testing a trained network against its own output would catch nothing. Instead a stub exposing the model's interface returns the closed-form solution, and the residual is checked both where it must vanish and where it must equal a known non-zero quantity. The second case pins down sign and scale, which a vanishing-residual test alone cannot.


Limitations

The inverse crime. The data was generated with the same equation the PINN was then given. This measures whether the method's machinery works; it does not show that a PINN recovers diffusivity from real measurements. A real experiment has contact resistance, unmodelled heat loss, a temperature-dependent diffusivity and imperfect boundaries — all model error, and model error is what breaks inverse methods in practice.

Scope. One dimension, one unknown coefficient, one geometry, one initial profile, one noise model (Gaussian, i.i.d.).

Loss weights are not tuned. $w_i = w_b = 10$ worked; no sensitivity study was run. Every weight is configurable and every component is logged separately, so the study is set up but not performed.

No uncertainty estimate. The method returns a point estimate with no confidence interval. On real data, with no ground truth to compare against, that is close to useless. Ensembling or a Bayesian PINN would be the route.

Three seeds is few — enough to show the spread exists, not to characterise it. Error bars in the figures are ±1 standard deviation over three runs, which is an indication of spread and not a confidence interval.

The noise sweep was not run. The code supports 0% / 5% / 10%; only 5% was executed, because the sensor-count study had priority.

Boundaries are enforced softly. Multiplying the network output by $\xi(1-\xi)$ would satisfy them exactly by construction and remove one loss term and one weight. The soft version was kept because the four-term loss is the standard formulation; the hard constraint is a clear next improvement.

Next steps

  1. Hard-constrain the boundary conditions and measure the difference.
  2. Run the noise sweep the code already supports.
  3. Make the diffusivity temperature-dependent — this breaks the analytical baseline entirely, which is where a PINN starts to earn its cost.
  4. Add an uncertainty estimate, starting with an ensemble over seeds.
  5. Move to 2-D, where no closed form exists and a mesh-free method has a real advantage.

Note on AI-assisted development

The code in this repository was written with AI assistance. The scientific design — which experiments to run, which baselines make the comparison fair, what the metrics should measure — and the interpretation of the results are my own. Every implementation decision here is one I can explain and defend.

No claim of novelty is made. This is a careful re-implementation of a known method on a problem small enough to verify completely.

References

  • Raissi, Perdikaris & Karniadakis (2019), Physics-informed neural networks, Journal of Computational Physics 378, 686–707 — the formulation used here, including the inverse-problem variant.
  • Cornell Virtual Workshop, Scientific Machine Learning — tutorial treatment of learning unknown coefficients jointly with a network.

Licence

MIT

About

Inverse PINN in PyTorch that recovers thermal diffusivity from sparse, noisy temperature data — benchmarked against least-squares and a data-only MLP on a 1-D heat equation with ground truth.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages