class_docstr: Multi-headed attention layer.
  
  Arguments:
      units: Positive integer, output dim of hidden layer.
      num_heads: Positive integer, number of heads
          to repeat the same attention structure.
      attention_dropout_rate: Float, dropout rate inside attention for training.
      density: Approximate fraction of trainable weights (in
          `RandomlyConnectedDense` layers).
      unidirectional: Boolean, use a unidirectional or bidirectional encoder.
      use_key_relative_position: Boolean, if 'True' use key
          relative embeddings in attention.
      use_value_relative_position: Boolean, if 'True' use value
          relative embeddings in attention.
      max_relative_position: Positive integer, max position for relative embeddings.
      heads_share_relative_embedding: Boolean, if 'True'
          heads will share relative embeddings.
class_docstr_tok: ["Multi-headed","attention","layer",".","Arguments",":","units",":","Positive","integer",",","output","dim","of","hidden","layer",".","num_heads",":","Positive","integer",",","number","of","heads","to","repeat","the","same","attention","structure",".","attention_dropout_rate",":","Float",",","dropout","rate","inside","attention","for","training",".","density",":","Approximate","fraction","of","trainable","weights","(","in","`","RandomlyConnectedDense","`","layers",")",".","unidirectional",":","Boolean",",","use","a","unidirectional","or","bidirectional","encoder",".","use_key_relative_position",":","Boolean",",","if","'True","'","use","key","relative","embeddings","in","attention",".","use_value_relative_position",":","Boolean",",","if","'True","'","use","value","relative","embeddings","in","attention",".","max_relative_position",":","Positive","integer",",","max","position","for","relative","embeddings",".","heads_share_relative_embedding",":","Boolean",",","if","'True'","heads","will","share","relative","embeddings","."]
docstr: Apply attention mechanism to query_input and source_input.
  
  Arguments:
      query_input: A tensor with shape [batch_size, length, input_size].
      source_input: A tensor with shape [batch_size, length, input_size].
      pad_mask: Float tensor with shape broadcastable
          to (..., length, length). Defaults to None.
      training: A bool, whether in training mode or not.
  
  Returns:
      Attention layer output with shape [batch_size, length, units]
docstr_tok: ["Apply","attention","mechanism","to","query_input","and","source_input",".","Arguments",":","query_input",":","A","tensor","with","shape","[","batch_size",",","length",",","input_size","]",".","source_input",":","A","tensor","with","shape","[","batch_size",",","length",",","input_size","]",".","pad_mask",":","Float","tensor","with","shape","broadcastable","to","(","...",",","length",",","length",")",".","Defaults","to","None",".","training",":","A","bool",",","whether","in","training","mode","or","not",".","Returns",":","Attention","layer","output","with","shape","[","batch_size",",","length",",","units","]"]
code: def call(
      self,
      query_input: tf.Tensor,
      source_input: tf.Tensor,
      pad_mask: Optional[tf.Tensor] = None,
      training: Optional[Union[tf.Tensor, bool]] = None,
  ) -> Tuple[tf.Tensor, tf.Tensor]:
      """Apply attention mechanism to query_input and source_input.
  
      Arguments:
          query_input: A tensor with shape [batch_size, length, input_size].
          source_input: A tensor with shape [batch_size, length, input_size].
          pad_mask: Float tensor with shape broadcastable
              to (..., length, length). Defaults to None.
          training: A bool, whether in training mode or not.
  
      Returns:
          Attention layer output with shape [batch_size, length, units]
      """
      if training is None:
          training = K.learning_phase()
  
      query = self._query_dense_layer(
          query_input
      )  # (batch_size, length, units)
      key = self._key_dense_layer(
          source_input
      )  # (batch_size, length, units)
      value = self._value_dense_layer(
          source_input
      )  # (batch_size, length, units)
  
      query = self._split_heads(
          query
      )  # (batch_size, num_heads, length, depth)
      key = self._split_heads(
          key
      )  # (batch_size, num_heads, length, depth)
      value = self._split_heads(
          value
      )  # (batch_size, num_heads, length, depth)
  
      attention, attention_weights = self._scaled_dot_product_attention(
          query, key, value, pad_mask, training
      )
      # attention.shape == (batch_size, num_heads, length, depth)
      # attention_weights.shape == (batch_size, num_heads, length, length)
      attention = self._combine_heads(
          attention
      )  # (batch_size, length, units)
  
      output = self._output_dense_layer(
          attention
      )  # (batch_size, length, units)
  
      return output, attention_weights
  
imports: from typing import Optional, Text, Tuple, Union
  import numpy
  import tensorflow
  from keras.utils.control_flow_util import smart_cond
  from tensorflow.keras import backend
  import rasa.shared.utils.cli
  from rasa.utils.tensorflow.layers import RandomlyConnectedDense
label_desc: Use image node_id 14 for calling the MultiHeadAttention obj's underlying member method code with example usage: obj.call(query_input, source_input, pad_mask, training) and returns: output,  attention_weights