예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OnnxModel"/> class.
        /// </summary>
        /// <param name="configuration">The configuration for the onnx model runner.</param>
        public OnnxModel(OnnxModelConfiguration configuration)
        {
            this.configuration = configuration;

            // The schemaDefinition is a ML.NET construct that allows us to specify the form
            // of the inputs. In this case we construct a schema definition programmatically
            // to reflect that the input is a vector of floats, of the sizes specified in the
            // configuration
            this.schemaDefinition = SchemaDefinition.Create(typeof(OnnxInputVector));
            this.schemaDefinition[nameof(OnnxInputVector.Vector)].ColumnType = new VectorDataViewType(NumberDataViewType.Single, this.configuration.InputVectorSize);
            this.schemaDefinition[nameof(OnnxInputVector.Vector)].ColumnName = this.configuration.InputVectorName;

            // We create the onnxTransformer which will be used to score inputs
            var onnxEmptyInputDataView = this.context.Data.LoadFromEnumerable(new List <OnnxInputVector>(), this.schemaDefinition);
            var scoringEstimator       =
                this.context.Transforms.ApplyOnnxModel(
                    modelFile: configuration.ModelFileName,
                    outputColumnNames: new[] { configuration.OutputVectorName },
                    inputColumnNames: new[] { configuration.InputVectorName },
                    shapeDictionary: configuration.ShapeDictionary,
                    gpuDeviceId: configuration.GpuDeviceId,
                    fallbackToCpu: false);

            this.onnxTransformer = scoringEstimator.Fit(onnxEmptyInputDataView);
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MaskRCNNOnnxModel"/> class.
        /// </summary>
        /// <param name="imageWidth">Input image width.</param>
        /// <param name="imageHeight">Input image height.</param>
        /// <param name="modelFileName">Model file name.</param>
        /// <param name="gpuDeviceId">GPU device ID to run execution on, or null to run on CPU.</param>
        /// <remarks>
        /// To run on a GPU, use the Microsoft.Psi.Onnx.Gpu library instead of Microsoft.Psi.Onnx.Cpu, and pass
        /// a valid non-negative integer. Typical device ID values are 0 or 1.
        /// </remarks>
        public MaskRCNNOnnxModel(int imageWidth, int imageHeight, string modelFileName, int?gpuDeviceId = null)
        {
            //// REVIEW: note the ColumnType below is (float, 3, height, width), while the plain OnnxModel is simply (float, size)
            ////         the rest is very similar to OnnxModel

            this.schemaDefinition = SchemaDefinition.Create(typeof(OnnxInputVector));
            this.schemaDefinition[nameof(OnnxInputVector.Vector)].ColumnType = new VectorDataViewType(NumberDataViewType.Single, 3, imageHeight, imageWidth);
            this.schemaDefinition[nameof(OnnxInputVector.Vector)].ColumnName = "image";

            var onnxEmptyInputDataView = this.context.Data.LoadFromEnumerable(new List <OnnxInputVector>(), this.schemaDefinition);
            var shapeDictionary        = new Dictionary <string, int[]>()
            {
                { "image", new int[] { 3, imageHeight, imageWidth } }
            };

            var scoringEstimator =
                this.context.Transforms.ApplyOnnxModel(
                    modelFile: modelFileName,
                    inputColumnNames: new[] { "image" },
                    outputColumnNames: new[] { BOXES, LABELS, SCORES, MASKS },
                    shapeDictionary: shapeDictionary,
                    gpuDeviceId: gpuDeviceId,
                    fallbackToCpu: false);

            this.onnxTransformer = scoringEstimator.Fit(onnxEmptyInputDataView);
        }
        public void OnnxModelScenario()
        {
            var modelFile = "squeezenet/00000001/model.onnx";

            using (var env = new ConsoleEnvironment(seed: 1, conc: 1))
            {
                var samplevector = GetSampleArrayData();

                var dataView = ML.Data.ReadFromEnumerable(
                    new TestData[] {
                    new TestData()
                    {
                        data_0 = samplevector
                    }
                });

                var onnx = new OnnxTransformer(env, "softmaxout_1", modelFile, "data_0").Transform(dataView);

                onnx.Schema.TryGetColumnIndex("softmaxout_1", out int score);

                using (var curs = onnx.GetRowCursor(onnx.Schema["softmaxout_1"]))
                {
                    var getScores = curs.GetGetter <VBuffer <float> >(score);
                    var buffer    = default(VBuffer <float>);
                    while (curs.MoveNext())
                    {
                        getScores(ref buffer);
                        Assert.Equal(1000, buffer.Length);
                    }
                }
            }
        }
예제 #4
0
        [ConditionalFact(typeof(Environment), nameof(Environment.Is64BitProcess))] // x86 output differs from Baseline
        public void OnnxModelMultiInput()
        {
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                return;
            }

            var modelFile = @"twoinput\twoinput.onnx";

            using (var env = new ConsoleEnvironment(seed: 1, conc: 1))
            {
                var samplevector = GetSampleArrayData();

                var dataView = ComponentCreation.CreateDataView(Env,
                                                                new TestDataMulti[] {
                    new TestDataMulti()
                    {
                        ina = new float[] { 1, 2, 3, 4, 5 },
                        inb = new float[] { 1, 2, 3, 4, 5 }
                    }
                });
                var onnx = new OnnxTransformer(env, modelFile, new[] { "ina", "inb" }, new[] { "outa", "outb" }).Transform(dataView);

                onnx.Schema.TryGetColumnIndex("outa", out int scoresa);
                onnx.Schema.TryGetColumnIndex("outb", out int scoresb);
                using (var curs = onnx.GetRowCursor(col => col == scoresa || col == scoresb))
                {
                    var getScoresa = curs.GetGetter <VBuffer <float> >(scoresa);
                    var getScoresb = curs.GetGetter <VBuffer <float> >(scoresb);
                    var buffera    = default(VBuffer <float>);
                    var bufferb    = default(VBuffer <float>);

                    while (curs.MoveNext())
                    {
                        getScoresa(ref buffera);
                        getScoresb(ref bufferb);
                        Assert.Equal(5, buffera.Length);
                        Assert.Equal(5, bufferb.Length);
                        Assert.Equal(0, buffera.GetValues().ToArray().Sum());
                        Assert.Equal(30, bufferb.GetValues().ToArray().Sum());
                    }
                }
            }
        }
        public void OnnxModelMultiInput()
        {
            var modelFile = Path.Combine(Directory.GetCurrentDirectory(), "twoinput", "twoinput.onnx");

            using (var env = new ConsoleEnvironment(seed: 1, conc: 1))
            {
                var samplevector = GetSampleArrayData();

                var dataView = ML.Data.ReadFromEnumerable(
                    new TestDataMulti[] {
                    new TestDataMulti()
                    {
                        ina = new float[] { 1, 2, 3, 4, 5 },
                        inb = new float[] { 1, 2, 3, 4, 5 }
                    }
                });
                var onnx = new OnnxTransformer(env, new[] { "outa", "outb" }, new[] { "ina", "inb" }, modelFile).Transform(dataView);

                onnx.Schema.TryGetColumnIndex("outa", out int scoresa);
                onnx.Schema.TryGetColumnIndex("outb", out int scoresb);
                using (var curs = onnx.GetRowCursor(onnx.Schema["outa"], onnx.Schema["outb"]))
                {
                    var getScoresa = curs.GetGetter <VBuffer <float> >(scoresa);
                    var getScoresb = curs.GetGetter <VBuffer <float> >(scoresb);
                    var buffera    = default(VBuffer <float>);
                    var bufferb    = default(VBuffer <float>);

                    while (curs.MoveNext())
                    {
                        getScoresa(ref buffera);
                        getScoresb(ref bufferb);
                        Assert.Equal(5, buffera.Length);
                        Assert.Equal(5, bufferb.Length);
                        Assert.Equal(0, buffera.GetValues().ToArray().Sum());
                        Assert.Equal(30, bufferb.GetValues().ToArray().Sum());
                    }
                }
            }
        }
예제 #6
0
        [ConditionalFact(typeof(Environment), nameof(Environment.Is64BitProcess))] // x86 output differs from Baseline
        public void OnnxModelScenario()
        {
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                return;
            }

            var modelFile = "squeezenet/00000001/model.onnx";

            using (var env = new ConsoleEnvironment(seed: 1, conc: 1))
            {
                var samplevector = GetSampleArrayData();

                var dataView = ComponentCreation.CreateDataView(Env,
                                                                new TestData[] {
                    new TestData()
                    {
                        data_0 = samplevector
                    }
                });

                var onnx = new OnnxTransformer(env, modelFile, "data_0", "softmaxout_1").Transform(dataView);

                onnx.Schema.TryGetColumnIndex("softmaxout_1", out int score);

                using (var curs = onnx.GetRowCursor(onnx.Schema["softmaxout_1"]))
                {
                    var getScores = curs.GetGetter <VBuffer <float> >(score);
                    var buffer    = default(VBuffer <float>);
                    while (curs.MoveNext())
                    {
                        getScores(ref buffer);
                        Assert.Equal(1000, buffer.Length);
                    }
                }
            }
        }
예제 #7
0
        public void TestOnnxTransformWithCustomShapes()
        {
            // The loaded model has input shape [-1, 3] and output shape [-1].
            var modelFile = Path.Combine(Directory.GetCurrentDirectory(), "unknowndimensions", "test_unknowndimensions_float.onnx");

            var dataPoints = new InputWithCustomShape[]
            {
                // It's a flattened 3-by-3 tensor.
                // [1.1, 1.3, 1.2]
                // |1.9, 1.3, 1.2|
                // [1.1, 1.3, 1.8]
                new InputWithCustomShape()
                {
                    input = new float[] { 1.1f, 1.3f, 1.2f, 1.9f, 1.3f, 1.2f, 1.1f, 1.3f, 1.8f }
                },
                // It's a flattened 3-by-3 tensor.
                // [0, 0, 1]
                // |1, 0, 0|
                // [1, 0, 0]
                new InputWithCustomShape()
                {
                    input = new float[] { 0f, 0f, 1f, 1f, 0f, 0f, 1f, 0f, 0f }
                }
            };

            var shapeDictionary = new Dictionary <string, int[]>()
            {
                { nameof(InputWithCustomShape.input), new int[] { 3, 3 } }
            };

            var dataView = ML.Data.LoadFromEnumerable(dataPoints);

            var pipeline             = new OnnxScoringEstimator[3];
            var onnxTransformer      = new OnnxTransformer[3];
            var transformedDataViews = new IDataView[3];

            // Test three public ONNX APIs with the custom shape.

            // Test 1.
            pipeline[0] = ML.Transforms.ApplyOnnxModel(
                new[] { nameof(PredictionWithCustomShape.argmax) }, new[] { nameof(InputWithCustomShape.input) },
                modelFile, shapeDictionary);
            onnxTransformer[0]      = pipeline[0].Fit(dataView);
            transformedDataViews[0] = onnxTransformer[0].Transform(dataView);

            // Test 2.
            pipeline[1] = ML.Transforms.ApplyOnnxModel(
                nameof(PredictionWithCustomShape.argmax), nameof(InputWithCustomShape.input),
                modelFile, shapeDictionary);
            onnxTransformer[1]      = pipeline[1].Fit(dataView);
            transformedDataViews[1] = onnxTransformer[1].Transform(dataView);

            // Test 3.
            pipeline[2]             = ML.Transforms.ApplyOnnxModel(modelFile, shapeDictionary);
            onnxTransformer[2]      = pipeline[2].Fit(dataView);
            transformedDataViews[2] = onnxTransformer[2].Transform(dataView);

            // Conduct the same check for all the 3 called public APIs.
            foreach (var transformedDataView in transformedDataViews)
            {
                var transformedDataPoints = ML.Data.CreateEnumerable <PredictionWithCustomShape>(transformedDataView, false).ToList();

                // One data point generates one transformed data point.
                Assert.Equal(dataPoints.Count(), transformedDataPoints.Count);

                // Check result numbers. They are results of applying ONNX argmax along the second axis; for example
                // [1.1, 1.3, 1.2] ---> [1] because 1.3 (indexed by 1) is the largest element.
                // |1.9, 1.3, 1.2| ---> |0|         1.9             0
                // [1.1, 1.3, 1.8] ---> [2]         1.8             2
                var expectedResults = new long[][]
                {
                    new long[] { 1, 0, 2 },
                    new long[] { 2, 0, 0 }
                };

                for (int i = 0; i < transformedDataPoints.Count; ++i)
                {
                    Assert.Equal(transformedDataPoints[i].argmax, expectedResults[i]);
                }
            }
            for (int i = 0; i < 3; i++)
            {
                (onnxTransformer[i] as IDisposable)?.Dispose();
            }
        }
예제 #8
0
 /// <summary>
 /// Initializes a new instance of <see cref="OnnxScoringEstimator"/>.
 /// </summary>
 /// <param name="catalog">The transform's catalog.</param>
 /// <param name="transformer">The ONNX transformer.</param>
 public static OnnxScoringEstimator ApplyOnnxModel(this TransformsCatalog catalog, OnnxTransformer transformer)
 => new OnnxScoringEstimator(CatalogUtils.GetEnvironment(catalog), transformer);