class_docstr: An attention block that allows spatial positions to attend to each other.
  
  Originally ported from here, but adapted to the N-d case.
  https://github.com/hojonathanho/diffusion/blob/1e0dceb3b3495bbe19116a5e1b3596cd0706c543/diffusion_tf/models/unet.py#L66.
class_docstr_tok: ["An","attention","block","that","allows","spatial","positions","to","attend","to","each","other",".","Originally","ported","from","here",",","but","adapted","to","the","N-d","case",".","https",":","\/\/github.com\/hojonathanho\/diffusion\/blob\/1e0dceb3b3495bbe19116a5e1b3596cd0706c543\/diffusion_tf\/models\/unet.py","#","L66","."]
code: def __init__(
      self,
      channels,
      num_heads=1,
      num_head_channels=None,
      num_groups=32,
      encoder_channels=None,
      overwrite_qkv=False,
      overwrite_linear=False,
      rescale_output_factor=1.0,
      eps=1e-5,
  ):
      super().__init__()
      self.channels = channels
      if num_head_channels is None:
          self.num_heads = num_heads
      else:
          assert (
              channels % num_head_channels == 0
          ), f"q,k,v channels {channels} is not divisible by num_head_channels {num_head_channels}"
          self.num_heads = channels // num_head_channels
  
      self.norm = nn.GroupNorm(
          num_channels=channels, num_groups=num_groups, epsilon=eps
      )
      self.qkv = nn.Conv1D(channels, channels * 3, 1)
      self.n_heads = self.num_heads
      self.rescale_output_factor = rescale_output_factor
  
      if encoder_channels is not None:
          self.encoder_kv = nn.Conv1D(encoder_channels, channels * 2, 1)
  
      self.proj = nn.Conv1D(channels, channels, 1)
  
      self.overwrite_qkv = overwrite_qkv
      self.overwrite_linear = overwrite_linear
  
      if overwrite_qkv:
          in_channels = channels
          self.norm = nn.GroupNorm(
              num_channels=channels, num_groups=num_groups, epsilon=1e-6
          )
          self.q = nn.Conv2D(
              in_channels,
              in_channels,
              kernel_size=1,
              stride=1,
              padding=0,
          )
          self.k = nn.Conv2D(
              in_channels,
              in_channels,
              kernel_size=1,
              stride=1,
              padding=0,
          )
          self.v = nn.Conv2D(
              in_channels,
              in_channels,
              kernel_size=1,
              stride=1,
              padding=0,
          )
          self.proj_out = nn.Conv2D(
              in_channels,
              in_channels,
              kernel_size=1,
              stride=1,
              padding=0,
          )
      elif self.overwrite_linear:
          num_groups = min(channels // 4, 32)
          self.norm = nn.GroupNorm(
              num_channels=channels, num_groups=num_groups, epsilon=1e-6
          )
          self.NIN_0 = NIN(channels, channels)
          self.NIN_1 = NIN(channels, channels)
          self.NIN_2 = NIN(channels, channels)
          self.NIN_3 = NIN(channels, channels)
  
          self.GroupNorm_0 = nn.GroupNorm(
              num_groups=num_groups, num_channels=channels, epsilon=1e-6
          )
      else:
          self.proj_out = nn.Conv1D(channels, channels, 1)
          self.set_weights(self)
  
      self.is_overwritten = False
  
imports: import math
  from inspect import isfunction
  import numpy
  import paddle
  import paddle.nn
  import paddle.nn.functional
label_desc: Use image node_id 1 to create a new AttentionBlock object from inherited base classes: nn with example: obj = AttentionBlock(channels, num_heads, num_head_channels, num_groups, encoder_channels, overwrite_qkv, overwrite_linear, rescale_output_factor, eps)