class_docstr: Provides an interface for activation maximization via gradient descent.
  
  This class implements the gradient ascent algorithm in order to perform
  activation maximization with convolutional neural networks (CNN).
  
  `Activation maximization <https://pdfs.semanticscholar.org/65d9/94fb778a8d9e0f632659fb33a082949a50d3.pdf>`_
  is one form of feature visualization that allows us to visualize what CNN
  filters are "looking for", by applying each filter to an input image and
  updating the input image so as to maximize the activation of the filter of
  interest (i.e. treating it as a gradient ascent task with activation as the
  loss). The implementation is inspired by `this demo <https://blog.keras.io/category/demo.html>`_
  by Francois Chollet.
  
  Args:
      model: A neural network model from `torchvision.models
          <https://pytorch.org/docs/stable/torchvision/models.html>`_,
          typically without the fully-connected part of the network.
          e.g. torchvisions.alexnet(pretrained=True).features
      img_size (int, optional, default=224): The size of an input image to be
          optimized.
      lr (float, optional, default=1.): The step size (or learning rate) of
          the gradient ascent.
      use_gpu (bool, optional, default=False): Use GPU if set to True and
          `torch.cuda.is_available()`.
class_docstr_tok: ["Provides","an","interface","for","activation","maximization","via","gradient","descent",".","This","class","implements","the","gradient","ascent","algorithm","in","order","to","perform","activation","maximization","with","convolutional","neural","networks","(","CNN",")",".","`","Activation","maximization","<","https",":","\/\/pdfs.semanticscholar.org\/65d9\/94fb778a8d9e0f632659fb33a082949a50d3.pdf",">","`","_","is","one","form","of","feature","visualization","that","allows","us","to","visualize","what","CNN","filters","are","``","looking","for","''",",","by","applying","each","filter","to","an","input","image","and","updating","the","input","image","so","as","to","maximize","the","activation","of","the","filter","of","interest","(","i.e",".","treating","it","as","a","gradient","ascent","task","with","activation","as","the","loss",")",".","The","implementation","is","inspired","by","`","this","demo","<","https",":","\/\/blog.keras.io\/category\/demo.html",">","`","_","by","Francois","Chollet",".","Args",":","model",":","A","neural","network","model","from","`","torchvision.models","<","https",":","\/\/pytorch.org\/docs\/stable\/torchvision\/models.html",">","`","_",",","typically","without","the","fully-connected","part","of","the","network",".","e.g",".","torchvisions.alexnet","(","pretrained=True",")",".features","img_size","(","int",",","optional",",","default=224",")",":","The","size","of","an","input","image","to","be","optimized",".","lr","(","float",",","optional",",","default=1",".",")",":","The","step","size","(","or","learning","rate",")","of","the","gradient","ascent",".","use_gpu","(","bool",",","optional",",","default=False",")",":","Use","GPU","if","set","to","True","and","`","torch.cuda.is_available","(",")","`","."]
docstr: Generates an image that maximally activates the target filter.
  
  Args:
      layer (torch.nn.modules.conv.Conv2d): The target Conv2d layer from
          which the filter to be chosen, based on `filter_idx`.
      filter_idx (int): The index of the target filter.
      num_iter (int, optional, default=30): The number of iteration for
          the gradient ascent operation.
  
  Returns:
      output (list of torch.Tensor): With dimentions
          :math:`(num_iter, C, H, W)`. The size of the image is
          determined by `img_size` attribute which defaults to 224.
docstr_tok: ["Generates","an","image","that","maximally","activates","the","target","filter",".","Args",":","layer","(","torch.nn.modules.conv.Conv2d",")",":","The","target","Conv2d","layer","from","which","the","filter","to","be","chosen",",","based","on","`","filter_idx","`",".","filter_idx","(","int",")",":","The","index","of","the","target","filter",".","num_iter","(","int",",","optional",",","default=30",")",":","The","number","of","iteration","for","the","gradient","ascent","operation",".","Returns",":","output","(","list","of","torch.Tensor",")",":","With","dimentions",":","math",":","`","(","num_iter",",","C",",","H",",","W",")","`",".","The","size","of","the","image","is","determined","by","`","img_size","`","attribute","which","defaults","to","224","."]
code: def optimize(self, layer, filter_idx, input_=None, num_iter=30):
      """Generates an image that maximally activates the target filter.
  
      Args:
          layer (torch.nn.modules.conv.Conv2d): The target Conv2d layer from
              which the filter to be chosen, based on `filter_idx`.
          filter_idx (int): The index of the target filter.
          num_iter (int, optional, default=30): The number of iteration for
              the gradient ascent operation.
  
      Returns:
          output (list of torch.Tensor): With dimentions
              :math:`(num_iter, C, H, W)`. The size of the image is
              determined by `img_size` attribute which defaults to 224.
  
      """
  
      # Validate the type of the layer
  
      if type(layer) != nn.modules.conv.Conv2d:
          raise TypeError("The layer must be nn.modules.conv.Conv2d.")
  
      # Validate filter index
  
      num_total_filters = layer.out_channels
      self._validate_filter_idx(num_total_filters, filter_idx)
  
      # Inisialize input (as noise) if not provided
  
      if input_ is None:
          input_ = np.uint8(
              np.random.uniform(
                  150, 180, (self._img_size, self._img_size, 3)
              )
          )
          input_ = apply_transforms(input_, size=self._img_size)
  
      if torch.cuda.is_available() and self.use_gpu:
          self.model = self.model.to("cuda")
          input_ = input_.to("cuda")
  
      # Remove previous hooks if any
  
      while len(self.handlers) > 0:
          self.handlers.pop().remove()
  
      # Register hooks to record activation and gradients
  
      self.handlers.append(
          self._register_forward_hooks(layer, filter_idx)
      )
      self.handlers.append(self._register_backward_hooks())
  
      # Inisialize gradients
  
      self.gradients = torch.zeros(input_.shape)
  
      # Optimize
  
      return self._ascent(input_, num_iter)
  
imports: import numpy
  import matplotlib.pyplot
  import torch
  import torch.nn
  from flashtorch.utils import apply_transforms, format_for_plotting, load_image, standardize_and_clip
label_desc: Use image node_id 8 for calling the GradientAscent obj's underlying member method code with example usage: obj.optimize(layer, filter_idx, input_, num_iter) and returns: self