DPSDataFidelity#
- class deepinv.sampling.DPSDataFidelity(denoiser=None, weight=1.0, clip=None, guidance='norm', *args, **kwargs)[source]#
Bases:
NoisyDataFidelityDiffusion posterior sampling data-fidelity term.
This corresponds to the \(p(y|x_t)\) approximation proposed in [29]. For the VE parametrization \(x_t=x_0+\sigma_t\omega\), DPS replaces \(p(x_0|x_t)\) by a Dirac mass at the denoised posterior mean:
\[p(x_0|x_t) \approx \delta\!\left(x_0-D(x_t,\sigma_t)\right).\]Two guidance strengths are available, selected with
guidance.guidance="norm"(the default) follows [29] and normalizes the residual by its own norm,\[-\nabla_x \log p_t(y|x) \approx \lambda \nabla_x \| \forw{\denoiser{x}{\sigma}} - y \|,\]which is the step size \(\zeta/\|y - A D(x_t,\sigma_t)\|\) of the original paper.
guidance="annealed"instead uses the Gaussian negative log-likelihood with the annealed variance \(\sigma_y^2+\sigma_t^2\),\[-\nabla_x \log p_t(y|x) \approx \lambda \nabla_x \frac{\| \forw{\denoiser{x}{\sigma}} - y \|^2}{2\left(\sigma_y^2+\sigma_t^2\right)},\]where \(\sigma = \sigma(t)\) is the noise level and \(\lambda\) controls the strength of the approximation.
Note
The two options put
weighton very different scales."norm"carries no noise variance, so \(\lambda\) has to absorb a factor of order \(\|y - A D(x_t,\sigma_t)\|/\sigma_y^2\), which is typically in the hundreds."annealed"shares the guidance strength ofdeepinv.sampling.ALDDataFidelity, so \(\lambda\approx 1\) is the natural choice, consistent with the other noisy data-fidelity terms.See also
This class can be used for building custom DPS-based diffusion models. A self-contained implementation of the original DPS algorithm can be found in
deepinv.sampling.DPS.- Parameters:
denoiser (deepinv.models.Denoiser) – Denoiser network
weight (float) – Weighting factor for the data fidelity term. Default to 1.0 .
clip (tuple[float]) – If not
None, clip the denoised output into[clip[0], clip[1]]interval. Default toNone.guidance (str) – Either
"norm"(default), the residual norm of [29], or"annealed", the Gaussian negative log-likelihood with variance \(\sigma_y^2+\sigma_t^2\), for whichweightis on the same scale as the other noisy data-fidelity terms.
- forward(x, y, physics, sigma, *args, get_model_outputs=False, **kwargs)[source]#
Returns the loss term \(\lambda \| \forw{\denoiser{x}{\sigma}} - y \|\).
- Parameters:
x (torch.Tensor) – input image
y (torch.Tensor) – measurements
physics (deepinv.physics.Physics) – forward operator
sigma (float, torch.Tensor) – standard deviation of the noise.
get_model_outputs (bool) – If
True, also return the denoised output along with the loss. Default toFalse.
- Returns:
(
torch.Tensoror tuple oftorch.Tensor) loss term (and denoised output ifget_model_outputsisTrue).- Return type:
- grad(x, y, physics, sigma, *args, get_model_outputs=False, **kwargs)[source]#
Computes the gradient \(-\nabla_{x_t} \log p_t(y|x_t) \approx \lambda \nabla_{x_t} \| \forw{\denoiser{x}{\sigma}} - y \|\).
- Parameters:
x (torch.Tensor) – Current iterate.
y (torch.Tensor) – Input data.
physics (deepinv.physics.Physics) – physics model
sigma (float, torch.Tensor) – Standard deviation of the noise.
get_model_outputs (bool) – If
True, also return the denoised output along with the score. Default toFalse.
- Returns:
(
torch.Tensoror tuple oftorch.Tensor) score term (and denoised output ifget_model_outputsisTrue).- Return type:
Examples using DPSDataFidelity:#
Using state-of-the-art diffusion models from HuggingFace Diffusers with DeepInverse
Building your diffusion posterior sampling method using SDEs
Flow-Matching for posterior sampling and unconditional generation
Noisy data-fidelity terms for diffusion posterior sampling