Skip to content

Allow user to overwrite unknown shapes loaded from ONNX model #3963

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 6, 2019

Conversation

wschin
Copy link
Member

@wschin wschin commented Jul 3, 2019

This PR adds an extra argument to ApplyOnnxModel functions.

        /// <param name="shapeDictionary">ONNX shape should be used to over those loaded from <paramref name="modelFile"/>.</param>

If a key-value pair, (tensor_name, [1, 2, 3]) exists, the tensor_name's shape loaded from ONNX model file will be replaced by [1, 2, 3]. It's allows user to replace unknown shapes in their applications.

Fix #3932.

With this PR, FasterRCNN mentioned in #3932 can be run as the example below.

        private class RcnnInput
        {
            [ColumnName("image")]
            [VectorType(3, 224, 224)]
            public float[] Input { get; set; }
        }

        private class RcnnOutput
        {
            [ColumnName("6379")]
            public float[] Boxes { get; set; }

            [ColumnName("6381")]
            public long[] Label { get; set; } 

            [ColumnName("6383")]
            public float[] Score { get; set; }
        }

        static public IEnumerable<float> GenerateRandomVector(int size)
        {
            var rnd = new Random(0);

            for (int i = 0; i < size; ++i)
                yield return rnd.NextSingle();
        }

        /// <summary>
        /// A test to check if dynamic shape works.
        /// </summary>
        [OnnxFact]
        public void TestOnnxTransformDynamicShape()
        {
            var modelFile = Path.Combine(Directory.GetCurrentDirectory(), "fasterRCNN", "faster_rcnn_R_50_FPN_1x.onnx");

            var dataPoints = new RcnnInput[] {
                new RcnnInput() { Input = GenerateRandomVector(3 * 224 * 224).ToArray(), }
            };

            var shapeDictionary = new Dictionary<string, int[]>() { { "image", new int[] { 3, 224, 224 } } };

            var dataView = ML.Data.LoadFromEnumerable(dataPoints);
            var transformedDataView = ML.Transforms.ApplyOnnxModel(new[] { "6379", "6381", "6383" }, new[] { "image" }, modelFile,
                shapeDictionary: shapeDictionary).Fit(dataView).Transform(dataView);

            // Convert IDataView to IEnumerable<ZipMapOutput> and then inspect the values.
            var transformedDataPoints = ML.Data.CreateEnumerable<RcnnOutput>(transformedDataView, false).ToList();

            for (int i = 0; i < transformedDataPoints.Count; ++i)
            {
                Assert.NotNull(transformedDataPoints[i].Boxes);
                Assert.NotNull(transformedDataPoints[i].Label);
                Assert.NotNull(transformedDataPoints[i].Score);
            }
        }

@@ -226,36 +328,17 @@ private static IRowMapper Create(IHostEnvironment env, ModelLoadContext ctx, Dat
/// <param name="modelFile">Model file path.</param>
/// <param name="gpuDeviceId">Optional GPU device ID to run execution on. Null for CPU.</param>
/// <param name="fallbackToCpu">If GPU error, raise exception or fallback to CPU.</param>
internal OnnxTransformer(IHostEnvironment env, string modelFile, int? gpuDeviceId = null, bool fallbackToCpu = false)
Copy link
Member Author

@wschin wschin Jul 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ctor is not used at all, so I removed it. #Resolved

Add a command line test

Remove unused code
@wschin wschin requested review from jignparm, artidoro and codemzs July 3, 2019 22:16
@wschin wschin self-assigned this Jul 3, 2019
=> new OnnxScoringEstimator(CatalogUtils.GetEnvironment(catalog), modelFile, gpuDeviceId, fallbackToCpu);
bool fallbackToCpu = false,
IDictionary<string, int[]> shapeDictionary = null)
=> new OnnxScoringEstimator(CatalogUtils.GetEnvironment(catalog), modelFile, gpuDeviceId, fallbackToCpu,
Copy link
Contributor

@artidoro artidoro Jul 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be a breaking change. I am afraid API compat is not active for this assembly. I will open an issue about it and fix it in the meantime.
Unfortunately the signature of the function changes if you add another parameter. The only way to do this change without being a breaking change is to add a new overload with the new parameter. #Resolved

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already a PR on reactivating API compat, could you approve it and rebase afterwards?


In reply to: 301718819 [](ancestors = 301718819)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Thanks.


In reply to: 301768225 [](ancestors = 301768225,301718819)

@artidoro
Copy link
Contributor

artidoro commented Jul 9, 2019

    private protected override void SaveModel(ModelSaveContext ctx)

Why are we not saving the ShapeDictionary here?
It seems like we will lose that information. #Resolved


Refers to: src/Microsoft.ML.OnnxTransformer/OnnxTransform.cs:307 in ced8c42. [](commit_id = ced8c42, deletion_comment = False)

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");
Copy link
Contributor

@artidoro artidoro Jul 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_unknowndimensions_float [](start = 96, length = 28)

nit: Could we use CSharp style for file names?
If that was the original name of the model, maybe it's fine like this. #ByDesign

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in another repo and I feel it looks just fine.


In reply to: 301724967 [](ancestors = 301724967)

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");
Copy link
Contributor

@artidoro artidoro Jul 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_unknowndimensions_float [](start = 96, length = 28)

Could you add a link to the description of the onnx model this test is using? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no such a description for those internal ONNX models but I can add a link to its source.


In reply to: 301726035 [](ancestors = 301726035)

/// </summary>
/// <param name="shapeDictionary">Dictionary of tensor shapes. Keys are tensor names
/// while values the associated shapes.</param>
private void TryModwlWithCustomShapesHelper(IDictionary<string, int[]> shapeDictionary)
Copy link
Contributor

@artidoro artidoro Jul 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TryModwlWithCustomShapesHelper [](start = 21, length = 30)

I think there might be a small typo: Modwl -> Model #Resolved

@wschin
Copy link
Member Author

wschin commented Jul 10, 2019

    private protected override void SaveModel(ModelSaveContext ctx)

Fixed and added a test.


In reply to: 509748317 [](ancestors = 509748317)


Refers to: src/Microsoft.ML.OnnxTransformer/OnnxTransform.cs:307 in ced8c42. [](commit_id = ced8c42, deletion_comment = False)

@artidoro
Copy link
Contributor

            verWrittenCur: 0x00010002,

Should we change the version number since we are changing the binary format of how it is saved?


Refers to: src/Microsoft.ML.OnnxTransformer/OnnxTransform.cs:155 in ab6424c. [](commit_id = ab6424c, deletion_comment = False)

@artidoro
Copy link
Contributor

    {

It would be very nice to have in a comment the layout of the binary format like we do in other transformers.
It's not a blocking issue though I think it would be very nice to have :)
If you do add it, you could write it in the load method above too.


Refers to: src/Microsoft.ML.OnnxTransformer/OnnxTransform.cs:327 in ab6424c. [](commit_id = ab6424c, deletion_comment = False)

Copy link
Member

@codemzs codemzs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

cannot use fasterrcnn onnx model in c# ap
3 participants