docs: def fc(inputs,
         num_units_out,
         activation=tf.nn.relu,
         stddev=0.01,
         bias=0.0,
         weight_decay=0,
         batch_norm_params=None,
         is_training=True,
         trainable=True,
         restore=True,
         scope=None,
         reuse=None):
    """Adds a fully connected layer followed by an optional batch_norm layer.
  
    FC creates a variable called 'weights', representing the fully connected
    weight matrix, that is multiplied by the input. If `batch_norm` is None, a
    second variable called 'biases' is added to the result of the initial
    vector-matrix multiplication.
  
    Args:
      inputs: a [B x N] tensor where B is the batch size and N is the number of
              input units in the layer.
      num_units_out: the number of output units in the layer.
      activation: activation function.
      stddev: the standard deviation for the weights.
      bias: the initial value of the biases.
      weight_decay: the weight decay.
      batch_norm_params: parameters for the batch_norm. If is None don't use it.
      is_training: whether or not the model is in training mode.
      trainable: whether or not the variables should be trainable or not.
      restore: whether or not the variables should be marked for restore.
      scope: Optional scope for variable_scope.
      reuse: whether or not the layer and its variables should be reused. To be
        able to reuse the layer scope must be given.
  
    Returns:
       the tensor variable representing the result of the series of operations.
    """
    with tf.variable_scope(scope, 'FC', [inputs], reuse=reuse):
      num_units_in = inputs.get_shape()[1]
      weights_shape = [num_units_in, num_units_out]
      weights_initializer = tf.truncated_normal_initializer(stddev=stddev)
      l2_regularizer = None
      if weight_decay and weight_decay > 0:
        l2_regularizer = losses.l2_regularizer(weight_decay)
      weights = variables.variable('weights',
                                   shape=weights_shape,
                                   initializer=weights_initializer,
                                   regularizer=l2_regularizer,
                                   trainable=trainable,
                                   restore=restore)
      if batch_norm_params is not None:
        outputs = tf.matmul(inputs, weights)
        with scopes.arg_scope([batch_norm], is_training=is_training,
                              trainable=trainable, restore=restore):
          outputs = batch_norm(outputs, **batch_norm_params)
      else:
        bias_shape = [num_units_out,]
        bias_initializer = tf.constant_initializer(bias)
        biases = variables.variable('biases',
                                    shape=bias_shape,
                                    initializer=bias_initializer,
                                    trainable=trainable,
                                    restore=restore)
        outputs = tf.nn.xw_plus_b(inputs, weights, biases)
      if activation:
        outputs = activation(outputs)
      return outputs