def minimize(self, seed_input=None, max_iter=<NUM_LIT:200>,<EOL>input_modifiers=None, grad_modifier=None,<EOL>callbacks=None, verbose=True):
seed_input = self._get_seed_input(seed_input)<EOL>input_modifiers = input_modifiers or []<EOL>grad_modifier = _identity if grad_modifier is None else get(grad_modifier)<EOL>callbacks = callbacks or []<EOL>if verbose:<EOL><INDENT>callbacks.append(_PRINT_CALLBACK)<EOL><DEDENT>cache = None<EOL>best_loss = float('<STR_LIT>')<EOL>best_input = None<EOL>grads = None<EOL>wrt_value = None<EOL>for i in range(max_iter):<EOL><INDENT>for modifier in input_modifiers:<EOL><INDENT>seed_input = modifier.pre(seed_input)<EOL><DEDENT>computed_values = self.compute_fn([seed_input, <NUM_LIT:0>])<EOL>losses = computed_values[:len(self.loss_names)]<EOL>named_losses = list(zip(self.loss_names, losses))<EOL>overall_loss, grads, wrt_value = computed_values[len(self.loss_names):]<EOL>if grads.shape != wrt_value.shape:<EOL><INDENT>grads = np.reshape(grads, wrt_value.shape)<EOL><DEDENT>grads = grad_modifier(grads)<EOL>for c in callbacks:<EOL><INDENT>c.callback(i, named_losses, overall_loss, grads, wrt_value)<EOL><DEDENT>if self.wrt_tensor_is_input_tensor:<EOL><INDENT>step, cache = self._rmsprop(grads, cache)<EOL>seed_input += step<EOL><DEDENT>for modifier in reversed(input_modifiers):<EOL><INDENT>seed_input = modifier.post(seed_input)<EOL><DEDENT>if overall_loss < best_loss:<EOL><INDENT>best_loss = overall_loss.copy()<EOL>best_input = seed_input.copy()<EOL><DEDENT><DEDENT>for c in callbacks:<EOL><INDENT>c.on_end()<EOL><DEDENT>return utils.deprocess_input(best_input[<NUM_LIT:0>], self.input_range), grads, wrt_value<EOL>
Performs gradient descent on the input image with respect to defined losses.

        Args:
            seed_input: An N-dim numpy array of shape: `(samples, channels, image_dims...)` if `image_data_format=
                channels_first` or `(samples, image_dims..., channels)` if `image_data_format=channels_last`.
                Seeded with random noise if set to None. (Default value = None)
            max_iter: The maximum number of gradient descent iterations. (Default value = 200)
            input_modifiers: A list of [InputModifier](vis.input_modifiers#inputmodifier) instances specifying
                how to make `pre` and `post` changes to the optimized input during the optimization process.
                `pre` is applied in list order while `post` is applied in reverse order. For example,
                `input_modifiers = [f, g]` means that `pre_input = g(f(inp))` and `post_input = f(g(inp))`
            grad_modifier: gradient modifier to use. See [grad_modifiers](vis.grad_modifiers.md). If you don't
                specify anything, gradients are unchanged. (Default value = None)
            callbacks: A list of [OptimizerCallback](vis.callbacks#optimizercallback) instances to trigger.
            verbose: Logs individual losses at the end of every gradient descent iteration.
                Very useful to estimate loss weight factor(s). (Default value = True)

        Returns:
            The tuple of `(optimized input, grads with respect to wrt, wrt_value)` after gradient descent iterations.