DPSDataFidelity#

class deepinv.sampling.DPSDataFidelity(denoiser=None, weight=1.0, clip=None, guidance='norm', *args, **kwargs)[source]#

Bases: NoisyDataFidelity

Diffusion 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 weight on 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 of deepinv.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 to None.

  • 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 which weight is 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:
Returns:

(torch.Tensor or tuple of torch.Tensor) loss term (and denoised output if get_model_outputs is True).

Return type:

Tensor | tuple[Tensor, Tensor]

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:
Returns:

(torch.Tensor or tuple of torch.Tensor) score term (and denoised output if get_model_outputs is True).

Return type:

Tensor | tuple[Tensor, Tensor]

Examples using DPSDataFidelity:#

Using state-of-the-art diffusion models from HuggingFace Diffusers with DeepInverse

Using state-of-the-art diffusion models from HuggingFace Diffusers with DeepInverse

Building your diffusion posterior sampling method using SDEs

Building your diffusion posterior sampling method using SDEs

DPS – Posterior Sampling with Diffusion Models

DPS -- Posterior Sampling with Diffusion Models

Flow-Matching for posterior sampling and unconditional generation

Flow-Matching for posterior sampling and unconditional generation

Noisy data-fidelity terms for diffusion posterior sampling

Noisy data-fidelity terms for diffusion posterior sampling