code: def transformer_encoder_attention_unit(x,
                                         hparams,
                                         encoder_self_attention_bias,
                                         attention_dropout_broadcast_dims,
                                         save_weights_to=None,
                                         make_image_summary=True):
    
  
    with tf.variable_scope("self_attention"):
      y = common_attention.multihead_attention(
          common_layers.layer_preprocess(x, hparams),
          None,
          encoder_self_attention_bias,
          hparams.attention_key_channels or hparams.hidden_size,
          hparams.attention_value_channels or hparams.hidden_size,
          hparams.hidden_size,
          hparams.num_heads,
          hparams.attention_dropout,
          attention_type=hparams.self_attention_type,
          save_weights_to=save_weights_to,
          max_relative_position=hparams.max_relative_position,
          make_image_summary=make_image_summary,
          dropout_broadcast_dims=attention_dropout_broadcast_dims,
          hard_attention_k=hparams.hard_attention_k)
      x = common_layers.layer_postprocess(x, y, hparams)
    return x
docs: Applies multihead attention function which is parametrised for encoding.
  
    Args:
      x: input
      hparams: model hyper-parameters
      encoder_self_attention_bias: a bias tensor for use in encoder self-attention
      attention_dropout_broadcast_dims: Fpr noise broadcasting in the dropout
        layers to save memory during training
      save_weights_to: an optional dictionary to capture attention weights for
        visualization; the weights tensor will be appended there under a string
        key created from the variable scope (including name).
      make_image_summary: Whether to make an attention image summary.
  
    Returns:
      the output tensor