code: def EncoderLayer(feature_depth,
                   feedforward_depth,
                   num_heads,
                   dropout,
                   mode):
    
    # The encoder block expects (activation, mask) as input and returns
    # the new activations only, we add the mask back to output next.
    encoder_block = layers.Serial(
        layers.Residual(  # Attention block here.
            layers.Parallel(layers.LayerNorm(), layers.Identity()),
            layers.MultiHeadedAttention(feature_depth, num_heads=num_heads,
                                        dropout=dropout, mode=mode),
            layers.Dropout(rate=dropout, mode=mode),
            shortcut=layers.FirstBranch()
        ),
        ResidualFeedForward(feature_depth, feedforward_depth, dropout, mode=mode)
    )
    # Now we add the mask back.
    return layers.Serial(
        layers.Reorder(output=((0, 1), 1)),  # (x, mask) --> ((x, mask), mask)
        layers.Parallel(encoder_block, layers.Identity())
    )
docs: Transformer encoder layer.
  
    The input to the encoder is a pair (embedded source, mask) where
    the mask is created from the original source to prevent attending
    to the padding part of the input.
  
    Args:
      feature_depth: int:  depth of embedding
      feedforward_depth: int: depth of feed-forward layer
      num_heads: int: number of attention heads
      dropout: float: dropout rate (how much to drop out)
      mode: str: 'train' or 'eval'
  
    Returns:
      the layer, returning a pair (actiavtions, mask).