Note
New to DeepInverse? Get started with the basics with the 5 minute quickstart tutorial..
Uncertainty quantification with PnP-ULA.#
This code shows you how to use sampling algorithms to quantify uncertainty of a reconstruction from incomplete and noisy measurements.
ULA obtains samples by running the following iteration:
where \(z_k \sim \mathcal{N}(0, I)\) is a Gaussian random variable, \(\eta\) is the step size and \(\alpha\) is a parameter controlling the regularization.
The PnP-ULA method is described in the paper Laumont et al.[1].
import deepinv as dinv
from deepinv.utils.plotting import plot
import torch
from deepinv.utils import load_example
Load image from the internet#
This example uses an image of Messi.
device = dinv.utils.get_device()
x = load_example("messi.jpg", img_size=32).to(device)
Selected GPU 0 with 5670.25 MiB free memory
Define forward operator and noise model#
This example uses inpainting as the forward operator and Gaussian noise as the noise model.
sigma = 0.1 # noise level
physics = dinv.physics.Inpainting(mask=0.5, img_size=x.shape[1:], device=device)
physics.noise_model = dinv.physics.GaussianNoise(sigma=sigma)
# Set the global random seed from pytorch to ensure reproducibility of the example.
torch.manual_seed(0)
<torch._C.Generator object at 0x7f1bba7883b0>
Define the likelihood#
Since the noise model is Gaussian, the negative log-likelihood is the L2 loss.
# load Gaussian Likelihood
likelihood = dinv.optim.data_fidelity.L2(sigma=sigma)
Define the prior#
The score a distribution can be approximated using Tweedieβs formula via the
deepinv.optim.ScorePrior class.
This example uses a pretrained DnCNN model.
From a Bayesian point of view, the score plays the role of the gradient of the
negative log prior
The hyperparameter sigma_denoiser (\(sigma\)) controls the strength of the prior.
In this example, we use a pretrained DnCNN model using the deepinv.loss.FNEJacobianSpectralNorm loss,
which makes sure that the denoiser is firmly non-expansive (see Terris et al.[2]), and helps to
stabilize the sampling algorithm.
sigma_denoiser = 2 / 255
prior = dinv.optim.ScorePrior(
denoiser=dinv.models.DnCNN(pretrained="download_lipschitz")
).to(device)
Create the MCMC sampler#
Here we use the Unadjusted Langevin Algorithm (ULA) to sample from the posterior defined in
deepinv.sampling.ULAIterator.
The hyperparameter step_size controls the step size of the MCMC sampler,
regularization controls the strength of the prior and
iterations controls the number of iterations of the sampler.
regularization = 0.9
step_size = 0.01 * (sigma**2)
iterations = int(5e3) if torch.cuda.is_available() else 10
params = {
"step_size": step_size,
"alpha": regularization,
"sigma": sigma_denoiser,
}
f = dinv.sampling.sampling_builder(
"ULA",
prior=prior,
data_fidelity=likelihood,
max_iter=iterations,
params_algo=params,
thinning=1,
verbose=True,
)
Generate the measurement#
We apply the forward model to generate the noisy measurement.
Run sampling algorithm and plot results#
The sampling algorithm returns the posterior mean and variance. We compare the posterior mean with a simple linear reconstruction.
mean, var = f.sample(y, physics)
# compute linear inverse
x_lin = physics.A_adjoint(y)
# compute PSNR
print(f"Linear reconstruction PSNR: {dinv.metric.PSNR()(x, x_lin).item():.2f} dB")
print(f"Posterior mean PSNR: {dinv.metric.PSNR()(x, mean).item():.2f} dB")
# plot results
error = (mean - x).abs().sum(dim=1).unsqueeze(1) # per pixel average abs. error
std = var.sum(dim=1).unsqueeze(1).sqrt() # per pixel average standard dev.
imgs = [x_lin, x, mean, std / std.flatten().max(), error / error.flatten().max()]
plot(
imgs,
titles=["measurement", "ground truth", "post. mean", "post. std", "abs. error"],
)

0%| | 0/5000 [00:00<?, ?it/s]
1%| | 30/5000 [00:00<00:16, 298.39it/s]
1%| | 61/5000 [00:00<00:16, 304.28it/s]
2%|β | 92/5000 [00:00<00:16, 306.04it/s]
2%|β | 123/5000 [00:00<00:15, 306.72it/s]
3%|β | 154/5000 [00:00<00:15, 306.67it/s]
4%|β | 185/5000 [00:00<00:15, 306.77it/s]
4%|β | 216/5000 [00:00<00:15, 306.76it/s]
5%|β | 247/5000 [00:00<00:15, 306.70it/s]
6%|β | 278/5000 [00:00<00:15, 306.61it/s]
6%|β | 309/5000 [00:01<00:15, 306.49it/s]
7%|β | 340/5000 [00:01<00:15, 306.58it/s]
7%|β | 371/5000 [00:01<00:15, 306.68it/s]
8%|β | 402/5000 [00:01<00:14, 306.62it/s]
9%|β | 433/5000 [00:01<00:14, 306.68it/s]
9%|β | 464/5000 [00:01<00:14, 306.71it/s]
10%|β | 495/5000 [00:01<00:14, 306.88it/s]
11%|β | 526/5000 [00:01<00:14, 307.07it/s]
11%|β | 557/5000 [00:01<00:14, 307.09it/s]
12%|ββ | 588/5000 [00:01<00:14, 307.15it/s]
12%|ββ | 619/5000 [00:02<00:14, 307.28it/s]
13%|ββ | 650/5000 [00:02<00:14, 307.18it/s]
14%|ββ | 681/5000 [00:02<00:14, 307.28it/s]
14%|ββ | 712/5000 [00:02<00:13, 307.44it/s]
15%|ββ | 743/5000 [00:02<00:13, 307.59it/s]
15%|ββ | 774/5000 [00:02<00:13, 307.34it/s]
16%|ββ | 805/5000 [00:02<00:13, 307.41it/s]
17%|ββ | 836/5000 [00:02<00:13, 307.35it/s]
17%|ββ | 867/5000 [00:02<00:13, 306.13it/s]
18%|ββ | 898/5000 [00:02<00:13, 306.07it/s]
19%|ββ | 929/5000 [00:03<00:13, 306.26it/s]
19%|ββ | 960/5000 [00:03<00:13, 306.75it/s]
20%|ββ | 991/5000 [00:03<00:13, 307.36it/s]
20%|ββ | 1022/5000 [00:03<00:13, 303.32it/s]
21%|ββ | 1053/5000 [00:03<00:13, 298.94it/s]
22%|βββ | 1083/5000 [00:03<00:13, 295.95it/s]
22%|βββ | 1113/5000 [00:03<00:13, 294.10it/s]
23%|βββ | 1143/5000 [00:03<00:13, 292.70it/s]
23%|βββ | 1173/5000 [00:03<00:13, 291.52it/s]
24%|βββ | 1203/5000 [00:03<00:13, 290.96it/s]
25%|βββ | 1233/5000 [00:04<00:12, 290.54it/s]
25%|βββ | 1263/5000 [00:04<00:12, 290.04it/s]
26%|βββ | 1293/5000 [00:04<00:12, 289.96it/s]
26%|βββ | 1322/5000 [00:04<00:12, 289.65it/s]
27%|βββ | 1351/5000 [00:04<00:12, 289.70it/s]
28%|βββ | 1380/5000 [00:04<00:12, 289.48it/s]
28%|βββ | 1409/5000 [00:04<00:12, 289.59it/s]
29%|βββ | 1438/5000 [00:04<00:12, 289.46it/s]
29%|βββ | 1467/5000 [00:04<00:12, 289.31it/s]
30%|βββ | 1496/5000 [00:04<00:12, 289.38it/s]
30%|βββ | 1525/5000 [00:05<00:12, 289.47it/s]
31%|βββ | 1554/5000 [00:05<00:11, 289.59it/s]
32%|ββββ | 1584/5000 [00:05<00:11, 289.99it/s]
32%|ββββ | 1614/5000 [00:05<00:11, 290.07it/s]
33%|ββββ | 1644/5000 [00:05<00:11, 290.34it/s]
33%|ββββ | 1674/5000 [00:05<00:11, 290.06it/s]
34%|ββββ | 1704/5000 [00:05<00:11, 290.10it/s]
35%|ββββ | 1734/5000 [00:05<00:11, 290.16it/s]
35%|ββββ | 1764/5000 [00:05<00:11, 290.25it/s]
36%|ββββ | 1794/5000 [00:06<00:11, 290.28it/s]
36%|ββββ | 1824/5000 [00:06<00:10, 289.54it/s]
37%|ββββ | 1853/5000 [00:06<00:10, 289.39it/s]
38%|ββββ | 1882/5000 [00:06<00:10, 289.56it/s]
38%|ββββ | 1911/5000 [00:06<00:10, 289.52it/s]
39%|ββββ | 1941/5000 [00:06<00:10, 289.72it/s]
39%|ββββ | 1971/5000 [00:06<00:10, 290.02it/s]
40%|ββββ | 2001/5000 [00:06<00:10, 290.00it/s]
41%|ββββ | 2031/5000 [00:06<00:10, 290.16it/s]
41%|ββββ | 2061/5000 [00:06<00:10, 289.42it/s]
42%|βββββ | 2090/5000 [00:07<00:10, 288.82it/s]
42%|βββββ | 2119/5000 [00:07<00:09, 288.62it/s]
43%|βββββ | 2148/5000 [00:07<00:09, 288.59it/s]
44%|βββββ | 2177/5000 [00:07<00:09, 288.61it/s]
44%|βββββ | 2206/5000 [00:07<00:09, 288.80it/s]
45%|βββββ | 2235/5000 [00:07<00:09, 287.06it/s]
45%|βββββ | 2264/5000 [00:07<00:09, 285.66it/s]
46%|βββββ | 2293/5000 [00:07<00:09, 284.65it/s]
46%|βββββ | 2322/5000 [00:07<00:09, 283.78it/s]
47%|βββββ | 2351/5000 [00:07<00:09, 283.10it/s]
48%|βββββ | 2380/5000 [00:08<00:09, 282.86it/s]
48%|βββββ | 2409/5000 [00:08<00:09, 282.66it/s]
49%|βββββ | 2438/5000 [00:08<00:09, 282.57it/s]
49%|βββββ | 2467/5000 [00:08<00:08, 281.52it/s]
50%|βββββ | 2496/5000 [00:08<00:08, 281.48it/s]
50%|βββββ | 2525/5000 [00:08<00:08, 281.36it/s]
51%|βββββ | 2554/5000 [00:08<00:08, 281.43it/s]
52%|ββββββ | 2583/5000 [00:08<00:08, 281.63it/s]
52%|ββββββ | 2612/5000 [00:08<00:08, 281.50it/s]
53%|ββββββ | 2641/5000 [00:08<00:08, 280.89it/s]
53%|ββββββ | 2670/5000 [00:09<00:08, 281.26it/s]
54%|ββββββ | 2699/5000 [00:09<00:08, 281.82it/s]
55%|ββββββ | 2728/5000 [00:09<00:08, 281.85it/s]
55%|ββββββ | 2757/5000 [00:09<00:07, 281.88it/s]
56%|ββββββ | 2786/5000 [00:09<00:07, 281.92it/s]
56%|ββββββ | 2815/5000 [00:09<00:07, 282.10it/s]
57%|ββββββ | 2844/5000 [00:09<00:07, 282.11it/s]
57%|ββββββ | 2873/5000 [00:09<00:07, 282.11it/s]
58%|ββββββ | 2902/5000 [00:09<00:07, 282.30it/s]
59%|ββββββ | 2931/5000 [00:09<00:07, 282.48it/s]
59%|ββββββ | 2960/5000 [00:10<00:07, 282.49it/s]
60%|ββββββ | 2989/5000 [00:10<00:07, 282.57it/s]
60%|ββββββ | 3018/5000 [00:10<00:07, 282.45it/s]
61%|ββββββ | 3047/5000 [00:10<00:06, 282.24it/s]
62%|βββββββ | 3076/5000 [00:10<00:06, 282.11it/s]
62%|βββββββ | 3105/5000 [00:10<00:06, 282.31it/s]
63%|βββββββ | 3134/5000 [00:10<00:06, 282.38it/s]
63%|βββββββ | 3163/5000 [00:10<00:06, 282.43it/s]
64%|βββββββ | 3192/5000 [00:10<00:06, 281.71it/s]
64%|βββββββ | 3221/5000 [00:11<00:06, 281.16it/s]
65%|βββββββ | 3250/5000 [00:11<00:06, 281.35it/s]
66%|βββββββ | 3279/5000 [00:11<00:06, 281.73it/s]
66%|βββββββ | 3308/5000 [00:11<00:05, 282.01it/s]
67%|βββββββ | 3337/5000 [00:11<00:05, 282.11it/s]
67%|βββββββ | 3366/5000 [00:11<00:05, 281.54it/s]
68%|βββββββ | 3395/5000 [00:11<00:05, 281.79it/s]
68%|βββββββ | 3424/5000 [00:11<00:05, 282.06it/s]
69%|βββββββ | 3453/5000 [00:11<00:05, 281.97it/s]
70%|βββββββ | 3482/5000 [00:11<00:05, 282.10it/s]
70%|βββββββ | 3511/5000 [00:12<00:05, 282.24it/s]
71%|βββββββ | 3540/5000 [00:12<00:05, 282.36it/s]
71%|ββββββββ | 3569/5000 [00:12<00:05, 282.44it/s]
72%|ββββββββ | 3598/5000 [00:12<00:04, 282.21it/s]
73%|ββββββββ | 3627/5000 [00:12<00:04, 282.14it/s]
73%|ββββββββ | 3656/5000 [00:12<00:04, 282.11it/s]
74%|ββββββββ | 3685/5000 [00:12<00:04, 282.17it/s]
74%|ββββββββ | 3714/5000 [00:12<00:04, 282.30it/s]
75%|ββββββββ | 3743/5000 [00:12<00:04, 282.46it/s]
75%|ββββββββ | 3772/5000 [00:12<00:04, 282.31it/s]
76%|ββββββββ | 3801/5000 [00:13<00:04, 282.00it/s]
77%|ββββββββ | 3830/5000 [00:13<00:04, 282.20it/s]
77%|ββββββββ | 3859/5000 [00:13<00:04, 282.39it/s]
78%|ββββββββ | 3888/5000 [00:13<00:03, 282.22it/s]
78%|ββββββββ | 3917/5000 [00:13<00:03, 282.07it/s]
79%|ββββββββ | 3946/5000 [00:13<00:03, 282.11it/s]
80%|ββββββββ | 3975/5000 [00:13<00:03, 282.24it/s]
80%|ββββββββ | 4004/5000 [00:13<00:03, 282.25it/s]
81%|ββββββββ | 4033/5000 [00:13<00:03, 282.44it/s]
81%|ββββββββ | 4062/5000 [00:14<00:03, 282.31it/s]
82%|βββββββββ | 4091/5000 [00:14<00:03, 282.41it/s]
82%|βββββββββ | 4120/5000 [00:14<00:03, 282.72it/s]
83%|βββββββββ | 4149/5000 [00:14<00:03, 281.48it/s]
84%|βββββββββ | 4178/5000 [00:14<00:02, 281.68it/s]
84%|βββββββββ | 4207/5000 [00:14<00:02, 281.66it/s]
85%|βββββββββ | 4236/5000 [00:14<00:02, 281.91it/s]
85%|βββββββββ | 4265/5000 [00:14<00:02, 282.14it/s]
86%|βββββββββ | 4294/5000 [00:14<00:02, 282.38it/s]
86%|βββββββββ | 4323/5000 [00:14<00:02, 282.54it/s]
87%|βββββββββ | 4352/5000 [00:15<00:02, 282.28it/s]
88%|βββββββββ | 4381/5000 [00:15<00:02, 282.25it/s]
88%|βββββββββ | 4410/5000 [00:15<00:02, 282.47it/s]
89%|βββββββββ | 4439/5000 [00:15<00:01, 282.50it/s]
89%|βββββββββ | 4468/5000 [00:15<00:01, 281.90it/s]
90%|βββββββββ | 4497/5000 [00:15<00:01, 281.97it/s]
91%|βββββββββ | 4526/5000 [00:15<00:01, 282.12it/s]
91%|βββββββββ | 4555/5000 [00:15<00:01, 282.26it/s]
92%|ββββββββββ| 4584/5000 [00:15<00:01, 282.03it/s]
92%|ββββββββββ| 4613/5000 [00:15<00:01, 282.28it/s]
93%|ββββββββββ| 4642/5000 [00:16<00:01, 282.19it/s]
93%|ββββββββββ| 4671/5000 [00:16<00:01, 282.18it/s]
94%|ββββββββββ| 4700/5000 [00:16<00:01, 282.13it/s]
95%|ββββββββββ| 4729/5000 [00:16<00:00, 282.36it/s]
95%|ββββββββββ| 4758/5000 [00:16<00:00, 281.90it/s]
96%|ββββββββββ| 4787/5000 [00:16<00:00, 281.86it/s]
96%|ββββββββββ| 4816/5000 [00:16<00:00, 282.23it/s]
97%|ββββββββββ| 4845/5000 [00:16<00:00, 282.17it/s]
97%|ββββββββββ| 4874/5000 [00:16<00:00, 282.51it/s]
98%|ββββββββββ| 4903/5000 [00:16<00:00, 282.11it/s]
99%|ββββββββββ| 4933/5000 [00:17<00:00, 284.52it/s]
99%|ββββββββββ| 4963/5000 [00:17<00:00, 286.40it/s]
100%|ββββββββββ| 4992/5000 [00:17<00:00, 287.26it/s]
100%|ββββββββββ| 5000/5000 [00:17<00:00, 288.64it/s]
Iteration 4999, current converge crit. = 1.43E-05, objective = 1.00E-03
Iteration 4999, current converge crit. = 3.42E-04, objective = 1.00E-03
Linear reconstruction PSNR: 8.55 dB
Posterior mean PSNR: 22.31 dB
- References:
Total running time of the script: (0 minutes 17.804 seconds)