Exposes all the layers of the model returned by get_layer_names.
    :param x: A symbolic representation of the network input
    :return: A dictionary mapping layer names to the symbolic
             representation of their output.

def fprop(self, x):
    """
    Exposes all the layers of the model returned by get_layer_names.
    :param x: A symbolic representation of the network input
    :return: A dictionary mapping layer names to the symbolic
             representation of their output.
    """

    if self.keras_model is None:
      # Get the input layer
      new_input = self.model.get_input_at(0)

      # Make a new model that returns each of the layers as output
      abstract_layers = self._get_abstract_layer_name()
      if abstract_layers:
        warnings.warn(
            "Abstract layer detected, picking last ouput node as default."
            "This could happen due to using of stacked model.")

      layer_outputs = []
      # For those abstract model layers, return their last output node as
      # default.
      for x_layer in self.model.layers:
        if x_layer.name not in abstract_layers:
          layer_outputs.append(x_layer.output)
        else:
          layer_outputs.append(x_layer.get_output_at(-1))

      self.keras_model = KerasModel(new_input, layer_outputs)

    # and get the outputs for that model on the input x
    outputs = self.keras_model(x)

    # Keras only returns a list for outputs of length >= 1, if the model
    # is only one layer, wrap a list
    if len(self.model.layers) == 1:
      outputs = [outputs]

    # compute the dict to return
    fprop_dict = dict(zip(self.get_layer_names(), outputs))

    return fprop_dict