public static KerasSymbol[] CreateInput( Shape shape = null, Shape batch_shape = null, string name = null, DType dtype = null, bool sparse = false, KerasSymbol tensor = null) { if (batch_shape == null && tensor == null) { Debug.Assert(shape != null, "Please provide to Input either a `shape` or a `batch_shape` argument. Note that `shape` does not include the batch dimension."); } if (shape != null && batch_shape != null) { var list = shape.Data.ToList(); list.Insert(0, 0); batch_shape = new Shape(list); } if (dtype == null) { dtype = K.FloatX(); } var input_layer = new InputLayer(batch_input_shape: batch_shape, name: name, dtype: dtype, sparse: sparse, input_tensor: tensor); // Return tensor including _keras_shape and _keras_history. // Note that in this case train_output and test_output are the same pointer. var outputs = input_layer._inbound_nodes[0].output_tensors; return(outputs); }
public override void Build(Shape input_shape = null) { if (input_shape != null && this.inputs == null && this.inputs.Count > 0) { var batch_shape = input_shape; var dtype = K.FloatX(); var x = InputLayer.CreateInput(batch_shape: batch_shape, dtype: dtype, name: this.name + "_input"); this.inputs = x.ToList(); foreach (var layer in this._layers) { x = layer.Invoke(x, null); } this.outputs = x.ToList(); this._build_input_shape = input_shape; } if (this.inputs != null && this.inputs.Count > 0) { this.InitGraphNetwork(this.inputs.ToArray(), this.outputs.ToArray(), name: this.name); this.built = true; } }
public void Add(Layer layer) { this.built = false; if (this._layers.Count == 0) { var set_inputs = false; // First layer in model: check that it is an input layer. if (!(layer is InputLayer)) { // Create an input tensor and call `layer` on the input tensor. // First, we need to infer the expected input shape and dtype. var first_layer = layer; if (first_layer.batch_input_shape != null) { var batch_shape = first_layer.batch_input_shape; var dtype = first_layer.dtype; // Instantiate the input layer. var x = InputLayer.CreateInput(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.Call(x); set_inputs = true; } } else { // Corner case where the user passes an InputLayer via `add`. Debug.Assert(layer._inbound_nodes.Last().output_tensors.Length == 1); set_inputs = true; } if (set_inputs) { if (layer._inbound_nodes.Count > 0 && layer._inbound_nodes.Last().output_tensors.Length != 1) { throw new Exception("All layers in a Sequential model should have a single output tensor. For multi-output layers, use the functional API."); } this.outputs = new List <KerasSymbol> { layer._inbound_nodes.Last().output_tensors[0] }; this.inputs = MxNet.Keras.Utils.LayerUtils.GetSourceInputs(this.outputs[0]).ToList(); } } else if (this.outputs != null && this.outputs.Count > 0) { var output_tensor = layer.Call(this.outputs[0]); if (output_tensor.Length > 1) { throw new Exception("All layers in a Sequential model should have a single output tensor. For multi-output layers, use the functional API."); } this.outputs = output_tensor.ToList(); } if (this.inputs.Count > 0) { this.Build(); } else { this._layers.Add(layer); } }
public void Add(Model layer) { this.built = false; if (this._layers.Count == 0) { var set_inputs = false; // First layer in model: check that it is an input layer. if (layer is Model || layer is Sequential) { // Create an input tensor and call `layer` on the input tensor. // First, we need to infer the expected input shape and dtype. if (layer.Layers == null || layer.Layers.Length == 0) { throw new Exception("Cannot add an empty model to a `Sequential` model."); } // In case of nested models: recover the first layer // of the deepest model to infer input shape and dtype. object first_layer = layer.Layers[0]; while (first_layer is Model || first_layer is Sequential) { first_layer = ((Model)first_layer).Layers[0]; } if (((Layer)first_layer).batch_input_shape != null) { var batch_shape = ((Layer)first_layer).batch_input_shape; var dtype = ((Layer)first_layer).dtype; // Instantiate the input layer. var x = InputLayer.CreateInput(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.Call(x, null); set_inputs = true; } } else { // Corner case where the user passes an InputLayer via `add`. Debug.Assert(layer._inbound_nodes.Last().output_tensors.Length == 1); set_inputs = true; } if (set_inputs) { if (layer._inbound_nodes.Last().output_tensors.Length != 1) { throw new Exception("All layers in a Sequential model should have a single output tensor. For multi-output layers, use the functional API."); } this.outputs = new List <KerasSymbol> { layer._inbound_nodes.Last().output_tensors[0] }; this.inputs = MxNet.Keras.Utils.LayerUtils.GetSourceInputs(this.outputs[0]).ToList(); } } else if (this.outputs != null) { var output_tensor = layer.Invoke(new KerasSymbol[] { this.outputs[0] }, null); if (output_tensor.Length > 1) { throw new Exception("All layers in a Sequential model should have a single output tensor. For multi-output layers, use the functional API."); } this.outputs = output_tensor.ToList(); } if (this.inputs != null) { this.Build(); } else { this._layers.Add(layer); } }