Diffusion-Prior Inverse Solver
Studies how diffusion priors and measurement guidance can be combined for inverse-problem reconstruction.

Description
Task: Inverse Problem Algorithm Design with Diffusion Priors
Research Question
Design a novel algorithm for solving scientific inverse problems using pre-trained diffusion model priors. Given a forward operator A and observation y = A(x) + noise, the algorithm should reconstruct x by leveraging a learned diffusion prior p(x).
Background
Diffusion models learn rich priors p(x) over signal distributions. For inverse problems, we want to sample from the posterior p(x|y) ∝ p(y|x) p(x). Existing approaches include:
- DPS — Diffusion Posterior Sampling (Chung et al., "Diffusion Posterior Sampling for General Noisy Inverse Problems", ICLR 2023; arXiv:2209.14687). Uses the score
∇_x log p(x)from the diffusion model and adds measurement guidance∇_x log p(y|x)at each denoising step. Code: https://github.com/DPS2022/diffusion-posterior-sampling. - REDDiff — Variational / Regularization-by-Denoising-Diffusion (Mardani, Song, Kautz, Vahdat, "A Variational Perspective on Solving Inverse Problems with Diffusion Models", ICLR 2024; arXiv:2305.04391). Variational formulation that yields a regularization-by-denoising update where denoisers at different timesteps concurrently impose structural constraints. Code: https://github.com/NVlabs/RED-diff.
- LGD — Loss-Guided Diffusion (Song et al., "Loss-Guided Diffusion Models for Plug-and-Play Controllable Generation", ICML 2023). Estimates the guidance term via Monte Carlo sampling around the denoised estimate to reduce bias of point-estimate approximations.
What to Implement
Implement the Custom class in algo/custom.py. You must implement:
__init__: Set up your algorithm (schedulers, optimizers, hyperparameters).inference(observation, num_samples): Given observationy, return reconstructedx.
Available Components
self.net(x, sigma)→ denoised estimate (Tweedie's formula: E[x_0 | x_t]).self.forward_op.forward(x)→ computeA(x).self.forward_op.gradient(x, y, return_loss=True)→(∇_x ||A(x) - y||², loss).self.forward_op.loss(x, y)→||A(x) - y||².Scheduler(num_steps, schedule, timestep, scaling)→ diffusion noise schedule.DiffusionSampler(scheduler).sample(model, x_start)→ unconditional sampling.
The pretrained denoiser, the forward-operator definitions, and the evaluation problems are fixed; the algorithm only chooses how to combine these pieces.
Evaluation
The algorithm is tested on three scientific inverse problems:
- Inverse Scattering (optical tomography): Recover permittivity from scattered EM fields. Metrics: PSNR, SSIM.
- Black Hole Imaging (radio astronomy): Reconstruct black hole images from sparse interferometric observations (EHT data). Metrics: PSNR, blur-PSNR (f=15), closure-phase chi-squared.
- FFHQ256 Image Inpainting (computer vision): Recover an FFHQ-256 face image from a masked observation (box mask) with additive Gaussian noise (σ=0.05). The forward operator is a fixed pixel-wise mask. Metrics: PSNR, SSIM, LPIPS.
Higher PSNR/SSIM is better; lower LPIPS and chi-squared are better.
Editable Region
The entire algo/custom.py file is editable. You may define any helper classes/functions within this file.
Code
1import torch2from tqdm import tqdm3from algo.base import Algo4from utils.scheduler import Scheduler5from utils.diffusion import DiffusionSampler6import numpy as np789class Custom(Algo):10"""Custom algorithm for solving inverse problems with diffusion priors.1112Available utilities:13- self.net: pre-trained diffusion model.14- self.net(x, sigma) returns denoised estimate (Tweedie's formula).15- self.net.img_channels, self.net.img_resolution: image shape info.
1from abc import ABC, abstractmethod234class Algo(ABC):5def __init__(self, net, # pre-trained diffusion model6forward_op # forward operator of the inverse problem7):8self.net = net9self.forward_op = forward_op1011@abstractmethod12def inference(self, observation, num_samples=1, **kwargs):13'''14Args:15- observation: observation for one single ground truth
1import numpy as np2import copy34'''5Scheduler for diffusion sampling following EDM framework.6schedule (\sigma(t)): linear, sqrt, vp7timestep (discretization of t): log, poly-n, vp8scaling: none, vp910Example:11VP: Scheduler(num_steps=1000, schedule='vp', timestep='vp', scaling='vp')12VE: Scheduler(num_steps=1000, schedule='sqrt', timestep='log', scaling='none')13EDM: Scheduler(num_steps=200, schedule='linear', timestep='poly-7', scaling='none')1415Example Usage: See DiffusionSampler in utils/diffusion.py for unconditional diffusion sampling.
1from tqdm import tqdm2import torch3import numpy as np4from utils.scheduler import Scheduler56class DiffusionSampler:7"""8Diffusion sampler for reverse SDE or PF-ODE9"""1011def __init__(self, scheduler, solver='euler'):12"""13Initializes the diffusion sampler with the given scheduler and solver.1415Parameters:
1from abc import ABC, abstractmethod2from torch.autograd import grad34import torch5from typing import Dict678class BaseOperator(ABC):9def __init__(self, sigma_noise=0.0, unnorm_shift=0.0, unnorm_scale=1.0, device='cuda'):10self.sigma_noise = sigma_noise11self.unnorm_shift = unnorm_shift12self.unnorm_scale = unnorm_scale13self.device = device1415@abstractmethod
1from inverse_problems.base import BaseOperator2import ehtim.statistics.dataframes as ehdf3import pandas as pd4import torch5import numpy as np6import ehtim as eh7from eval import Evaluator8import copy9from piq import psnr10import torch.nn.functional as F11from typing import Dict121314class BlackHoleImaging(BaseOperator):15"""
1from abc import ABC, abstractmethod2import numpy as np3import scipy45import torch6from torch.nn import functional as F7from torchvision.transforms import functional as TF8from torchvision.transforms import InterpolationMode910from typing import List, Optional11from .base import BaseOperator1213# helper functions for implementing the operators14class Blurkernel(torch.nn.Module):15def __init__(self, blur_type='gaussian', kernel_size=31, std=3.0, device=None):
Method Summary
DPS + proximal $x_0$ refinement + EMA
Combine DPS Jacobian guidance with iterative clean-space proximal refinement of $\hat x_0$, both smoothed by per-step EMA momentum.
1. for diffusion step do2.3.4.5. ; for : (with grad-norm clip)6.7. ;8. apply SDE/ODE step using score , then9. if inpaint mask :