class_docstr: Two-dimensional attentional pooling
  
  Adapted from CLIP: https://github.com/openai/CLIP/blob/main/clip/model.py
  
  Arguments
  ---------
  spatial_dim: int
      the size of the spatial dimension
  embed_dim: int
      the embedding dimension
  num_heads_channels: int
      the number of attention heads
  output_dim: int
      the output dimension
  
  Example
  -------
  >>> attn_pool = AttentionPool2d(
  ...     spatial_dim=64,
  ...     embed_dim=16,
  ...     num_heads_channels=2,
  ...     output_dim=4
  ... )
  >>> x = torch.randn(4, 1, 64, 64)
  >>> x_pool = attn_pool(x)
  >>> x_pool.shape
  torch.Size([4, 4])
class_docstr_tok: ["Two-dimensional","attentional","pooling","Adapted","from","CLIP",":","https",":","\/\/github.com\/openai\/CLIP\/blob\/main\/clip\/model.py","Arguments","--","--","--","--","-","spatial_dim",":","int","the","size","of","the","spatial","dimension","embed_dim",":","int","the","embedding","dimension","num_heads_channels",":","int","the","number","of","attention","heads","output_dim",":","int","the","output","dimension","Example","--","--","--","-",">",">",">","attn_pool","=","AttentionPool2d","(","...","spatial_dim=64",",","...","embed_dim=16",",","...","num_heads_channels=2",",","...","output_dim=4","...",")",">",">",">","x","=","torch.randn","(","4",",","1",",","64",",","64",")",">",">",">","x_pool","=","attn_pool","(","x",")",">",">",">","x_pool.shape","torch.Size","(","[","4",",","4","]",")"]
docstr: Computes the attention forward pass
  
  Arguments
  ---------
  x: torch.Tensor
      the tensor to be attended to
  
  Returns
  -------
  result: torch.Tensor
      the attention output
docstr_tok: ["Computes","the","attention","forward","pass","Arguments","--","--","--","--","-","x",":","torch.Tensor","the","tensor","to","be","attended","to","Returns","--","--","--","-","result",":","torch.Tensor","the","attention","output"]
code: def forward(self, x):
      """Computes the attention forward pass
  
      Arguments
      ---------
      x: torch.Tensor
          the tensor to be attended to
  
      Returns
      -------
      result: torch.Tensor
          the attention output
      """
      b, c, *_spatial = x.shape
      x = x.reshape(b, c, -1)  # NC(HW)
      x = torch.cat(
          [x.mean(dim=-1, keepdim=True), x], dim=-1
      )  # NC(HW+1)
      x = x + self.positional_embedding[None, :, :].to(
          x.dtype
      )  # NC(HW+1)
      x = self.qkv_proj(x)
      x = self.attention(x)
      x = self.c_proj(x)
      return x[:, :, 0]
  
imports: from abc import abstractmethod
  from speechbrain.utils.data_utils import pad_divisible
  from .autoencoders import NormalizingAutoencoder
  import math
  import torch
  import torch.nn
  import torch.nn.functional
label_desc: Use image node_id 2 for calling the AttentionPool2d obj's underlying member method code with example usage: obj.forward(x) and returns: x