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` argu
(self, layer)
| 130 | |
| 131 | @trackable.no_automatic_dependency_tracking |
| 132 | def add(self, layer): |
| 133 | """Adds a layer instance on top of the layer stack. |
| 134 | |
| 135 | Arguments: |
| 136 | layer: layer instance. |
| 137 | |
| 138 | Raises: |
| 139 | TypeError: If `layer` is not a layer instance. |
| 140 | ValueError: In case the `layer` argument does not |
| 141 | know its input shape. |
| 142 | ValueError: In case the `layer` argument has |
| 143 | multiple output tensors, or is already connected |
| 144 | somewhere else (forbidden in `Sequential` models). |
| 145 | """ |
| 146 | # If we are passed a Keras tensor created by keras.Input(), we can extract |
| 147 | # the input layer from its keras history and use that without any loss of |
| 148 | # generality. |
| 149 | if hasattr(layer, '_keras_history'): |
| 150 | origin_layer = layer._keras_history[0] |
| 151 | if isinstance(origin_layer, input_layer.InputLayer): |
| 152 | layer = origin_layer |
| 153 | |
| 154 | if not isinstance(layer, base_layer.Layer): |
| 155 | raise TypeError('The added layer must be ' |
| 156 | 'an instance of class Layer. ' |
| 157 | 'Found: ' + str(layer)) |
| 158 | |
| 159 | tf_utils.assert_no_legacy_layers([layer]) |
| 160 | |
| 161 | self.built = False |
| 162 | set_inputs = False |
| 163 | if not self._layers: |
| 164 | if isinstance(layer, input_layer.InputLayer): |
| 165 | # Corner case where the user passes an InputLayer layer via `add`. |
| 166 | assert len(nest.flatten(layer._inbound_nodes[-1].output_tensors)) == 1 |
| 167 | set_inputs = True |
| 168 | else: |
| 169 | batch_shape, dtype = training_utils.get_input_shape_and_dtype(layer) |
| 170 | if batch_shape: |
| 171 | # Instantiate an input layer. |
| 172 | x = input_layer.Input( |
| 173 | batch_shape=batch_shape, dtype=dtype, name=layer.name + '_input') |
| 174 | # This will build the current layer |
| 175 | # and create the node connecting the current layer |
| 176 | # to the input layer we just created. |
| 177 | layer(x) |
| 178 | set_inputs = True |
| 179 | |
| 180 | if set_inputs: |
| 181 | # If an input layer (placeholder) is available. |
| 182 | if len(nest.flatten(layer._inbound_nodes[-1].output_tensors)) != 1: |
| 183 | raise ValueError('All layers in a Sequential model ' |
| 184 | 'should have a single output tensor. ' |
| 185 | 'For multi-output layers, ' |
| 186 | 'use the functional API.') |
| 187 | self.outputs = [ |
| 188 | nest.flatten(layer._inbound_nodes[-1].output_tensors)[0] |
| 189 | ] |