Poisson-Gaussian Losses¶
Two different likelihoods are called "Poisson-Gaussian". This page covers both and says which one to use.
| Loss | Model | Use for |
|---|---|---|
PoissonGaussianLoss |
Convolution: a Poisson count read out with additive Gaussian noise | Detector data: shot noise plus read noise (CCD/CMOS, photon counting, microscopy, low-dose imaging) |
PoissonGaussianContaminationMixtureLoss |
Two-component mixture: each sample is Poisson or Gaussian | Not a detector model; see Mixture losses |
EnhancedPoissonGaussianContaminationMixtureLoss |
Same mixture with gain, offset and a signal-dependent Gaussian variance | Not a detector model; see Mixture losses |
PoissonGaussianLikelihoodRatioLoss |
Average of a Poisson deviance and a scaled squared error | Not a likelihood of either model |
API reference
See PoissonGaussianLoss and the other classes in the
API reference for full signatures.
Detector model: PoissonGaussianLoss¶
A detector counts \(K\) photo-electrons, multiplies them by a gain \(g\), adds an offset \(b\) and adds Gaussian read noise:
The density of the measured value is the convolution of the two laws:
\(\lambda\) is the expected count (the model output, or \(\log\lambda\) with
log_input=True), \(g\) is in output units per count, \(b\) is a signed offset
(bias or background in output units) and \(\sigma^2\) is the read-noise variance
in output units squared. The target \(y\) is in output units and can be
non-integer or negative.
Two limits fix the scale of the loss:
- High counts. \(p(y \mid \lambda) \to \mathcal{N}(y;\, g\lambda + b,\, g^2\lambda + \sigma^2)\). The leading correction is the skewness term \(\tfrac{\gamma}{6}\,\mathrm{He}_3(z)\) with \(\gamma = g^3\lambda / (g^2\lambda+\sigma^2)^{3/2} \approx 1/\sqrt{\lambda}\).
- No read noise. With \(g = 1\), \(b = 0\) and \(\sigma \to 0\), integer targets give \(-\log \text{Poisson}(y;\lambda)\) plus the constant \(\tfrac12\log(2\pi\sigma^2)\).
How the sum is evaluated¶
- Finite support. For each element the sum runs over a count window that
keeps at least
tail_sigma(default 12) standard deviations of the Poisson prior, \(\lambda \pm (t\sqrt{\lambda+1} + t^2)\), merged with a window of the same radius around the mode of the posterior \(\Pr(k \mid y)\). The weights are renormalised over the window, so the result is a normalised density. - Outliers. A target far from \(g\lambda + b\) has a posterior window disjoint from the prior window. It is scored on its own window with the exact, unrenormalised Poisson pmf, so the loss keeps growing instead of saturating.
- Bounded memory. Elements are processed in chunks of about \(2^{22}\) count
terms. First derivatives are posterior moments, e.g.
\(\partial\mathcal{L}/\partial b = -\mathbb{E}[y - gk - b \mid y]/\sigma^2\), so the
backward pass stores O(batch) tensors. Second derivatives
(
create_graph=True) recompute through a differentiable log-sum-exp. - Fail closed. Negative or non-finite rates, non-positive gain or read-noise
variance, and non-finite targets raise
ValueError. Masked entries may hold NaN. A window wider thanmax_terms(default 4096, reached near \(\lambda \approx 2\times10^4\)) raises; use the Gaussian limit there.
The algorithm follows poisson_gaussian_nll in torchsky. That version also
provides a CDF, forward-mode AD, second-order rate derivatives at
\(\lambda = 0\) and well-conditioned curvature at tiny rates in float32; these are
not in torchregress.
Parameters¶
gain,offset,read_noise_variance(float): detector constants. Defaults1.0,0.0,1.0.learn_gain,learn_offset,learn_read_noise(bool): learn \(\log g\), \(b\), \(\log\sigma^2\), initialised at the values above. DefaultFalse.log_input(bool):y_predis \(\log\lambda\). DefaultFalse.tail_sigma(float): support radius in standard deviations. Default12.0.max_terms(int): largest allowed count window. Default4096.reduction:'mean'|'sum'|'none'.
forward(y_pred, target, gain=None, offset=None, read_noise_variance=None, mask=None, weights=None)
takes optional per-element calibration maps that replace the module values for
that call. As with the other losses, extra arguments come before mask and
weights; pass them, and mask/weights, by keyword.
Example¶
import math
import torch
from torch import nn
import torchregress as tr
torch.manual_seed(0)
gain, offset, read_var = 2.0, 100.0, 9.0 # ADU per electron, bias in ADU, ADU^2
# Simulated detector: a rate that depends on x, low counts, strong read noise.
x = torch.rand(2000, 1) * 3
rate = torch.exp(0.8 * x - 0.5)
counts = torch.poisson(rate)
y = gain * counts + offset + math.sqrt(read_var) * torch.randn_like(rate)
model = nn.Sequential(nn.Linear(1, 32), nn.Tanh(), nn.Linear(32, 1)) # predicts log rate
loss_fn = tr.losses.PoissonGaussianLoss(
gain=gain, offset=offset, read_noise_variance=read_var, log_input=True
)
opt = torch.optim.Adam(model.parameters(), lr=1e-2)
for _ in range(300):
opt.zero_grad()
loss = loss_fn(model(x), y)
loss.backward()
opt.step()
print(f"final NLL {loss.item():.3f}")
To estimate the read noise from data as well, pass learn_read_noise=True and
add loss_fn.parameters() to the optimiser.
Mixture losses¶
PoissonGaussianContaminationMixtureLoss computes
with the Poisson term from torch.nn.PoissonNLLLoss(full=True). It is a
two-component mixture: each sample comes from one of the two laws.
EnhancedPoissonGaussianContaminationMixtureLoss uses the same form with equal weights,
\(\mu = g\lambda + b\) in both components and a Gaussian variance
\(\sigma_1^2 + \sigma_2^2\,\mu\).
These are not the detector model
Shot noise plus read noise is the convolution above, not a mixture. The mixture also evaluates a Poisson pmf on continuous, possibly negative targets, where it is not a density. For any negative target the Poisson term \(\lambda - y\log\lambda\) goes to \(-\infty\) as \(\lambda \to 0\), so the loss is unbounded below at low counts.
A two-component mixture is the right form for contamination, where a fraction of samples follow a different law (Huber's \(\varepsilon\)-contamination). These two classes give both components the same location \(\lambda\), so they do not down-weight outliers either.
Simulated detector data (\(g = 1\), \(b = 0\); 25 pixels per fit, 300 fits; rate estimated by maximum likelihood; coverage of the 95% profile-likelihood interval):
| \(\lambda\), \(\sigma^2\) | PoissonGaussianLoss bias / coverage |
PoissonGaussianContaminationMixtureLoss bias / coverage |
Enhanced (shot_noise=1) bias / coverage |
|---|---|---|---|
| 0.5, 4 | +3% / 0.97 | estimate collapses to 0 / 0.00 | collapses to 0 / 0.00 |
| 2, 4 | +2% / 0.94 | −71% / 0.14 | −70% / 0.18 |
| 10, 9 | +0.4% / 0.96 | +0.3% / 0.84 | +1.2% / 0.93 |
| 1000, 25 | +0.04% / 0.95 | +0.08% / 0.61 (estimator sd 1.6×) | +0.04% / 0.95 |
At high counts the enhanced mixture with shot_noise = g matches the Gaussian
limit because its Gaussian component is \(\mathcal{N}(g\lambda, g^2\lambda+\sigma^2)\)
and the Poisson component is negligible. With 10% broad outliers added, every
loss in the table is biased by several standard errors.
Parameters¶
PoissonGaussianContaminationMixtureLoss:
eps(float): numerical floor. Default1e-8.learn_variance(bool),initial_variance(float),min_variance(float): Gaussian variance \(\sigma^2\).log_input(bool):y_predis \(\log\lambda\). DefaultFalse.mixture_weights: weight \(w\) of the Poisson component;None(0.5), a float, or'learn'.extra_variance_model(bool): add theextra_varforward argument to \(\sigma^2\). Note thatextra_varis the third positional parameter offorward(y_pred, target, extra_var=None, mask=None, weights=None).
EnhancedPoissonGaussianContaminationMixtureLoss:
gain,offset,read_noise(\(\sigma_1^2\)),shot_noise(\(\sigma_2^2\)): floats or'learn'.log_input(bool),calibration(bool, adds a learnable affine map on \(\lambda\)).
import torch
import torchregress as tr
y_pred = torch.log(torch.tensor([[10.0, 20.0], [5.0, 15.0]]))
target = torch.tensor([[11.2, 19.5], [4.8, 16.3]])
mixture = tr.losses.PoissonGaussianContaminationMixtureLoss(initial_variance=0.1, log_input=True)
enhanced = tr.losses.EnhancedPoissonGaussianContaminationMixtureLoss(
gain=1.0, read_noise=0.1, shot_noise=1.0, log_input=True
)
print(mixture(y_pred, target), enhanced(y_pred, target))
Likelihood-ratio loss¶
PoissonGaussianLikelihoodRatioLoss returns
\(\tfrac12\big(D_{\text{Pois}}(y,\lambda) + (y-\lambda)^2/\sigma^2\big)\), the mean
of a Poisson likelihood-ratio deviance and a scaled squared error. It is a
heuristic score, not the likelihood of either model above.
When to use which¶
flowchart TD
A[Targets are detector readouts?] -->|yes| C[PoissonGaussianLoss]
A -->|no, integer counts without read noise| D[PoissonDevianceLoss / NegativeBinomialNLLLoss]
A -->|no, continuous with outliers| E[Robust losses]
| Situation | Loss |
|---|---|
| Shot noise plus read noise, any count level | PoissonGaussianLoss |
| Very high counts (\(\lambda \gtrsim 2\times10^4\)) | Gaussian NLL with variance \(g^2\lambda+\sigma^2\) |
| Pure counts, no read noise | PoissonDevianceLoss, NegativeBinomialNLLLoss (Poisson & Tweedie) |
| Outlier contamination | Robust losses |
Gain and offset identifiability
With learnable gain and offset, \(g\), \(b\) and the scale of \(\lambda\) trade off against each other unless the rate is anchored, e.g. by a fixed gain from a photon-transfer curve or by bias frames for \(b\).
Next steps¶
- Poisson & Tweedie — count models without read noise
- Gaussian losses — the high-count limit
- Transform losses — variance-stabilising transforms (Anscombe) as an alternative
- Poisson-Gaussian example — runnable demo of the mixture losses
References¶
| # | Reference |
|---|---|
| 1 | D.L. Snyder, A.M. Hammoud, R.L. White. "Image recovery from data acquired with a charge-coupled-device camera." J. Opt. Soc. Am. A, 10(5):1014–1023, 1993. |
| 2 | J. Seifert et al. "Maximum-likelihood estimation in ptychography in the presence of Poisson-Gaussian noise statistics." Optics Letters, 48(22):6027–6030, 2023. |
| 3 | A. Foi, M. Trimeche, V. Katkovnik, K. Egiazarian. "Practical Poissonian-Gaussian Noise Modeling and Fitting for Single-Image Raw-Data." IEEE Trans. Image Process., 17(10):1737–1754, 2008. |
| 4 | P.J. Huber. "Robust estimation of a location parameter." Ann. Math. Statist., 35(1):73–101, 1964. |
| 5 | G.J. McLachlan, D. Peel. Finite Mixture Models. Wiley, 2000. |