VIVEK JAYARAM
commited on
Commit
•
c829170
1
Parent(s):
366a67c
More sample images, finished readme
Browse files- README.md +38 -2
- cdim/eta_scheduler.py +10 -1
- inference.py +1 -2
- models/imagenet_model_config.yaml +20 -0
- noise_configs/poisson_noise_config.yaml +1 -1
- sample_images/celebhq_00001.jpg +0 -0
- sample_images/celebhq_29999.jpg +0 -0
- sample_images/ffhq_00010.png +0 -0
- sample_images/imagenet_val_00002.png +0 -0
- sample_images/lsun_church.png +0 -0
README.md
CHANGED
@@ -16,14 +16,14 @@ We solve noisy linear inverse problems with diffusion models. The method is fast
|
|
16 |
|
17 |
## Getting started
|
18 |
|
|
|
|
|
19 |
### 1) Clone the repository
|
20 |
|
21 |
```
|
22 |
git clone https://github.com/vivjay30/cdim
|
23 |
|
24 |
cd cdim
|
25 |
-
|
26 |
-
export PYTHONPATH=$PYTHONPATH:`pwd`
|
27 |
```
|
28 |
|
29 |
### 2) Install dependencies
|
@@ -37,3 +37,39 @@ pip install -r requirements.txt
|
|
37 |
|
38 |
pip install torch==2.4.1+cu124 torchvision-0.19.1+cu124 --extra-index-url https://download.pytorch.org/whl/cu124
|
39 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
## Getting started
|
18 |
|
19 |
+
Recommended environment: Python 3.11, Cuda 12, Conda. For lower verions please adjust the dependencies below.
|
20 |
+
|
21 |
### 1) Clone the repository
|
22 |
|
23 |
```
|
24 |
git clone https://github.com/vivjay30/cdim
|
25 |
|
26 |
cd cdim
|
|
|
|
|
27 |
```
|
28 |
|
29 |
### 2) Install dependencies
|
|
|
37 |
|
38 |
pip install torch==2.4.1+cu124 torchvision-0.19.1+cu124 --extra-index-url https://download.pytorch.org/whl/cu124
|
39 |
```
|
40 |
+
|
41 |
+
## Inference Examples
|
42 |
+
We recommend using the ddpm models from the diffusers library. These are better and can be run without any manual downloading. Model will be downloaded on first run. The run will produce a noisy_measurement.png and output.png. The ouptut directory can be passed as an argument. You can use kl optimization instead of l2 with the `--loss kl` flag.
|
43 |
+
|
44 |
+
#### CelebHQ Inpainting Example
|
45 |
+
|
46 |
+
`python inference.py sample_images/celebhq_00001.jpg 50 3 operator_configs/box_inpainting_config.yaml noise_configs/gaussian_noise_config.yaml google/ddpm-celebahq-256`
|
47 |
+
|
48 |
+
#### LSUN Churches Gaussian Deblur Example
|
49 |
+
`python inference.py sample_images/lsun_church.png 50 3 operator_configs/gaussian_blur_config.yaml noise_configs/gaussian_noise_config.yaml google/ddpm-church-256`
|
50 |
+
|
51 |
+
#### Poisson Noise Example
|
52 |
+
`python inference.py sample_images/celebhq_29999.jpg 50 3 operator_configs/identity_operator_config.yaml noise_configs/poisson_noise_config.yaml google/ddpm-celebahq-256 --loss kl --eta-type gradnorm`
|
53 |
+
|
54 |
+
#### Discrete KL with Bimodal Noise Example
|
55 |
+
An example to show discrete KL on a non-standard noise distirbution
|
56 |
+
`python inference.py sample_images/celebhq_00001.jpg 200 1 operator_configs/box_inpainting_config.yaml noise_configs/bimodal_noise_config.yaml google/ddpm-celebahq-256 --loss categorical_kl --lambda-val 2 --eta-type gradnorm`
|
57 |
+
|
58 |
+
## FFHQ and Imagenet Models
|
59 |
+
These models are generally not as strong as the huggingface ddpm models, but are used for comparisons with baseline methods.
|
60 |
+
|
61 |
+
From [this link](https://drive.google.com/drive/folders/1jElnRoFv7b31fG0v6pTSQkelbSX3xGZh?usp=sharing), download the checkpoints "ffhq_10m.pt" and "imagenet_256.pt" to models/
|
62 |
+
|
63 |
+
#### Imagenet Super Resolution Example
|
64 |
+
`python inference.py sample_images/imagenet_val_00002.png 50 3 operator_configs/super_resolution_config.yaml noise_configs/gaussian_noise_config.yaml models/imagenet_model_config.yaml`
|
65 |
+
|
66 |
+
#### FFHQ Random Inpainting (Faster)
|
67 |
+
Here we set T=25 and K=1 to show the algorithm running faster
|
68 |
+
`python inference.py sample_images/ffhq_00010.png 25 1 operator_configs/random_inpainting_config.yaml noise_configs/gaussian_noise_config.yaml models/ffhq_model_config.yaml`
|
69 |
+
|
70 |
+
## A note on Eta and Lambda schedules
|
71 |
+
By default the model tries to use expected gradnorm to set the step size schedule (eta). The gradient magnitudes have been precomputed on the train set and are stored in `etas.json`. However, those values are only valid for the specific tasks and number of steps T and K. When using a different task or step configuration, we fall back to `--eta-type gradnorm` which performs individual step gradient normalization as the value of eta. You can always use that flag, which is a less efficient but more general method.
|
72 |
+
|
73 |
+
In addition, the step size schedule eta is scaled by a constant value lambda (the proportionality constant). Getting eta and lambda correct is vital to good convergence, especially with fewer denoising and optimization steps. If you find that the model overfits (loss oscillates wildly) or undefits (loss doesn't go to 0 for KL or sigma^2 for L2), then you should tweak the argument `--lambda-val`. The best guess is printed out for you to use as a starting point.
|
74 |
+
|
75 |
+
|
cdim/eta_scheduler.py
CHANGED
@@ -1,7 +1,8 @@
|
|
1 |
import json
|
2 |
|
3 |
class EtaScheduler:
|
4 |
-
def __init__(self, method, task, T, K, loss_type,
|
|
|
5 |
self.task = task
|
6 |
self.T = T
|
7 |
self.K = K
|
@@ -10,11 +11,19 @@ class EtaScheduler:
|
|
10 |
self.method = method
|
11 |
|
12 |
self.precomputed_etas = self._load_precomputed_etas()
|
|
|
13 |
# Couldn't find expected gradnorm
|
14 |
if not self.precomputed_etas and method == "expected_gradnorm":
|
15 |
self.method = "gradnorm"
|
16 |
print("Etas for this configuration not found. Switching to gradnorm.")
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
# Get the best lambda_val if it's not passed
|
19 |
if self.lambda_val is None:
|
20 |
if self.method == "expected_gradnorm":
|
|
|
1 |
import json
|
2 |
|
3 |
class EtaScheduler:
|
4 |
+
def __init__(self, method, task, T, K, loss_type,
|
5 |
+
noise_function, lambda_val=None):
|
6 |
self.task = task
|
7 |
self.T = T
|
8 |
self.K = K
|
|
|
11 |
self.method = method
|
12 |
|
13 |
self.precomputed_etas = self._load_precomputed_etas()
|
14 |
+
|
15 |
# Couldn't find expected gradnorm
|
16 |
if not self.precomputed_etas and method == "expected_gradnorm":
|
17 |
self.method = "gradnorm"
|
18 |
print("Etas for this configuration not found. Switching to gradnorm.")
|
19 |
|
20 |
+
|
21 |
+
# Precomputed gradients are only for gaussian noise
|
22 |
+
if noise_function.name != "gaussian" and method == "expected_gradnorm":
|
23 |
+
self.method = "gradnorm"
|
24 |
+
print("Precomputed gradients are only for gaussian noise. Switching to gradnorm.")
|
25 |
+
|
26 |
+
|
27 |
# Get the best lambda_val if it's not passed
|
28 |
if self.lambda_val is None:
|
29 |
if self.method == "expected_gradnorm":
|
inference.py
CHANGED
@@ -17,7 +17,6 @@ from cdim.diffusion.scheduling_ddim import DDIMScheduler
|
|
17 |
from cdim.diffusion.diffusion_pipeline import run_diffusion
|
18 |
from cdim.eta_scheduler import EtaScheduler
|
19 |
|
20 |
-
# torch.manual_seed(7)
|
21 |
|
22 |
def load_image(path):
|
23 |
"""
|
@@ -83,7 +82,7 @@ def main(args):
|
|
83 |
save_to_image(noisy_measurement, os.path.join(args.output_dir, "noisy_measurement.png"))
|
84 |
|
85 |
eta_scheduler = EtaScheduler(args.eta_type, operator.name, args.T,
|
86 |
-
args.K, args.loss, args.lambda_val)
|
87 |
|
88 |
t0 = time.time()
|
89 |
output_image = run_diffusion(
|
|
|
17 |
from cdim.diffusion.diffusion_pipeline import run_diffusion
|
18 |
from cdim.eta_scheduler import EtaScheduler
|
19 |
|
|
|
20 |
|
21 |
def load_image(path):
|
22 |
"""
|
|
|
82 |
save_to_image(noisy_measurement, os.path.join(args.output_dir, "noisy_measurement.png"))
|
83 |
|
84 |
eta_scheduler = EtaScheduler(args.eta_type, operator.name, args.T,
|
85 |
+
args.K, args.loss, noise_function, args.lambda_val)
|
86 |
|
87 |
t0 = time.time()
|
88 |
output_image = run_diffusion(
|
models/imagenet_model_config.yaml
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Defaults for image training.
|
2 |
+
|
3 |
+
image_size: 256
|
4 |
+
num_channels: 256
|
5 |
+
num_res_blocks: 2
|
6 |
+
channel_mult: ""
|
7 |
+
learn_sigma: True
|
8 |
+
class_cond: False
|
9 |
+
use_checkpoint: False
|
10 |
+
attention_resolutions: "32,16,8"
|
11 |
+
num_heads: 4
|
12 |
+
num_head_channels: 64
|
13 |
+
num_heads_upsample: -1
|
14 |
+
use_scale_shift_norm: True
|
15 |
+
dropout: 0.0
|
16 |
+
resblock_updown: True
|
17 |
+
use_fp16: False
|
18 |
+
use_new_attention_order: False
|
19 |
+
|
20 |
+
model_path: models/imagenet256.pt
|
noise_configs/poisson_noise_config.yaml
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
name: poisson
|
2 |
-
rate: 0.
|
|
|
1 |
name: poisson
|
2 |
+
rate: 0.05
|
sample_images/celebhq_00001.jpg
ADDED
sample_images/celebhq_29999.jpg
ADDED
sample_images/ffhq_00010.png
ADDED
sample_images/imagenet_val_00002.png
ADDED
sample_images/lsun_church.png
ADDED