예제 #1
0
        // Use for multiple dimension arrays
        static IntPtr SetupMulti(TFDataType dt, long [] dims, Array data, long bytes)
        {
            var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);

            if (dims == null)
            {
                return(TF_NewTensor(dt, IntPtr.Zero, 0, dataHandle.AddrOfPinnedObject(), (UIntPtr)bytes, FreeTensorHandle, GCHandle.ToIntPtr(dataHandle)));
            }
            else
            {
                return(TF_NewTensor(dt, dims, dims.Length, dataHandle.AddrOfPinnedObject(), (UIntPtr)bytes, FreeTensorHandle, GCHandle.ToIntPtr(dataHandle)));
            }
        }
예제 #2
0
        private static void FetchMultiDimensionalArray(Array target, TFDataType dt, IntPtr data, long[] shape)
        {
            var idx = new int[shape.Length];

            for (int i = 0; i < shape.Length; i++)
            {
                if (shape[i] > Int32.MaxValue)
                {
                    throw new ArgumentOutOfRangeException("Shape can not be longer than 32 bits");
                }
            }
            Copy(target, dt, shape, idx, 0, ref data);
        }
예제 #3
0
        /// <summary>
        ///   Input() is used to instantiate a Keras tensor.
        /// </summary>
        ///
        /// <remarks>
        ///   A Keras tensor is a tensor object from the underlying backend (Theano or TensorFlow), which we
        ///   augment with certain attributes that allow us to build a Keras model just by knowing the inputs
        ///   and outputs of the model.
        /// </remarks>
        ///
        /// <param name="shape">A shape tuple (integer), including the batch size. For instance,
        ///   <c>batch_shape= (10, 32)</c> indicates that the expected input will be batches of 10 32-dimensional
        ///   vectors. <c>batch_shape= (None, 32)</c> indicates batches of an arbitrary number of 32-dimensional
        ///   vectors.</param>
        /// <param name="batch_shape">The batch shape.</param>
        /// <param name="name">An optional name string for the layer. Should be unique in a model (do not reuse
        ///   the same name twice). It will be autogenerated if it isn't provided.</param>
        /// <param name="dtype">The data type expected by the input, as a string
        ///   (`float32`, `float64`, `int32`...)</param>
        /// <param name="sparse">A boolean specifying whether the placeholder to be created is sparse.</param>
        /// <param name="tensor">Optional existing tensor to wrap into the `Input` layer.
        ///   If set, the layer will not create a placeholder tensor.</param>
        ///
        public static List <Tensor> Input(int?[] shape     = null, int?[] batch_shape = null, string name = null,
                                          TFDataType dtype = KerasSharp.Tools.DEFAULT_DTYPE, bool sparse = false, Tensor tensor = null)
        {
            if (batch_shape == null && tensor == null)
            {
                throw new ArgumentException("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)
            {
                batch_shape = new int?[] { null }
            }
예제 #4
0
            private static (string[], int[], bool[], TFShape[], TFDataType[]) GetInputMetaData(TFGraph graph, string[] source, ISchema inputSchema)
            {
                var tfShapes        = new TFShape[source.Length];
                var tfTypes         = new TFDataType[source.Length];
                var colNames        = new string[source.Length];
                var inputColIndices = new int[source.Length];
                var isInputVector   = new bool[source.Length];

                for (int i = 0; i < source.Length; i++)
                {
                    colNames[i] = source[i];
                    if (!inputSchema.TryGetColumnIndex(colNames[i], out inputColIndices[i]))
                    {
                        throw Contracts.Except($"Column '{colNames[i]}' does not exist");
                    }

                    var tfoutput = new TFOutput(graph[colNames[i]]);
                    if (!TensorFlowUtils.IsTypeSupported(tfoutput.OutputType))
                    {
                        throw Contracts.Except($"Input type '{tfoutput.OutputType}' of input column '{colNames[i]}' is not supported in TensorFlow");
                    }

                    tfShapes[i] = graph.GetTensorShape(tfoutput);
                    var type  = inputSchema.GetColumnType(inputColIndices[i]);
                    var shape = tfShapes[i].ToIntArray().Skip(tfShapes[i][0] == -1 ? BatchSize : 0);
                    if (type.AsVector.DimCount == 1)
                    {
                        int valCount = shape.Aggregate((x, y) => x * y);
                        if (type.ValueCount != valCount)
                        {
                            throw Contracts.Except($"Input shape mismatch: Input '{colNames[i]}' has shape {tfShapes[i].ToString()}, but input data is of length {valCount}.");
                        }
                    }
                    else if (shape.Select((dim, j) => dim != type.AsVector.GetDim(j)).Any(b => b))
                    {
                        throw Contracts.Except($"Input shape mismatch: Input '{colNames[i]}' has shape {tfShapes[i].ToString()}, but input data is {type.AsVector.ToString()}.");
                    }

                    isInputVector[i] = type.IsVector;

                    tfTypes[i] = tfoutput.OutputType;

                    var l = new long[tfShapes[i].NumDimensions];
                    for (int ishape = 0; ishape < tfShapes[i].NumDimensions; ishape++)
                    {
                        l[ishape] = tfShapes[i][ishape] == -1 ? BatchSize : tfShapes[i][ishape];
                    }
                    tfShapes[i] = new TFShape(l);
                }
                return(colNames, inputColIndices, isInputVector, tfShapes, tfTypes);
            }
예제 #5
0
        /// <summary>
        /// Converts a <see cref="TFDataType"/> to a system type.
        /// </summary>
        /// <param name="type">The <see cref="TFDataType"/> to be converted.</param>
        /// <returns>The system type corresponding to the given <paramref name="type"/>.</returns>
        public static Type TypeFromTensorType(TFDataType type)
        {
            switch (type)
            {
            case TFDataType.Float:
                return(typeof(float));

            case TFDataType.Float_ref:
                return(typeof(float));

            case TFDataType.Double:
                return(typeof(double));

            case TFDataType.Int8:
                return(typeof(sbyte));

            case TFDataType.Int16:
                return(typeof(short));

            case TFDataType.Int32:
                return(typeof(int));

            case TFDataType.Int64:
                return(typeof(long));

            case TFDataType.UInt8:
                return(typeof(byte));

            case TFDataType.UInt16:
                return(typeof(ushort));

            case TFDataType.UInt32:
                return(typeof(uint));

            case TFDataType.UInt64:
                return(typeof(ulong));

            case TFDataType.String:
                throw new NotSupportedException();

            case TFDataType.Bool:
                return(typeof(bool));

            case TFDataType.Complex128:
                return(typeof(Complex));

            default:
                return(null);
            }
        }
예제 #6
0
        /// <summary>
        ///   Input() is used to instantiate a Keras tensor.
        /// </summary>
        ///
        /// <remarks>
        ///   A Keras tensor is a tensor object from the underlying backend (Theano or TensorFlow), which we
        ///   augment with certain attributes that allow us to build a Keras model just by knowing the inputs
        ///   and outputs of the model.
        /// </remarks>
        ///
        /// <param name="shape">A shape tuple (integer), including the batch size. For instance,
        ///   <c>batch_shape= (10, 32)</c> indicates that the expected input will be batches of 10 32-dimensional
        ///   vectors. <c>batch_shape= (None, 32)</c> indicates batches of an arbitrary number of 32-dimensional
        ///   vectors.</param>
        /// <param name="batch_shape">The batch shape.</param>
        /// <param name="name">An optional name string for the layer. Should be unique in a model (do not reuse
        ///   the same name twice). It will be autogenerated if it isn't provided.</param>
        /// <param name="dtype">The data type expected by the input, as a string
        ///   (`float32`, `float64`, `int32`...)</param>
        /// <param name="sparse">A boolean specifying whether the placeholder to be created is sparse.</param>
        /// <param name="tensor">Optional existing tensor to wrap into the `Input` layer.
        ///   If set, the layer will not create a placeholder tensor.</param>
        ///
        public static List <Tensor> Input(int?[] shape     = null, int?[] batch_shape = null, string name = null,
                                          TFDataType dtype = KerasSharp.Utils.DEFAULT_DTYPE, bool sparse = false, Tensor tensor = null)
        {
            // https://github.com/fchollet/keras/blob/f65a56fb65062c8d14d215c9f4b1015b97cc5bf3/keras/engine/topology.py#L1416

            if (batch_shape == null && tensor == null)
            {
                throw new ArgumentException("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)
            {
                batch_shape = new int?[] { null }
            }
        private TFTensor CreateTensorFromImage(byte[] contents, TFDataType dataType = TFDataType.Float)
        {
            // DecodeJpeg uses a scalar String-valued tensor as input.
            using (var tensor = TFTensor.CreateString(contents))
                using (var graph = ConstructGraphToNormalizeImage(out TFOutput input, out TFOutput output, dataType))
                    using (var session = new TFSession(graph))
                    {
                        var normalized = session.Run(
                            inputs: new[] { input },
                            inputValues: new[] { tensor },
                            outputs: new[] { output });

                        return(normalized[0]);
                    }
        }
        internal static bool IsTypeSupported(TFDataType tfoutput)
        {
            switch (tfoutput)
            {
            case TFDataType.Float:
            case TFDataType.Double:
            case TFDataType.UInt8:
            case TFDataType.UInt16:
            case TFDataType.UInt32:
            case TFDataType.UInt64:
                return(true);

            default:
                return(false);
            }
        }
예제 #9
0
        private static unsafe object FetchSimple(TFDataType dt, IntPtr data)
        {
            switch (dt)
            {
            case TFDataType.Float:
                return(*(float *)data);

            case TFDataType.Double:
                return(*(double *)data);

            case TFDataType.Int8:
                return(*(sbyte *)data);

            case TFDataType.Int16:
                return(*(short *)data);

            case TFDataType.Int32:
                return(*(int *)data);

            case TFDataType.Int64:
                return(*(long *)data);

            case TFDataType.UInt8:
                return(*(byte *)data);

            case TFDataType.UInt16:
                return(*(ushort *)data);

            case TFDataType.UInt32:
                return(*(uint *)data);

            case TFDataType.UInt64:
                return(*(ulong *)data);

            case TFDataType.String:
                throw new NotImplementedException();

            case TFDataType.Bool:
                return(*(bool *)data);

            case TFDataType.Complex128:
                return(*(Complex *)data);

            default:
                return(null);
            }
        }
예제 #10
0
        private static PrimitiveDataViewType Tf2MlNetTypeOrNull(TFDataType type)
        {
            switch (type)
            {
            case TFDataType.Float:
                return(NumberDataViewType.Single);

            case TFDataType.Float_ref:
                return(NumberDataViewType.Single);

            case TFDataType.Double:
                return(NumberDataViewType.Double);

            case TFDataType.UInt8:
                return(NumberDataViewType.Byte);

            case TFDataType.UInt16:
                return(NumberDataViewType.UInt16);

            case TFDataType.UInt32:
                return(NumberDataViewType.UInt32);

            case TFDataType.UInt64:
                return(NumberDataViewType.UInt64);

            case TFDataType.Int8:
                return(NumberDataViewType.SByte);

            case TFDataType.Int16:
                return(NumberDataViewType.Int16);

            case TFDataType.Int32:
                return(NumberDataViewType.Int32);

            case TFDataType.Int64:
                return(NumberDataViewType.Int64);

            case TFDataType.Bool:
                return(BooleanDataViewType.Instance);

            case TFDataType.String:
                return(TextDataViewType.Instance);

            default:
                return(null);
            }
        }
예제 #11
0
 /// <summary>
 ///   Specifies the ndim, dtype and shape of every input to a layer.
 /// </summary>
 ///
 /// <remarks>
 ///   Every layer should expose (if appropriate) an `input_spec` attribute:
 ///   a list of instances of InputSpec(one per input tensor).
 ///   A null entry in a shape is compatible with any dimension,
 ///   a null shape is compatible with any shape.
 /// </remarks>
 ///
 /// <param name="dtype">Expected datatype of the input.</param>
 /// <param name="shape">Shape tuple, expected shape of the input
 ///         (may include null for unchecked axes).</param>
 /// <param name="ndim">Integer, expected rank of the input.</param>
 /// <param name="max_ndim">The maximum rank of the input.</param>
 /// <param name="min_ndim">The minimum rank of the input.</param>
 /// <param name="axes">Dictionary mapping integer axes to
 ///    a specific dimension value.</param>
 public InputSpec(TFDataType dtype = Tools.DEFAULT_DTYPE, int[] shape = null, int?ndim     = null,
                  int?max_ndim     = null, int?min_ndim = null, Dictionary <int, int> axes = null)
 {
     this.dtype = dtype;
     this.shape = shape;
     if (shape != null)
     {
         this.ndim = shape.Length;
     }
     else
     {
         this.ndim = ndim;
     }
     this.max_ndim = max_ndim;
     this.min_ndim = min_ndim;
     this.axes     = axes ?? new Dictionary <int, int>();
 }
예제 #12
0
        private static TFGraph ConstructGraphToNormalizeImage(out TFOutput input,
                                                              out TFOutput output,
                                                              TFDataType destinationDataType = TFDataType.Float)
        {
            var graph = new TFGraph();

            input = graph.Placeholder(TFDataType.String);

            output = graph.Cast(
                graph.ExpandDims(
                    input: graph.Cast(graph.DecodeJpeg(contents: input, channels: 3), DstT: TFDataType.Float),
                    dim: graph.Const(0, "make_batch")
                    )
                , destinationDataType
                );

            return(graph);
        }
예제 #13
0
        // Convert the image in filename to a Tensor suitable as input to the Inception model.
        public static TFTensor CreateTensorFromImage(byte[] image, TFDataType destinationDataType = TFDataType.Float)
        {
            // DecodeJpeg uses a scalar String-valued tensor as input.
            var tensor = TFTensor.CreateString(image);

            // Construct a graph to normalize the image
            var(graph, input, output) = ConstructGraphToNormalizeImage(destinationDataType);
            // Execute that graph to normalize this one image
            using (var session = new TFSession(graph))
            {
                var normalized = session.Run(
                    inputs: new[] { input },
                    inputValues: new[] { tensor },
                    outputs: new[] { output });

                return(normalized[0]);
            }
        }
예제 #14
0
        // Use for single dimension arrays
        internal static IntPtr SetupTensor(TFDataType dt, long[] dims, Array data, int start, int count, int size)
        {
            if (start < 0 || start > data.Length - count)
            {
                throw new ArgumentException("start + count > Array size");
            }

            var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);

            if (dims == null)
            {
                return(TF_NewTensor(dt, IntPtr.Zero, 0, dataHandle.AddrOfPinnedObject() + start * size, (UIntPtr)(count * size), FreeTensorHandleDelegate, GCHandle.ToIntPtr(dataHandle)));
            }
            else
            {
                return(TF_NewTensor(dt, dims, dims.Length, dataHandle.AddrOfPinnedObject() + start * size, (UIntPtr)(count * size), FreeTensorHandleDelegate, GCHandle.ToIntPtr(dataHandle)));
            }
        }
예제 #15
0
        private static PrimitiveType Tf2MlNetTypeOrNull(TFDataType type)
        {
            switch (type)
            {
            case TFDataType.Float:
                return(NumberType.R4);

            case TFDataType.Float_ref:
                return(NumberType.R4);

            case TFDataType.Double:
                return(NumberType.R8);

            case TFDataType.UInt8:
                return(NumberType.U1);

            case TFDataType.UInt16:
                return(NumberType.U2);

            case TFDataType.UInt32:
                return(NumberType.U4);

            case TFDataType.UInt64:
                return(NumberType.U8);

            case TFDataType.Int8:
                return(NumberType.I1);

            case TFDataType.Int16:
                return(NumberType.I2);

            case TFDataType.Int32:
                return(NumberType.I4);

            case TFDataType.Int64:
                return(NumberType.I8);

            case TFDataType.Bool:
                return(BoolType.Instance);

            default:
                return(null);
            }
        }
예제 #16
0
        private static TFGraph ConstructGraphToNormalizeRawImage(out TFOutput input, out TFOutput output, int resizeWidth, int resizeHeight,
                                                                 TFDataType destinationDataType = TFDataType.Float)
        {
            // Some constants specific to the pre-trained model at:
            // https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip
            //
            // - The model was trained after with images scaled to 224x224 pixels.
            // - The colors, represented as R, G, B in 1-byte each were converted to
            //   float using (value - Mean)/Scale.

            const float Mean  = 117;
            const float Scale = 1;

            //var graph = new TFGraph();

            //input = graph.Placeholder(TFDataType.UInt8);
            //output = graph.Cast(graph.Div(
            //    x: graph.Sub(
            //        x: graph.ResizeBilinear(
            //            images: graph.ExpandDims(
            //                input: graph.Cast(input, DstT: TFDataType.Float),
            //                dim: graph.Const(0, "make_batch")),
            //            size: graph.Const(new int[] { resizeWidth, resizeHeight }, "size")),
            //        y: graph.Const(Mean, "mean")),
            //    y: graph.Const(Scale, "scale")), destinationDataType);

            //return graph;



            var graph = new TFGraph();

            input = graph.Placeholder(TFDataType.UInt8);

            output = graph.Cast(
                graph.ExpandDims(
                    input: graph.Cast(input, DstT: TFDataType.Float),
                    dim: graph.Const(0, "make_batch")
                    )
                , destinationDataType
                );

            return(graph);
        }
예제 #17
0
        // Convert the image in filename to a Tensor suitable as input to the Inception model.
        public static TFTensor CreateTensorFromImageFile(string file, TFDataType destinationDataType = TFDataType.Float)
        {
            var contents = File.ReadAllBytes(file);

            // DecodeJpeg uses a scalar String-valued tensor as input.
            using (var tensor = TFTensor.CreateString(contents))
                // Construct a graph to normalize the image
                using (var graph = ConstructGraphToNormalizeImage(out TFOutput input, out TFOutput output, destinationDataType))
                    // Execute that graph to normalize this one image
                    using (var session = new TFSession(graph))
                    {
                        var normalized = session.Run(
                            inputs: new[] { input },
                            inputValues: new[] { tensor },
                            outputs: new[] { output });
                        Console.WriteLine(normalized.Length);
                        return(normalized[0]);
                    }
        }
예제 #18
0
        public static TFTensor CreateTensor(TFTensor tensor, TFDataType destinationDataType = TFDataType.Float)
        {
            TFGraph  graph;
            TFOutput input, output;

            // Construct a graph to normalize the image
            ConstructGraphToNormalizeImage(out graph, out input, out output, destinationDataType);

            // Execute that graph to normalize this one image
            using (var session = new TFSession(graph))
            {
                var normalized = session.Run(
                    inputs: new[] { input },
                    inputValues: new[] { tensor },
                    outputs: new[] { output });

                return(normalized[0]);
            }
        }
예제 #19
0
        internal static PrimitiveType Tf2MlNetType(TFDataType type)
        {
            switch (type)
            {
            case TFDataType.Float:
                return(NumberType.R4);

            case TFDataType.Double:
                return(NumberType.R8);

            case TFDataType.UInt32:
                return(NumberType.U4);

            case TFDataType.UInt64:
                return(NumberType.U8);

            default:
                throw new NotSupportedException("TensorFlow type not supported.");
            }
        }
예제 #20
0
        static Type TypeFromTensorType(TFDataType type)
        {
            switch (type)
            {
            case TFDataType.Float:
                return(typeof(float));

            case TFDataType.Double:
                return(typeof(double));

            case TFDataType.Int32:
                return(typeof(int));

            case TFDataType.UInt8:
                return(typeof(byte));

            case TFDataType.Int16:
                return(typeof(short));

            case TFDataType.Int8:
                return(typeof(sbyte));

            case TFDataType.String:
                return(typeof(TFString));

            case TFDataType.Int64:
                return(typeof(long));

            case TFDataType.Bool:
                return(typeof(bool));

            case TFDataType.UInt16:
                return(typeof(ushort));

            case TFDataType.Complex128:
                return(typeof(Complex));

            default:
                return(null);
            }
        }
예제 #21
0
    private unsafe TFTensor CreateTensorFromImageFileAlt(Mat inputFileName, TFDataType destinationDataType = TFDataType.Float)
    {
        Cv2.Resize(inputFileName, inputFileName, new OpenCvSharp.Size(64, 64)); // 일반 graph일 때


        var array = new byte[inputFileName.Width * inputFileName.Height * inputFileName.ElemSize()]; // 임시 array 생성

        Marshal.Copy(inputFileName.Data, array, 0, array.Length);                                    // MS에서 제공하는 COPY Method
        var matrix = new byte[1, inputFileName.Rows, inputFileName.Width, 3];

        for (int i = 0; i < inputFileName.Rows; i++)
        {
            for (int j = 0; j < inputFileName.Cols; j++)
            {
                // 혹시라도 안되면 byte의 channel에 주목해보기!!! 난 bgr2rgb도 따로 안해서 둘다 시험해보기.
                matrix[0, i, j, 0] = array[i * inputFileName.Step() + j * 3 + 0]; // 행-렬이다 여기서도. 즉 y,x이다.
                matrix[0, i, j, 1] = array[i * inputFileName.Step() + j * 3 + 1];
                matrix[0, i, j, 2] = array[i * inputFileName.Step() + j * 3 + 2]; // c++에서 복사해보고 제대로 복사되나 보고
            }
        }
        UInt16[,,,] float_array = new UInt16[1, inputFileName.Rows, inputFileName.Cols, 3];
        for (int i = 0; i < inputFileName.Rows; i++)
        {
            for (int j = 0; j < inputFileName.Cols; j++)
            { // 안된다면 byte에
                // 혹시라도 안되면 byte의 channel에 주목해보기!!! 난 bgr2rgb도 따로 안해서 둘다 시험해보기.
                float_array[0, i, j, 0] = (UInt16)(matrix[0, i, j, 0]);

                float_array[0, i, j, 1] = (UInt16)(matrix[0, i, j, 1]);

                float_array[0, i, j, 2] = (UInt16)(matrix[0, i, j, 2]); // c++에서 복사해보고 제대로 복사되나 보고
            }
        }

        //Buffer.BlockCopy(array, 0, float_array, 0, matrix.Length);


        TFTensor tensor = float_array; // 그대로 주게되면 제대로 들어가는지도 보고.

        return(tensor);
    }
예제 #22
0
        public static TFTensor CreateTensorFromImageFile(byte[] contents, TFDataType destinationDataType = TFDataType.Float)
        {
            var tensor = TFTensor.CreateString(contents);

            TFOutput input, output;

            // Construct a graph to normalize the image
            using (var graph = ConstructGraphToNormalizeImage(out input, out output, destinationDataType))
            {
                // Execute that graph to normalize this one image
                using (var session = new TFSession(graph))
                {
                    var normalized = session.Run(
                        inputs: new[] { input },
                        inputValues: new[] { tensor },
                        outputs: new[] { output });

                    return(normalized[0]);
                }
            }
        }
예제 #23
0
        /// <summary>
        /// Creates a sequence of numbers.
        /// </summary>
        /// <remarks>
        /// Creates a sequence of numbers that begins at `start` and extends by increments of `delta` up to but not including
        /// `limit`. The dtype of the resulting tensor is inferred from the inputs unless it is provided explicitly.
        /// </remarks>
        /// <param name="start">A 0 - D `Tensor` (scalar).Acts as first entry in the range if `limit` is not None; otherwise, acts as range limit and first entry defaults to 0.</param>
        /// <param name="limit">A 0 - D `Tensor` (scalar).Upper limit of sequence, exclusive. If None, defaults to the value of `start` while the first entry of the range defaults to 0.</param>
        /// <param name="delta">A 0 - D `Tensor` (scalar).Number that increments `start`. Defaults to 1.</param>
        /// <param name="dataType">The type of the elements of the resulting tensor.</param>
        /// <param name="operName">A name for the operation.Defaults to "range".</param>
        public TFOutput Range(TFOutput start, TFOutput?limit = null, TFOutput?delta = null, TFDataType?dataType = null, string operName = "range")
        {
            // https://github.com/tensorflow/tensorflow/blob/r1.2/tensorflow/python/ops/math_ops.py#L1156

            if (limit == null)
            {
                limit = start;
                start = Cast(Const(new TFTensor(0.0)), start.OutputType); // TODO: Maybe add dataType as convenience in Const?
            }

            if (delta == null)
            {
                delta = Cast(Const(new TFTensor(1.0)), start.OutputType);
            }

            using (var newScope = WithScope(MakeName("Range", operName)))
            {
                // infer dtype if not explicitly provided
                if (dataType == null)
                {
                    var dtype_hierarchy = new[] { TFDataType.Int32, TFDataType.Int64, TFDataType.Float, TFDataType.Double };
                    if (!dtype_hierarchy.Contains(start.OutputType) ||
                        !dtype_hierarchy.Contains(limit.Value.OutputType) ||
                        !dtype_hierarchy.Contains(delta.Value.OutputType))
                    {
                        throw new ArgumentException("Unexpected type");
                    }

                    TFDataType[] dtypes         = new[] { start.OutputType, limit.Value.OutputType, delta.Value.OutputType };
                    int          imax           = dtypes.Select(x => Array.IndexOf(dtype_hierarchy, x)).Max();
                    TFDataType   inferred_dtype = dtype_hierarchy[imax];

                    start = Cast(start, inferred_dtype);
                    limit = Cast(limit.Value, inferred_dtype);
                    delta = Cast(delta.Value, inferred_dtype);
                }

                return(Range(start, limit.Value, delta.Value, operName: operName));
            }
        }
예제 #24
0
        /// <summary>
        /// Create a constant tensor based on a shape
        /// Used by Zeros and Ones
        /// </summary>
        /// <param name="value">Value for tensor</param>
        /// <param name="tfshape">Shape of the tensor</param>
        /// <param name="dtype">Optional Type of the Zero value. Default: Double</param>
        /// <param name="operName">Operation name, optional.</param>
        /// <returns></returns>
        /// see https://github.com/tensorflow/tensorflow/blob/r1.1/tensorflow/python/framework/constant_op.py
        public TFOutput Constant(object value, TFShape tfshape, TFDataType dtype = TFDataType.Double, string operName = null)
        {
            if (tfshape.NumDimensions <= 0)
            {
                TFTensor tensor = TFTensor.Create1DTensor(dtype, value);
                return(Const(tensor, tensor.TensorType, operName));
            }
            //convert the .net type to relevant tensorflow type
            object dtvalue = TFTensor.FetchSimple(dtype, value);

            var shape = tfshape.ToArray();
            var idx   = new int [shape.Length];

            for (int i = 0; i < shape.Length; i++)
            {
                if (shape [i] > Int32.MaxValue)
                {
                    throw new ArgumentOutOfRangeException("Shape can not be longer than 32 bits");
                }
            }

            Array data = null;

            if (tfshape.IsLongArray)
            {
                data = Array.CreateInstance(dtvalue.GetType(), tfshape.ToArray());
            }
            else
            {
                data = Array.CreateInstance(dtvalue.GetType(), tfshape.ToIntArray());
            }

            TFTensor.Set(data, dtype, shape, idx, 0, value);

            TFTensor tensor_value = new TFTensor(data);

            return(Const(tensor_value, tensor_value.TensorType, operName));
        }
예제 #25
0
        // Convert the image in filename to a Tensor suitable as input to the Inception model.
        public static TFTensor CreateTensorFromImageFile(string file, TFDataType destinationDataType = TFDataType.Float)
        {
            contents = File.ReadAllBytes(file);
            System.Buffer.BlockCopy(contents, 99712, crop, 0, 336 * 336);

            // DecodeJpeg uses a scalar String-valued tensor as input.
            var tensor = TFTensor.CreateString(contents);

            TFOutput input, output;

            // Construct a graph to normalize the image
            using (var graph = ConstructGraphToNormalizeImage(out input, out output, destinationDataType)){
                // Execute that graph to normalize this one image
                using (var session = new TFSession(graph)) {
                    var normalized = session.Run(
                        inputs: new [] { input },
                        inputValues: new [] { tensor },
                        outputs: new [] { output });

                    return(normalized [0]);
                }
            }
        }
예제 #26
0
        // Additional pointers for using TensorFlow & CustomVision together
        // Python: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/label_image/label_image.py
        // C++: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/label_image/main.cc
        // Java: https://github.com/Azure-Samples/cognitive-services-android-customvision-sample/blob/master/app/src/main/java/demo/tensorflow/org/customvision_sample/MSCognitiveServicesClassifier.java
        private static (TFGraph, TFOutput, TFOutput) ConstructGraphToNormalizeImage(TFDataType destinationDataType = TFDataType.Float)
        {
            const int W = 227;
            const int H = 227;
            //const float Scale = 1;

            // Depending on your CustomVision.ai Domain - set appropriate Mean Values (RGB)
            // https://github.com/Azure-Samples/cognitive-services-android-customvision-sample for RGB values (in BGR order)
            //var bgrValues = new TFTensor(new float[] { 104.0f, 117.0f, 123.0f }); // General (Compact) & Landmark (Compact)
            //var bgrValues = new TFTensor(0f); // Retail (Compact)

            var graph = new TFGraph();
            var input = graph.Placeholder(TFDataType.String);

            var caster        = graph.Cast(graph.DecodeJpeg(contents: input, channels: 3), DstT: TFDataType.Float);
            var dims_expander = graph.ExpandDims(caster, graph.Const(0, "batch"));
            var resized       = graph.ResizeBilinear(dims_expander, graph.Const(new int[] { H, W }, "size"));
            //var resized_mean = graph.Sub(resized, graph.Const(bgrValues, "mean"));
            //var normalised = graph.Div(resized_mean, graph.Const(Scale));
            var output = resized;

            return(graph, input, output);
        }
예제 #27
0
        // The inception model takes as input the image described by a Tensor in a very
        // specific normalized format (a particular image size, shape of the input tensor,
        // normalized pixel values etc.).
        //
        // This function constructs a graph of TensorFlow operations which takes as
        // input a JPEG-encoded string and returns a tensor suitable as input to the
        // inception model.
        private (TFGraph graph, TFOutput input, TFOutput output) PreprocessNeuralNetwork(int width, int height)
        {
            // Custom model has been processed using Keras
            // which uses its own algorithm for normalizing images
            // RGB values are normalized between -1 and 1
            // image shape can be customized in keras,
            // so width and height are converted to method arguments
            const TFDataType destinationDataType = TFDataType.Float;

            TFGraph  graph = new TFGraph();
            TFOutput input = graph.Placeholder(TFDataType.String);

            var decodeJpeg  = graph.DecodeJpeg(contents: input, channels: 3);
            var castToFloat = graph.Cast(decodeJpeg, DstT: TFDataType.Float);
            var expandDims  = graph.ExpandDims(castToFloat, dim: graph.Const(0, "make_batch")); // shape: [1, height, width, channels]
            var resize      = graph.ResizeBilinear(expandDims, size: graph.Const(new int[] { width, height }, "size"));
            var divide      = graph.Div(resize, y: graph.Const(255f, destinationDataType, "divide"));
            var substract   = graph.Sub(divide, y: graph.Const(.5f, destinationDataType, "sub"));
            var multiply    = graph.Mul(substract, y: graph.Const(2f, destinationDataType, "multiply"));
            var castToDestinationDataType = graph.Cast(multiply, destinationDataType);

            return(graph, input, castToDestinationDataType);
        }
예제 #28
0
        public static TFTensor CreateTensorFromMemoryJpg(Byte[] jpeg, TFDataType destinationDataType = TFDataType.Float)
        {
            // DecodeJpeg uses a scalar String-valued tensor as input.

            var      tensor = TFTensor.CreateString(jpeg);
            TFOutput input;
            TFOutput output;

            // Construct a graph to normalize the image
            using (var graph = ConstructGraphToNormalizeImage2(out input, out output, destinationDataType))
            {
                // Execute that graph to normalize this one image
                using (var session = new TFSession(graph))
                {
                    var normalized = session.Run(
                        inputs: new[] { input },
                        inputValues: new[] { tensor },
                        outputs: new[] { output });

                    return(normalized[0]);
                }
            }
        }
        private static TFTensor CreateTensorFromBitmap(Image bitmap, TFDataType destinationDataType = TFDataType.Float)
        {
            //var contents = File.ReadAllBytes(file);
            var contents = ImageUtils.ImageToByte(bitmap);

            // DecodeJpeg uses a scalar String-valued tensor as input.
            var tensor = TFTensor.CreateString(contents);

            // Construct a graph to normalize the image
            using (var graph = ConstructGraphToNormalizeImage(out TFOutput input, out TFOutput output, destinationDataType))
            {
                // Execute that graph to normalize this one image
                using (var session = new TFSession(graph))
                {
                    var normalized = session.Run(
                        inputs: new[] { input },
                        inputValues: new[] { tensor },
                        outputs: new[] { output });

                    return(normalized[0]);
                }
            }
        }
예제 #30
0
        public static TFTensor CreateTensorFromBGR(Byte[] rgb, TFDataType destinationDataType = TFDataType.Float)
        {
            // DecodeJpeg uses a scalar String-valued tensor as input.
            //var tensor = TFTensor.CreateString(bgr);

            /*
             *        byte[] floatValues = new byte[640 * 480 * 3];
             *        int j = 0;
             *        for (int i = 0; i < rgb.Length/4; i++)
             *        {
             *            floatValues[j * 3 + 0] = (rgb[i * 4 + 0]) ;
             *            floatValues[j * 3 + 1] = (rgb[i * 4 + 1]) ;
             *            floatValues[j * 3 + 2] = (rgb[i * 4 + 2]) ;
             *            j++;
             *        }*/

            TFShape shape = new TFShape(480, 640, 3);

            var      tensor = TFTensor.FromBuffer(shape, rgb, 0, rgb.Length);
            TFOutput input;
            TFOutput output;

            // Construct a graph to normalize the image
            using (var graph = ConstructGraphToNormalizeImage(out input, out output, destinationDataType))
            {
                // Execute that graph to normalize this one image
                using (var session = new TFSession(graph))
                {
                    var normalized = session.Run(
                        inputs: new[] { input },
                        inputValues: new[] { tensor },
                        outputs: new[] { output });

                    return(normalized[0]);
                }
            }
        }