예제 #1
0
        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);
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
            }
        }