def __init__(self, layers=None, name=None): super(Sequential, self).__init__(name=name) self.supports_masking = True self._build_input_shape = None self._compute_output_and_mask_jointly = True self._layer_call_argspecs = {} # Add to the model any layers passed to the constructor. if layers: tf_utils.assert_no_legacy_layers(layers) for layer in layers: self.add(layer)
def __init__(self, layers=None, name=None): """Creates a `Sequential` model instance. Args: layers: Optional list of layers to add to the model. name: Optional name for the model. """ super(Sequential, self).__init__(name=name, autocast=False) self.supports_masking = True self._compute_output_and_mask_jointly = True self._layer_call_argspecs = {} # Add to the model any layers passed to the constructor. if layers: if not isinstance(layers, (list, tuple)): layers = [layers] tf_utils.assert_no_legacy_layers(layers) for layer in layers: self.add(layer)
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)
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)
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()
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)
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)