Anonymous-123/ImageNet-Editing
1
1"""2Like image_sample.py, but use a noisy image classifier to guide the sampling3process towards more realistic images.4"""5 6import argparse7import os8 9import numpy as np10import torch as th11import torch.distributed as dist12import torch.nn.functional as F13 14from guided_diffusion import dist_util, logger15from guided_diffusion.script_util import (16 NUM_CLASSES,17 model_and_diffusion_defaults,18 classifier_defaults,19 create_model_and_diffusion,20 create_classifier,21 add_dict_to_argparser,22 args_to_dict,23)24 25 26def main():27 args = create_argparser().parse_args()28 29 dist_util.setup_dist()30 logger.configure()31 32 logger.log("creating model and diffusion...")33 model, diffusion = create_model_and_diffusion(34 **args_to_dict(args, model_and_diffusion_defaults().keys())35 )36 model.load_state_dict(37 dist_util.load_state_dict(args.model_path, map_location="cpu")38 )39 model.to(dist_util.dev())40 if args.use_fp16:41 model.convert_to_fp16()42 model.eval()43 44 logger.log("loading classifier...")45 classifier = create_classifier(**args_to_dict(args, classifier_defaults().keys()))46 classifier.load_state_dict(47 dist_util.load_state_dict(args.classifier_path, map_location="cpu")48 )49 classifier.to(dist_util.dev())50 if args.classifier_use_fp16:51 classifier.convert_to_fp16()52 classifier.eval()53 54 def cond_fn(x, t, y=None):55 assert y is not None56 with th.enable_grad():57 x_in = x.detach().requires_grad_(True)58 logits = classifier(x_in, t)59 log_probs = F.log_softmax(logits, dim=-1)60 selected = log_probs[range(len(logits)), y.view(-1)]61 return th.autograd.grad(selected.sum(), x_in)[0] * args.classifier_scale62 63 def model_fn(x, t, y=None):64 assert y is not None65 return model(x, t, y if args.class_cond else None)66 67 logger.log("sampling...")68 all_images = []69 all_labels = []70 while len(all_images) * args.batch_size < args.num_samples:71 model_kwargs = {}72 classes = th.randint(73 low=0, high=NUM_CLASSES, size=(args.batch_size,), device=dist_util.dev()74 )75 model_kwargs["y"] = classes76 sample_fn = (77 diffusion.p_sample_loop if not args.use_ddim else diffusion.ddim_sample_loop78 )79 sample = sample_fn(80 model_fn,81 (args.batch_size, 3, args.image_size, args.image_size),82 clip_denoised=args.clip_denoised,83 model_kwargs=model_kwargs,84 cond_fn=cond_fn,85 device=dist_util.dev(),86 )87 sample = ((sample + 1) * 127.5).clamp(0, 255).to(th.uint8)88 sample = sample.permute(0, 2, 3, 1)89 sample = sample.contiguous()90 91 gathered_samples = [th.zeros_like(sample) for _ in range(dist.get_world_size())]92 dist.all_gather(gathered_samples, sample) # gather not supported with NCCL93 all_images.extend([sample.cpu().numpy() for sample in gathered_samples])94 gathered_labels = [th.zeros_like(classes) for _ in range(dist.get_world_size())]95 dist.all_gather(gathered_labels, classes)96 all_labels.extend([labels.cpu().numpy() for labels in gathered_labels])97 logger.log(f"created {len(all_images) * args.batch_size} samples")98 99 arr = np.concatenate(all_images, axis=0)100 arr = arr[: args.num_samples]101 label_arr = np.concatenate(all_labels, axis=0)102 label_arr = label_arr[: args.num_samples]103 if dist.get_rank() == 0:104 shape_str = "x".join([str(x) for x in arr.shape])105 out_path = os.path.join(logger.get_dir(), f"samples_{shape_str}.npz")106 logger.log(f"saving to {out_path}")107 np.savez(out_path, arr, label_arr)108 109 dist.barrier()110 logger.log("sampling complete")111 112 113def create_argparser():114 defaults = dict(115 clip_denoised=True,116 num_samples=10000,117 batch_size=16,118 use_ddim=False,119 model_path="",120 classifier_path="",121 classifier_scale=1.0,122 )123 defaults.update(model_and_diffusion_defaults())124 defaults.update(classifier_defaults())125 parser = argparse.ArgumentParser()126 add_dict_to_argparser(parser, defaults)127 return parser128 129 130if __name__ == "__main__":131 main()132 