def layer_postprocess(layer_input, layer_output, model_params, perform_dropout):
  """Applies dropout, residual connection, and layer normalization.

  Based on layer postprocessing from "Attention Is All You Need":
  https://arxiv.org/abs/1706.03762

  Args:
    layer_input: <float>[batch_size, length, emb_size]
    layer_output: <float>[batch_size, length, emb_size]
    model_params: ModelParameters proto.
    perform_dropout: If True, perform dropout. Should be True for training.

  Returns:
    <float>[batch_size, length, emb_size]
  """
  x = layer_output
  # Apply dropout if training.
  if perform_dropout:
    x = tf.nn.dropout(
        x, keep_prob=(1.0 - model_params.training_options.layer_dropout_rate))
  # Residual connection.
  x = x + layer_input
  # Layer normalization.
  x = apply_norm(x)
  return x
Applies dropout, residual connection, and layer normalization.

  Based on layer postprocessing from "Attention Is All You Need":
  https://arxiv.org/abs/1706.03762

  Args:
    layer_input: <float>[batch_size, length, emb_size]
    layer_output: <float>[batch_size, length, emb_size]
    model_params: ModelParameters proto.
    perform_dropout: If True, perform dropout. Should be True for training.

  Returns:
    <float>[batch_size, length, emb_size]
  
language/xsp/model/common_layers.py