def render_vis( model, objective_f, param_f=None, optimizer=None, transforms=None, thresholds=(512, ), verbose=False, preprocess=True, progress=True, show_image=True, save_image=False, image_name=None, show_inline=False, fixed_image_size=None, ): if param_f is None: param_f = lambda: param.image(128) # param_f is a function that should return two things # params - parameters to update, which we pass to the optimizer # image_f - a function that returns an image as a tensor params, image_f = param_f() if optimizer is None: optimizer = lambda params: torch.optim.Adam(params, lr=5e-2) optimizer = optimizer(params) if transforms is None: transforms = transform.standard_transforms transforms = transforms.copy() if preprocess: if model._get_name() == "InceptionV1": # Original Tensorflow InceptionV1 takes input range [-117, 138] transforms.append(transform.preprocess_inceptionv1()) else: # Assume we use normalization for torchvision.models # See https://pytorch.org/docs/stable/torchvision/models.html transforms.append(transform.normalize()) # Upsample images smaller than 224 image_shape = image_f().shape if fixed_image_size is not None: new_size = fixed_image_size elif image_shape[2] < 224 or image_shape[3] < 224: new_size = 224 else: new_size = None if new_size: transforms.append( torch.nn.Upsample(size=new_size, mode="bilinear", align_corners=True)) transform_f = transform.compose(transforms) hook = hook_model(model, image_f) objective_f = objectives.as_objective(objective_f) if verbose: model(transform_f(image_f())) print("Initial loss: {:.3f}".format(objective_f(hook))) images = [] try: for i in tqdm(range(1, max(thresholds) + 1), disable=(not progress)): optimizer.zero_grad() try: model.encode_image(transform_f(image_f())) except RuntimeError as ex: if i == 1: # Only display the warning message # on the first iteration, no need to do that # every iteration warnings.warn( "Some layers could not be computed because the size of the " "image is not big enough. It is fine, as long as the non" "computed layers are not used in the objective function" f"(exception details: '{ex}')") loss = objective_f(hook) loss.backward() optimizer.step() if i in thresholds: image = tensor_to_img_array(image_f()) if verbose: print("Loss at step {}: {:.3f}".format( i, objective_f(hook))) if show_inline: show(image) images.append(image) except KeyboardInterrupt: print("Interrupted optimization at step {:d}.".format(i)) if verbose: print("Loss at step {}: {:.3f}".format(i, objective_f(hook))) images.append(tensor_to_img_array(image_f())) if save_image: export(image_f(), image_name) if show_inline: show(tensor_to_img_array(image_f())) elif show_image: view(image_f()) return images
def render_vis(model, objective_f, param_f=None, optimizer=None, transforms=None, thresholds=(512, ), verbose=False, preprocess=True, progress=True, show_image=True, save_image=False, image_name=None, show_inline=False): if param_f is None: param_f = lambda: param.image(128) # param_f is a function that should return two things # params - parameters to update, which we pass to the optimizer # image_f - a function that returns an image as a tensor params, image_f = param_f() if optimizer is None: optimizer = lambda params: torch.optim.Adam(params, lr=5e-2) optimizer = optimizer(params) if transforms is None: transforms = transform.standard_transforms.copy() if preprocess: if model._get_name() == "InceptionV1": # Original Tensorflow InceptionV1 takes input range [-117, 138] transforms.append(transform.preprocess_inceptionv1()) else: # Assume we use normalization for torchvision.models # See https://pytorch.org/docs/stable/torchvision/models.html transforms.append(transform.normalize()) # Upsample images smaller than 224 image_shape = image_f().shape if image_shape[2] < 224 or image_shape[3] < 224: transforms.append( torch.nn.Upsample(size=224, mode='bilinear', align_corners=True)) transform_f = transform.compose(transforms) hook = hook_model(model, image_f) objective_f = objectives.as_objective(objective_f) if verbose: model(transform_f(image_f())) print("Initial loss: {:.3f}".format(objective_f(hook))) images = [] try: for i in tqdm(range(1, max(thresholds) + 1), disable=(not progress)): optimizer.zero_grad() model(transform_f(image_f())) loss = objective_f(hook) loss.backward() optimizer.step() if i in thresholds: image = tensor_to_img_array(image_f()) if verbose: print("Loss at step {}: {:.3f}".format( i, objective_f(hook))) if show_inline: show(image) images.append(image) except KeyboardInterrupt: print("Interrupted optimization at step {:d}.".format(i)) if verbose: print("Loss at step {}: {:.3f}".format(i, objective_f(hook))) images.append(tensor_to_img_array(image_f())) if save_image: export(image_f(), image_name) if show_inline: show(tensor_to_img_array(image_f())) elif show_image: view(image_f()) return images