VIVEK JAYARAM commited on
Commit
c829170
1 Parent(s): 366a67c

More sample images, finished readme

Browse files
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, lambda_val=None):
 
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
 
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