def ffnn(input_emb, hidden_sizes, dropout_ratio, mode):
  """A simple feed-forward neural network.

  Dropout is applied before each linear layer. Non-linearities are not applied
  to the final hidden layer.

  Args:
    input_emb: tensor<float> [..., embedding_size]
    hidden_sizes: list<int> [hidden_size_1, hidden_size_2, ...]
    dropout_ratio: The probability of dropping out each unit in the activation.
        This can be None, and is only applied during training.
    mode: One of the keys from tf.estimator.ModeKeys.

  Returns:
    output_emb: A Tensor with the same shape as `input_emb`, except for the last
        dimension which will have size `hidden_sizes[-1]` instead.
  """
  for i, h in enumerate(hidden_sizes):
    with tf.variable_scope("ffnn_{}".format(i)):
      if mode == tf_estimator.ModeKeys.TRAIN and dropout_ratio is not None:
        input_emb = tf.nn.dropout(input_emb, 1.0 - dropout_ratio)
      input_emb = tf.layers.dense(input_emb, h)
      if i < len(hidden_sizes) - 1:
        input_emb = tf.nn.relu(input_emb)
  return input_emb
A simple feed-forward neural network.

  Dropout is applied before each linear layer. Non-linearities are not applied
  to the final hidden layer.

  Args:
    input_emb: tensor<float> [..., embedding_size]
    hidden_sizes: list<int> [hidden_size_1, hidden_size_2, ...]
    dropout_ratio: The probability of dropping out each unit in the activation.
        This can be None, and is only applied during training.
    mode: One of the keys from tf.estimator.ModeKeys.

  Returns:
    output_emb: A Tensor with the same shape as `input_emb`, except for the last
        dimension which will have size `hidden_sizes[-1]` instead.
  
language/common/layers/common_layers.py