def gru_cell(input_layer,
             state,
             num_units,
             bias=tf.zeros_initializer(),
             weights=None,
             phase=prettytensor.Phase.train,
             parameter_modifier=parameters.identity):
  """Gated recurrent unit memory cell (GRU).

  Args:
    input_layer: The input layer.
    state: The current state of the network. For GRUs, this is a list with
      one element (tensor) of shape [batch, num_units].
    num_units: How big is the hidden state.
    bias: An initializer for the bias or a Tensor. No bias if set to None.
    weights: An initializer for weights or a Tensor.
    phase: The phase of graph construction.  See `pt.Phase`.
    parameter_modifier: A function to modify parameters that is applied after
      creation and before use.
  Returns:
    A RecurrentResult.
  """
  # As a compound op, it needs to respect whether or not this is a sequential
  # builder.
  if input_layer.is_sequential_builder():
    layer = input_layer.as_layer()
  else:
    layer = input_layer
  # We start with bias of 1.0 to not reset and not udpate.
  # NB We compute activation_input and activation_state in two different ops,
  # instead of concatenating them, followed by one matrix multiplication. The
  # reason is that input has size [batch_size x input_size], while state has
  # [ ? x state_size ], where the first dimension is 1 initially and will be
  # batch_size only after the first RNN computation. We thus cannot concatenate
  # input and state, and instead add the results of two fully connected ops,
  # which works thanks to broadcasting, independent of state's batch size.
  state = state[0]
  state_pt = prettytensor.wrap(state, layer.bookkeeper)

  activation_input = layer.fully_connected(
      2 * num_units,
      bias=None if bias is None else tf.constant_initializer(1.0),
      activation_fn=None,
      weights=weights,
      phase=phase,
      parameter_modifier=parameter_modifier)
  activation_state = state_pt.fully_connected(
      2 * num_units,
      bias=None,
      activation_fn=None,
      weights=weights,
      phase=phase,
      parameter_modifier=parameter_modifier)

  # adds batch_size x (2 * num_units) + ? x (2 * num_inputs)
  activation = activation_input + activation_state
  activation = activation.sigmoid()

  split = activation.split(1, 2)
  r = split[0]
  u = split[1]

  c = layer.concat(1, [r * state]).fully_connected(
      num_units,
      bias=bias,
      activation_fn=None,
      weights=weights,
      phase=phase,
      parameter_modifier=parameter_modifier).apply(tf.tanh)
  new_h = u * state + (1 - u) * c
  if input_layer.is_sequential_builder():
    new_h = input_layer.set_head(input_layer)
  return RecurrentResult(new_h, [new_h])
Gated recurrent unit memory cell (GRU).

  Args:
    input_layer: The input layer.
    state: The current state of the network. For GRUs, this is a list with
      one element (tensor) of shape [batch, num_units].
    num_units: How big is the hidden state.
    bias: An initializer for the bias or a Tensor. No bias if set to None.
    weights: An initializer for weights or a Tensor.
    phase: The phase of graph construction.  See `pt.Phase`.
    parameter_modifier: A function to modify parameters that is applied after
      creation and before use.
  Returns:
    A RecurrentResult.