コード例 #1
0
    def add(self, layer):
        """
			Adds a layer following all previous layers. 

			Arguments:
				layer:	A layer that supports call, call_inv and log_det.  

			Example: 
					
				> import invtf
				> import tensorflow.keras as keras

				> # Model
				> g = invtf.Generator()
				> g.add(invtf.dequantize.UniformDequantize(input_shape=input_shape)) 
				> g.add(invtf.layers.Normalize()) 
				> g.add(invtf.layers.Conv3DCirc()) 


			Comments: 

				This code is essentially that of keras.Sequential [1]. As explained 
				above the class inherits from Model instead of Sequential to allow
				Multi-Scale architecture with multiple outputs. To simultaneously support
				the Sequential API we have a modified version of the Sequential 'add(..)'
				function. 
		
				The main modification is that the function below allow multiple outputs 
				of MultiScale layers which keras.Sequential does not. 


			TODO:
				(1) Make InvLayer class everyone inherits from with O(1) mem backprop. 

		"""

        if len(self._layers) == 0:
            if not hasattr(layer, "_batch_input_shape"):
                raise Exception(
                    "The first layer should include input dimension, e.g. UniformDequantize(input_shape=X.shape[1:]). "
                )

        if isinstance(layer, keras.layers.InputLayer):
            raise Exception(
                "Don't add an InputLayer, this is the responsibility of the Generator class. "
            )

        if not isinstance(layer, keras.layers.Layer):
            raise TypeError(
                "The added layer must be an instance of class Layer. Found: " +
                str(layer))

        self.built = False
        set_inputs = False

        from tensorflow.python.keras.engine import input_layer
        from tensorflow.python.keras.engine import training_utils
        from tensorflow.python.keras.utils import layer_utils
        from tensorflow.python.util import nest
        from tensorflow.python.util import tf_inspect

        # If list is empty.
        if not self._layers:
            batch_shape, dtype = training_utils.get_input_shape_and_dtype(
                layer)
            if batch_shape:
                # Instantiate an input layer.
                x = input_layer.Input(batch_shape=batch_shape,
                                      dtype=dtype,
                                      name=layer.name + '_input')
                # This will build the current layer
                # and create the node connecting the current layer
                # to the input layer we just created.
                layer(x)
                set_inputs = True

            if set_inputs:
                # If an input layer (placeholder) is available.
                if len(nest.flatten(
                        layer._inbound_nodes[-1].output_tensors)) != 1:
                    raise ValueError(
                        'All layers of Invertible Generator (besides MultiScale) '
                        'should have a single output tensor. ')
                self.outputs = [
                    nest.flatten(layer._inbound_nodes[-1].output_tensors)[0]
                ]
                self.inputs = layer_utils.get_source_inputs(self.outputs[0])

        elif self.outputs:
            """# If the model is being built continuously on top of an input layer:
			# refresh its output.
			output_tensor = layer(self.outputs[0])
	
			# MAIN NEW LINE
			if isinstance(layer, invtf.layers.MultiScale): output_tensor = output_tensor[0]

			if len(nest.flatten(output_tensor)) != 1:
				raise TypeError('All layers of Invertible Gnerator (Besides MultiScale) '
												'should have a single output tensor. ')
			self.outputs = [output_tensor]"""

            # If the model is being built continuously on top of an input layer:
            # refresh its output.
            output_tensor = layer(self.outputs[0])

            # MAIN MODIFICATION.
            Zs = []
            if isinstance(layer, invtf.layers.MultiScale):
                Zs = [output_tensor[1]]
                output_tensor = output_tensor[0]

            if len(nest.flatten(output_tensor)) != 1:
                raise TypeError(
                    'All layers of Invertible Generator (Besides MultiScale) '
                    'should have a single output tensor. ')
            self.outputs = [output_tensor] + self.outputs[1:] + Zs

        if self.outputs:
            # True if set_inputs or self._is_graph_network or if adding a layer
            # to an already built deferred seq model.
            self.built = True

        if set_inputs or self._is_graph_network:
            self._init_graph_network(self.inputs, self.outputs, name=self.name)
        else:
            self._layers.append(layer)
        if self._layers:
            self._track_layers(self._layers)

        self._layer_call_argspecs[layer] = tf_inspect.getfullargspec(
            layer.call)
コード例 #2
0
    def add(self, layer):
        """Adds a layer instance on top of the layer stack.

    Arguments:
        layer: layer instance.

    Raises:
        TypeError: If `layer` is not a layer instance.
        ValueError: In case the `layer` argument does not
            know its input shape.
        ValueError: In case the `layer` argument has
            multiple output tensors, or is already connected
            somewhere else (forbidden in `Sequential` models).
    """
        # If we are passed a Keras tensor created by keras.Input(), we can extract
        # the input layer from its keras history and use that without any loss of
        # generality.
        if hasattr(layer, '_keras_history'):
            origin_layer = layer._keras_history[0]
            if isinstance(origin_layer, input_layer.InputLayer):
                layer = origin_layer

        if not isinstance(layer, base_layer.Layer):
            raise TypeError('The added layer must be '
                            'an instance of class Layer. '
                            'Found: ' + str(layer))

        tf_utils.assert_no_legacy_layers([layer])

        self.built = False
        set_inputs = False
        if not self._layers:
            if isinstance(layer, input_layer.InputLayer):
                # Corner case where the user passes an InputLayer layer via `add`.
                assert len(
                    nest.flatten(layer._inbound_nodes[-1].output_tensors)) == 1
                set_inputs = True
            else:
                batch_shape, dtype = training_utils.get_input_shape_and_dtype(
                    layer)
                if batch_shape:
                    # Instantiate an input layer.
                    x = input_layer.Input(batch_shape=batch_shape,
                                          dtype=dtype,
                                          name=layer.name + '_input')
                    # This will build the current layer
                    # and create the node connecting the current layer
                    # to the input layer we just created.
                    layer(x)
                    set_inputs = True

            if set_inputs:
                # If an input layer (placeholder) is available.
                if len(nest.flatten(
                        layer._inbound_nodes[-1].output_tensors)) != 1:
                    raise ValueError('All layers in a Sequential model '
                                     'should have a single output tensor. '
                                     'For multi-output layers, '
                                     'use the functional API.')
                self.outputs = [
                    nest.flatten(layer._inbound_nodes[-1].output_tensors)[0]
                ]
                self.inputs = layer_utils.get_source_inputs(self.outputs[0])

        elif self.outputs:
            # If the model is being built continuously on top of an input layer:
            # refresh its output.
            output_tensor = layer(self.outputs[0])
            if len(nest.flatten(output_tensor)) != 1:
                raise TypeError('All layers in a Sequential model '
                                'should have a single output tensor. '
                                'For multi-output layers, '
                                'use the functional API.')
            self.outputs = [output_tensor]
        if set_inputs or self._is_graph_network:
            self._init_graph_network(self.inputs, self.outputs, name=self.name)
            self.built = True
        else:
            self._layers.append(layer)
        if self._layers:
            self._track_layers(self._layers)

        self._layer_call_argspecs[layer] = tf_inspect.getfullargspec(
            layer.call)
コード例 #3
0
ファイル: sequential.py プロジェクト: mrax714/nearme
  def add(self, layer):
    """Adds a layer instance on top of the layer stack.

    Args:
        layer: layer instance.

    Raises:
        TypeError: If `layer` is not a layer instance.
        ValueError: In case the `layer` argument does not
            know its input shape.
        ValueError: In case the `layer` argument has
            multiple output tensors, or is already connected
            somewhere else (forbidden in `Sequential` models).
    """
    # If we are passed a Keras tensor created by keras.Input(), we can extract
    # the input layer from its keras history and use that without any loss of
    # generality.
    if hasattr(layer, '_keras_history'):
      origin_layer = layer._keras_history[0]
      if isinstance(origin_layer, input_layer.InputLayer):
        layer = origin_layer
        logging.warning(
            'Please add `keras.layers.InputLayer` instead of `keras.Input` to '
            'Sequential model. `keras.Input` is intended to be used by '
            'Functional model.')

    if isinstance(layer, module.Module):
      if not isinstance(layer, base_layer.Layer):
        layer = functional.ModuleWrapper(layer)
    else:
      raise TypeError('The added layer must be '
                      'an instance of class Layer. '
                      'Found: ' + str(layer))

    tf_utils.assert_no_legacy_layers([layer])
    if not self._is_layer_name_unique(layer):
      raise ValueError('All layers added to a Sequential model '
                       'should have unique names. Name "%s" is already the name'
                       ' of a layer in this model. Update the `name` argument '
                       'to pass a unique name.' % (layer.name,))

    self.built = False
    set_inputs = False
    self._maybe_create_attribute('_self_tracked_trackables', [])
    if not self._self_tracked_trackables:
      if isinstance(layer, input_layer.InputLayer):
        # Case where the user passes an Input or InputLayer layer via `add`.
        set_inputs = True
      else:
        batch_shape, dtype = training_utils.get_input_shape_and_dtype(layer)
        if batch_shape:
          # Instantiate an input layer.
          x = input_layer.Input(
              batch_shape=batch_shape, dtype=dtype, name=layer.name + '_input')
          # This will build the current layer
          # and create the node connecting the current layer
          # to the input layer we just created.
          layer(x)
          set_inputs = True

      if set_inputs:
        outputs = nest.flatten(layer._inbound_nodes[-1].outputs)
        if len(outputs) != 1:
          raise ValueError(SINGLE_LAYER_OUTPUT_ERROR_MSG)
        self.outputs = outputs
        self.inputs = layer_utils.get_source_inputs(self.outputs[0])
        self.built = True
        self._has_explicit_input_shape = True

    elif self.outputs:
      # If the model is being built continuously on top of an input layer:
      # refresh its output.
      output_tensor = layer(self.outputs[0])
      if len(nest.flatten(output_tensor)) != 1:
        raise ValueError(SINGLE_LAYER_OUTPUT_ERROR_MSG)
      self.outputs = [output_tensor]
      self.built = True

    if set_inputs or self._graph_initialized:
      self._init_graph_network(self.inputs, self.outputs)
      self._graph_initialized = True
    else:
      self._self_tracked_trackables.append(layer)
      self._handle_deferred_layer_dependencies([layer])

    self._layer_call_argspecs[layer] = tf_inspect.getfullargspec(layer.call)
コード例 #4
0
    def add(self, layer):
        """Adds a layer instance on top of the layer stack.

    Arguments:
        layer: layer instance.

    Raises:
        TypeError: If `layer` is not a layer instance.
        ValueError: In case the `layer` argument does not
            know its input shape.
        ValueError: In case the `layer` argument has
            multiple output tensors, or is already connected
            somewhere else (forbidden in `Sequential` models).
    """
        # If we are passed a Keras tensor created by keras.Input(), we can extract
        # the input layer from its keras history and use that without any loss of
        # generality.
        if hasattr(layer, '_keras_history'):
            origin_layer = layer._keras_history[0]
            if isinstance(origin_layer, input_layer.InputLayer):
                layer = origin_layer

        if not isinstance(layer, base_layer.Layer):
            raise TypeError('The added layer must be '
                            'an instance of class Layer. '
                            'Found: ' + str(layer))

        tf_utils.assert_no_legacy_layers([layer])

        # This allows the added layer to broadcast mutations to the current
        # layer, which is necessary to ensure cache correctness.
        layer._attribute_sentinel.add_parent(self._attribute_sentinel)

        self.built = False
        set_inputs = False
        if not self._layers:
            if isinstance(layer, input_layer.InputLayer):
                # Corner case where the user passes an InputLayer layer via `add`.
                assert len(
                    nest.flatten(layer._inbound_nodes[-1].output_tensors)) == 1
                set_inputs = True
            else:
                batch_shape, dtype = training_utils.get_input_shape_and_dtype(
                    layer)
                if batch_shape:
                    # Instantiate an input layer.
                    x = input_layer.Input(batch_shape=batch_shape,
                                          dtype=dtype,
                                          name=layer.name + '_input')
                    # This will build the current layer
                    # and create the node connecting the current layer
                    # to the input layer we just created.
                    layer(x)
                    set_inputs = True

            if set_inputs:
                # If an input layer (placeholder) is available.
                if len(nest.flatten(
                        layer._inbound_nodes[-1].output_tensors)) != 1:
                    raise ValueError(SINGLE_LAYER_OUTPUT_ERROR_MSG)
                self.outputs = [
                    nest.flatten(layer._inbound_nodes[-1].output_tensors)[0]
                ]
                self.inputs = layer_utils.get_source_inputs(self.outputs[0])

        elif self.outputs:
            # If the model is being built continuously on top of an input layer:
            # refresh its output.
            output_tensor = layer(self.outputs[0])
            if len(nest.flatten(output_tensor)) != 1:
                raise ValueError(SINGLE_LAYER_OUTPUT_ERROR_MSG)
            self.outputs = [output_tensor]

        if self.outputs:
            # True if set_inputs or self._is_graph_network or if adding a layer
            # to an already built deferred seq model.
            self.built = True

        if set_inputs or self._is_graph_network:
            self._init_graph_network(self.inputs, self.outputs, name=self.name)
        else:
            self._layers.append(layer)
            self._handle_deferred_layer_dependencies([layer])

        self._layer_call_argspecs[layer] = tf_inspect.getfullargspec(
            layer.call)
        # Different Model types add to `._layers` in different ways, so for safety
        # we do a cache invalidation to make sure the changes are reflected.
        self._attribute_sentinel.invalidate_all()
コード例 #5
0
ファイル: sequential.py プロジェクト: adit-chandra/tensorflow
  def add(self, layer):
    """Adds a layer instance on top of the layer stack.

    Arguments:
        layer: layer instance.

    Raises:
        TypeError: If `layer` is not a layer instance.
        ValueError: In case the `layer` argument does not
            know its input shape.
        ValueError: In case the `layer` argument has
            multiple output tensors, or is already connected
            somewhere else (forbidden in `Sequential` models).
    """
    # If we are passed a Keras tensor created by keras.Input(), we can extract
    # the input layer from its keras history and use that without any loss of
    # generality.
    if hasattr(layer, '_keras_history'):
      origin_layer = layer._keras_history[0]
      if isinstance(origin_layer, input_layer.InputLayer):
        layer = origin_layer

    if not isinstance(layer, base_layer.Layer):
      raise TypeError('The added layer must be '
                      'an instance of class Layer. '
                      'Found: ' + str(layer))
    self.built = False
    set_inputs = False
    if not self._layers:
      if isinstance(layer, input_layer.InputLayer):
        # Corner case where the user passes an InputLayer layer via `add`.
        assert len(nest.flatten(layer._inbound_nodes[-1].output_tensors)) == 1
        set_inputs = True
      else:
        batch_shape, dtype = training_utils.get_input_shape_and_dtype(layer)
        if batch_shape:
          # Instantiate an input layer.
          x = input_layer.Input(
              batch_shape=batch_shape, dtype=dtype, name=layer.name + '_input')
          # This will build the current layer
          # and create the node connecting the current layer
          # to the input layer we just created.
          layer(x)
          set_inputs = True

      if set_inputs:
        # If an input layer (placeholder) is available.
        if len(nest.flatten(layer._inbound_nodes[-1].output_tensors)) != 1:
          raise ValueError('All layers in a Sequential model '
                           'should have a single output tensor. '
                           'For multi-output layers, '
                           'use the functional API.')
        self.outputs = [
            nest.flatten(layer._inbound_nodes[-1].output_tensors)[0]
        ]
        self.inputs = layer_utils.get_source_inputs(self.outputs[0])

    elif self.outputs:
      # If the model is being built continuously on top of an input layer:
      # refresh its output.
      output_tensor = layer(self.outputs[0])
      if isinstance(output_tensor, list):
        raise TypeError('All layers in a Sequential model '
                        'should have a single output tensor. '
                        'For multi-output layers, '
                        'use the functional API.')
      self.outputs = [output_tensor]
    if set_inputs or self._is_graph_network:
      self._init_graph_network(self.inputs, self.outputs, name=self.name)
      self.built = True
    else:
      self._layers.append(layer)
    if self._layers:
      self._track_layers(self._layers)

    self._layer_call_argspecs[layer] = tf_inspect.getfullargspec(layer.call)
コード例 #6
0
  def add(self, layer):
    """Adds a layer instance on top of the layer stack.

    Arguments:
        layer: layer instance.

    Raises:
        TypeError: If `layer` is not a layer instance.
        ValueError: In case the `layer` argument does not
            know its input shape.
        ValueError: In case the `layer` argument has
            multiple output tensors, or is already connected
            somewhere else (forbidden in `Sequential` models).
    """
    if not isinstance(layer, base_layer.Layer):
      raise TypeError('The added layer must be '
                      'an instance of class Layer. '
                      'Found: ' + str(layer))
    self.built = False
    set_inputs = False
    if not self._layers:
      if isinstance(layer, InputLayer):
        # Corner case where the user passes an InputLayer layer via `add`.
        assert len(layer._inbound_nodes[-1].output_tensors) == 1
        set_inputs = True
      else:
        batch_shape, dtype = training_utils.get_input_shape_and_dtype(layer)
        if batch_shape:
          # Instantiate an input layer.
          x = Input(
              batch_shape=batch_shape,
              dtype=dtype,
              name=layer.name + '_input')
          # This will build the current layer
          # and create the node connecting the current layer
          # to the input layer we just created.
          layer(x)
          set_inputs = True

      if set_inputs:
        # If an input layer (placeholder) is available.
        if len(layer._inbound_nodes[-1].output_tensors) != 1:
          raise ValueError('All layers in a Sequential model '
                           'should have a single output tensor. '
                           'For multi-output layers, '
                           'use the functional API.')
        self.outputs = [layer._inbound_nodes[-1].output_tensors[0]]
        self.inputs = layer_utils.get_source_inputs(self.outputs[0])

    elif self.outputs:
      # If the model is being built continuously on top of an input layer:
      # refresh its output.
      output_tensor = layer(self.outputs[0])
      if isinstance(output_tensor, list):
        raise TypeError('All layers in a Sequential model '
                        'should have a single output tensor. '
                        'For multi-output layers, '
                        'use the functional API.')
      self.outputs = [output_tensor]
    if set_inputs or self._is_graph_network:
      self._init_graph_network(self.inputs, self.outputs, name=self.name)
      self.built = True
    else:
      self._layers.append(layer)
    if self._layers:
      self._track_layers(self._layers)
コード例 #7
0
    def add(self, layer):
        from tensorflow.python.keras.utils import tf_utils
        from tensorflow.python.keras.engine import training_utils
        from tensorflow.python.util import nest
        from tensorflow.python.keras.utils import layer_utils
        from tensorflow.python.util import tf_inspect

        # If we are passed a Keras tensor created by keras.Input(), we can extract
        # the input layer from its keras history and use that without any loss of
        # generality.
        if hasattr(layer, '_keras_history'):
            origin_layer = layer._keras_history[0]
            if isinstance(origin_layer, keras.layers.InputLayer):
                layer = origin_layer

        if not isinstance(layer, keras.layers.Layer):
            raise TypeError('The added layer must be '
                            'an instance of class Layer. '
                            'Found: ' + str(layer))

        tf_utils.assert_no_legacy_layers([layer])

        self.built = False
        set_inputs = False
        if not self._layers:
            if isinstance(layer, keras.layers.InputLayer):
                # Corner case where the user passes an InputLayer layer via `add`.
                assert len(
                    nest.flatten(layer._inbound_nodes[-1].output_tensors)) == 1
                set_inputs = True
            else:
                batch_shape, dtype = training_utils.get_input_shape_and_dtype(
                    layer)
                if batch_shape:
                    # Instantiate an input layer.
                    x = keras.layers.Input(batch_shape=batch_shape,
                                           dtype=dtype,
                                           name=layer.name + '_input')
                    # This will build the current layer
                    # and create the node connecting the current layer
                    # to the input layer we just created.
                    layer(x)
                    set_inputs = True

            if set_inputs:
                # If an input layer (placeholder) is available.
                if len(nest.flatten(
                        layer._inbound_nodes[-1].output_tensors)) != 1:
                    raise ValueError('All layers in a Sequential model '
                                     'should have a single output tensor. '
                                     'For multi-output layers, '
                                     'use the functional API.')
                self.outputs = [
                    nest.flatten(layer._inbound_nodes[-1].output_tensors)[0]
                ]
                self.inputs = layer_utils.get_source_inputs(self.outputs[0])

        elif self.outputs:
            # If the model is being built continuously on top of an input layer:
            # refresh its output.
            output_tensor = layer(self.outputs[0])
            if len(nest.flatten(output_tensor)) != 1 and not isinstance(
                    layer, MultiScale):
                raise TypeError('All layers in a Sequential model '
                                'should have a single output tensor. '
                                'For multi-output layers, '
                                'use the functional API.')
            self.outputs = [output_tensor]

        if self.outputs:
            # True if set_inputs or self._is_graph_network or if adding a layer
            # to an already built deferred seq model.
            self.built = True

        if set_inputs or self._is_graph_network:
            self._init_graph_network(self.inputs, self.outputs, name=self.name)
        else:
            self._layers.append(layer)
        if self._layers:
            self._track_layers(self._layers)

        self._layer_call_argspecs[layer] = tf_inspect.getfullargspec(
            layer.call)