def feed_forward_gaussian(
    config, action_space, observations, unused_length, state=None):
  """Independent feed forward networks for policy and value.

  The policy network outputs the mean action and the standard deviation is
  learned as independent parameter vector.

  Args:
    config: Configuration object.
    action_space: Action space of the environment.
    observations: Sequences of observations.
    unused_length: Batch of sequence lengths.
    state: Unused batch of initial states.

  Raises:
    ValueError: Unexpected action space.

  Returns:
    Attribute dictionary containing the policy, value, and unused state.
  """
  if not isinstance(action_space, gym.spaces.Box):
    raise ValueError('Network expects continuous actions.')
  if not len(action_space.shape) == 1:
    raise ValueError('Network only supports 1D action vectors.')
  action_size = action_space.shape[0]
  init_output_weights = tf.contrib.layers.variance_scaling_initializer(
      factor=config.init_output_factor)
  before_softplus_std_initializer = tf.constant_initializer(
      np.log(np.exp(config.init_std) - 1))
  flat_observations = tf.reshape(observations, [
      tf.shape(observations)[0], tf.shape(observations)[1],
      functools.reduce(operator.mul, observations.shape.as_list()[2:], 1)])
  with tf.variable_scope('policy'):
    x = flat_observations
    for size in config.policy_layers:
      x = tf.contrib.layers.fully_connected(x, size, tf.nn.relu)
    mean = tf.contrib.layers.fully_connected(
        x, action_size, tf.tanh,
        weights_initializer=init_output_weights)
    std = tf.nn.softplus(tf.get_variable(
        'before_softplus_std', mean.shape[2:], tf.float32,
        before_softplus_std_initializer))
    std = tf.tile(
        std[None, None],
        [tf.shape(mean)[0], tf.shape(mean)[1]] + [1] * (mean.shape.ndims - 2))
  with tf.variable_scope('value'):
    x = flat_observations
    for size in config.value_layers:
      x = tf.contrib.layers.fully_connected(x, size, tf.nn.relu)
    value = tf.contrib.layers.fully_connected(x, 1, None)[..., 0]
  mean = tf.check_numerics(mean, 'mean')
  std = tf.check_numerics(std, 'std')
  value = tf.check_numerics(value, 'value')
  policy = CustomKLDiagNormal(mean, std)
  return agents.tools.AttrDict(policy=policy, value=value, state=state)
Independent feed forward networks for policy and value.

  The policy network outputs the mean action and the standard deviation is
  learned as independent parameter vector.

  Args:
    config: Configuration object.
    action_space: Action space of the environment.
    observations: Sequences of observations.
    unused_length: Batch of sequence lengths.
    state: Unused batch of initial states.

  Raises:
    ValueError: Unexpected action space.

  Returns:
    Attribute dictionary containing the policy, value, and unused state.