class_docstr: A template to construct a feature extractor consisting of a CNN followed by a
  sequence-to-sequence contextualizer like a Transformer-Encoder. Before inputting the CNN output
  tensor to the contextualizer, the tensor's spatial dimensions are unrolled
  into a sequence.
  
  Args:
      cnn (nn.Module): any convolutional neural network that takes in batches of images of
           shape (batch_size, channels, height, width) and outputs tensor
           representations of shape (batch_size, out_channels, out_height, out_width).
      cnn_output_shape (tuple): A tuple of shape (batch_size, num_channels, height, width)
                         describing the output shape of the given CNN (required).
      contextualizer (nn.Module, optional): A sequence-to-sequence model that takes inputs of shape
                       (num_timesteps, batch_size, num_features) and uses
                       attention to contextualize the sequence and returns
                       a sequence of the exact same shape. This will mainly be
                       a Transformer-Encoder (required).
      output_type (string): One of 'sequence' or 'spatial'. If Spatial then the final
                    output of the model, which is a sequence, will be reshaped
                    to resemble the image-batch shape of the output of the CNN.
                    If Sequence then the output sequence is returned as is (required).
  
  Examples:
      >>> cnn = nn.Sequential(nn.Conv2d(3, 32, kernel_size=3),
      >>>                     nn.Conv2d(32, 64, kernel_size=3),
      >>>                     nn.MaxPool2d(2))
      >>> cnn_output_shape = (-1, 64, 8, 8)
      >>> contextualizer = nn.TransformerEncoderLayer(...)
      >>> output_type = 'spatial'
      >>>
      >>> attention_cnn = ContextCNNGeneric(cnn, cnn_output_shape, contextualizer, output_type)
      >>> output = attention_cnn(torch.randn((32,3,16,16)))
      >>>
      >>> output.size() == cnn_output_shape # True
code: def __init__(
      self,
      cnn: nn.Module,
      cnn_output_shape: Tuple[int, int, int, int],
      contextualizer: Union[nn.Module, Any],
      output_type: str,
  ):
      super(ContextCNNGeneric, self).__init__()
      assert output_type in ["spatial", "sequence"], (
          "parameter 'output_type' must be one of ('spatial', 'sequence')"
          + f" but is {output_type}"
      )
  
      self.cnn = cnn
      self.cnn_output_shape = cnn_output_shape
      self.contextualizer = contextualizer
      self.output_type = output_type
  
file_path: pykale/kale/embed/attention_cnn.py
imports: from typing import Any, Tuple, Union
  import torch
  import torch.nn
  from kale.embed.positional_encoding import PositionalEncoding
  from kale.prepdata.tensor_reshape import seq_to_spatial, spatial_to_seq
label_desc: Use image node_id 1 to create a new ContextCNNGeneric object from inherited base classes: nn with example: obj = ContextCNNGeneric(cnn, cnn_output_shape, contextualizer, output_type)