diff --git a/src/Microsoft.ML.OnnxConverter/SaveOnnxCommand.cs b/src/Microsoft.ML.OnnxConverter/SaveOnnxCommand.cs index 966fe255f4..a2aa961b22 100644 --- a/src/Microsoft.ML.OnnxConverter/SaveOnnxCommand.cs +++ b/src/Microsoft.ML.OnnxConverter/SaveOnnxCommand.cs @@ -201,7 +201,7 @@ internal static ModelProto ConvertTransformListToOnnxModel(OnnxContextImpl ctx, ch.Check(variableName != null, "The targeted pipeline can not be fully converted into a well-defined ONNX model. " + "Please check if all steps in that pipeline are convertible to ONNX " + "and all necessary variables are not dropped (via command line arguments)."); - var trueVariableName = ctx.AddIntermediateVariable(null, idataviewColumnName + ".onnx", true); + var trueVariableName = ctx.AddIntermediateVariable(null, idataviewColumnName + ".output", true); ctx.CreateNode("Identity", variableName, trueVariableName, ctx.GetNodeName("Identity"), ""); ctx.AddOutputVariable(outputData.Schema[i].Type, trueVariableName); } diff --git a/src/Microsoft.ML.OnnxTransformer/OnnxTransform.cs b/src/Microsoft.ML.OnnxTransformer/OnnxTransform.cs index 60d82c6a76..fd213845b4 100644 --- a/src/Microsoft.ML.OnnxTransformer/OnnxTransform.cs +++ b/src/Microsoft.ML.OnnxTransformer/OnnxTransform.cs @@ -410,9 +410,14 @@ public Mapper(OnnxTransformer parent, DataViewSchema inputSchema) : protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() { + var stdSuffix = ".output"; var info = new DataViewSchema.DetachedColumn[_parent.Outputs.Length]; for (int i = 0; i < _parent.Outputs.Length; i++) - info[i] = new DataViewSchema.DetachedColumn(_parent.Outputs[i], _parent.OutputTypes[i], null); + { + var onnxOutputName = _parent.Outputs[i]; + var columnName = onnxOutputName.EndsWith(stdSuffix) ? onnxOutputName.Replace(stdSuffix, "") : onnxOutputName; + info[i] = new DataViewSchema.DetachedColumn(columnName, _parent.OutputTypes[i], null); + } return info; } diff --git a/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/ExcludeVariablesInOnnxConversion.txt b/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/ExcludeVariablesInOnnxConversion.txt index d37a3a39db..7b0036d538 100644 --- a/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/ExcludeVariablesInOnnxConversion.txt +++ b/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/ExcludeVariablesInOnnxConversion.txt @@ -450,7 +450,7 @@ "PredictedLabel" ], "output": [ - "PredictedLabel.onnx" + "PredictedLabel.output" ], "name": "Identity", "opType": "Identity" @@ -460,7 +460,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity0", "opType": "Identity" @@ -470,7 +470,7 @@ "Probability" ], "output": [ - "Probability.onnx" + "Probability.output" ], "name": "Identity1", "opType": "Identity" @@ -533,7 +533,7 @@ ], "output": [ { - "name": "PredictedLabel.onnx", + "name": "PredictedLabel.output", "type": { "tensorType": { "elemType": 9, @@ -551,7 +551,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, @@ -569,7 +569,7 @@ } }, { - "name": "Probability.onnx", + "name": "Probability.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/LightGbmBinaryClassificationOnnxConversionTest.txt b/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/LightGbmBinaryClassificationOnnxConversionTest.txt index 9d3ac3fd55..8bac688f71 100644 --- a/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/LightGbmBinaryClassificationOnnxConversionTest.txt +++ b/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/LightGbmBinaryClassificationOnnxConversionTest.txt @@ -360,7 +360,7 @@ "FeatureVector0" ], "output": [ - "FeatureVector.onnx" + "FeatureVector.output" ], "name": "Identity", "opType": "Identity" @@ -370,7 +370,7 @@ "Target" ], "output": [ - "Target.onnx" + "Target.output" ], "name": "Identity0", "opType": "Identity" @@ -380,7 +380,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -427,7 +427,7 @@ ], "output": [ { - "name": "FeatureVector.onnx", + "name": "FeatureVector.output", "type": { "tensorType": { "elemType": 1, @@ -445,7 +445,7 @@ } }, { - "name": "Target.onnx", + "name": "Target.output", "type": { "tensorType": { "elemType": 1, @@ -463,7 +463,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/LogisticRegressionSaveModelToOnnxTest.txt b/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/LogisticRegressionSaveModelToOnnxTest.txt index 253b2ed684..f41b69f8c4 100644 --- a/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/LogisticRegressionSaveModelToOnnxTest.txt +++ b/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/LogisticRegressionSaveModelToOnnxTest.txt @@ -104,7 +104,7 @@ "FeatureVector0" ], "output": [ - "FeatureVector.onnx" + "FeatureVector.output" ], "name": "Identity", "opType": "Identity" @@ -114,7 +114,7 @@ "Target" ], "output": [ - "Target.onnx" + "Target.output" ], "name": "Identity0", "opType": "Identity" @@ -124,7 +124,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -171,7 +171,7 @@ ], "output": [ { - "name": "FeatureVector.onnx", + "name": "FeatureVector.output", "type": { "tensorType": { "elemType": 1, @@ -189,7 +189,7 @@ } }, { - "name": "Target.onnx", + "name": "Target.output", "type": { "tensorType": { "elemType": 1, @@ -207,7 +207,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/ModelWithLessIO.txt b/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/ModelWithLessIO.txt index 22273e89f4..e265a3b7c9 100644 --- a/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/ModelWithLessIO.txt +++ b/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/ModelWithLessIO.txt @@ -677,27 +677,27 @@ "floats": [ -0.9850374, -1, - -0.428571433, + -0.42857143, 0.05882353, 0.9655172, - 0.478260875, - 7.006492E-45, + 0.47826087, + 7E-45, 0.9354839, -0.837172, - -0.896625638, + -0.89662564, -0.3455931, - 0.223126009, + 0.22312601, 0.8040303, 0.60825175, -0.06932944, - -0.402043074, + -0.40204307, -0.7417274, - -0.408434927, + -0.40843493, 0.7105746, 0.1875386, 0.7631735, - 0.706173241, - 0.625906467, + 0.70617324, + 0.62590647, -0.35968104 ], "type": "FLOATS" @@ -776,7 +776,7 @@ "PredictedLabel" ], "output": [ - "PredictedLabel.onnx" + "PredictedLabel.output" ], "name": "Identity", "opType": "Identity" @@ -786,7 +786,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity0", "opType": "Identity" @@ -796,7 +796,7 @@ "Probability" ], "output": [ - "Probability.onnx" + "Probability.output" ], "name": "Identity1", "opType": "Identity" @@ -859,7 +859,7 @@ ], "output": [ { - "name": "PredictedLabel.onnx", + "name": "PredictedLabel.output", "type": { "tensorType": { "elemType": 9, @@ -877,7 +877,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, @@ -895,7 +895,7 @@ } }, { - "name": "Probability.onnx", + "name": "Probability.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/OneHotBagPipeline.txt b/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/OneHotBagPipeline.txt index 6822e97818..93550ceda7 100644 --- a/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/OneHotBagPipeline.txt +++ b/test/BaselineOutput/Common/Onnx/BinaryClassification/BreastCancer/OneHotBagPipeline.txt @@ -324,8 +324,8 @@ { "name": "target_weights", "floats": [ - 0.504761934, - -0.979112267 + 0.50476193, + -0.97911227 ], "type": "FLOATS" } @@ -403,7 +403,7 @@ "Label" ], "output": [ - "Label.onnx" + "Label.output" ], "name": "Identity", "opType": "Identity" @@ -413,7 +413,7 @@ "F1" ], "output": [ - "F1.onnx" + "F1.output" ], "name": "Identity0", "opType": "Identity" @@ -423,7 +423,7 @@ "F22" ], "output": [ - "F2.onnx" + "F2.output" ], "name": "Identity1", "opType": "Identity" @@ -433,7 +433,7 @@ "Features" ], "output": [ - "Features.onnx" + "Features.output" ], "name": "Identity2", "opType": "Identity" @@ -443,7 +443,7 @@ "PredictedLabel" ], "output": [ - "PredictedLabel.onnx" + "PredictedLabel.output" ], "name": "Identity3", "opType": "Identity" @@ -453,7 +453,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity4", "opType": "Identity" @@ -463,7 +463,7 @@ "Probability" ], "output": [ - "Probability.onnx" + "Probability.output" ], "name": "Identity5", "opType": "Identity" @@ -544,7 +544,7 @@ ], "output": [ { - "name": "Label.onnx", + "name": "Label.output", "type": { "tensorType": { "elemType": 9, @@ -562,7 +562,7 @@ } }, { - "name": "F1.onnx", + "name": "F1.output", "type": { "tensorType": { "elemType": 1, @@ -580,7 +580,7 @@ } }, { - "name": "F2.onnx", + "name": "F2.output", "type": { "tensorType": { "elemType": 1, @@ -598,7 +598,7 @@ } }, { - "name": "Features.onnx", + "name": "Features.output", "type": { "tensorType": { "elemType": 1, @@ -616,7 +616,7 @@ } }, { - "name": "PredictedLabel.onnx", + "name": "PredictedLabel.output", "type": { "tensorType": { "elemType": 9, @@ -634,7 +634,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, @@ -652,7 +652,7 @@ } }, { - "name": "Probability.onnx", + "name": "Probability.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/Cluster/BreastCancer/Kmeans.txt b/test/BaselineOutput/Common/Onnx/Cluster/BreastCancer/Kmeans.txt index 2aa042f0a8..68fbc19f19 100644 --- a/test/BaselineOutput/Common/Onnx/Cluster/BreastCancer/Kmeans.txt +++ b/test/BaselineOutput/Common/Onnx/Cluster/BreastCancer/Kmeans.txt @@ -148,7 +148,7 @@ "Features0" ], "output": [ - "Features.onnx" + "Features.output" ], "name": "Identity", "opType": "Identity" @@ -158,7 +158,7 @@ "PredictedLabel" ], "output": [ - "PredictedLabel.onnx" + "PredictedLabel.output" ], "name": "Identity0", "opType": "Identity" @@ -168,7 +168,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -268,7 +268,7 @@ ], "output": [ { - "name": "Features.onnx", + "name": "Features.output", "type": { "tensorType": { "elemType": 1, @@ -286,7 +286,7 @@ } }, { - "name": "PredictedLabel.onnx", + "name": "PredictedLabel.output", "type": { "tensorType": { "elemType": 12, @@ -304,7 +304,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/MultiClassClassification/BreastCancer/MultiClassificationLogisticRegressionSaveModelToOnnxTest.txt b/test/BaselineOutput/Common/Onnx/MultiClassClassification/BreastCancer/MultiClassificationLogisticRegressionSaveModelToOnnxTest.txt index 9840c142ec..ab04e5921f 100644 --- a/test/BaselineOutput/Common/Onnx/MultiClassClassification/BreastCancer/MultiClassificationLogisticRegressionSaveModelToOnnxTest.txt +++ b/test/BaselineOutput/Common/Onnx/MultiClassClassification/BreastCancer/MultiClassificationLogisticRegressionSaveModelToOnnxTest.txt @@ -288,7 +288,7 @@ "Label0" ], "output": [ - "Label.onnx" + "Label.output" ], "name": "Identity", "opType": "Identity" @@ -298,7 +298,7 @@ "Features0" ], "output": [ - "Features.onnx" + "Features.output" ], "name": "Identity0", "opType": "Identity" @@ -308,7 +308,7 @@ "PredictedLabel" ], "output": [ - "PredictedLabel.onnx" + "PredictedLabel.output" ], "name": "Identity1", "opType": "Identity" @@ -318,7 +318,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity2", "opType": "Identity" @@ -378,7 +378,7 @@ ], "output": [ { - "name": "Label.onnx", + "name": "Label.output", "type": { "tensorType": { "elemType": 12, @@ -396,7 +396,7 @@ } }, { - "name": "Features.onnx", + "name": "Features.output", "type": { "tensorType": { "elemType": 1, @@ -414,7 +414,7 @@ } }, { - "name": "PredictedLabel.onnx", + "name": "PredictedLabel.output", "type": { "tensorType": { "elemType": 12, @@ -432,7 +432,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastForestRegressionTrainer.txt b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastForestRegressionTrainer.txt index 35318c2259..3605f27cb9 100644 --- a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastForestRegressionTrainer.txt +++ b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastForestRegressionTrainer.txt @@ -39328,7 +39328,7 @@ "FeatureVector" ], "output": [ - "FeatureVector.onnx" + "FeatureVector.output" ], "name": "Identity", "opType": "Identity" @@ -39338,7 +39338,7 @@ "Target" ], "output": [ - "Target.onnx" + "Target.output" ], "name": "Identity0", "opType": "Identity" @@ -39348,7 +39348,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -39404,7 +39404,7 @@ ], "output": [ { - "name": "FeatureVector.onnx", + "name": "FeatureVector.output", "type": { "tensorType": { "elemType": 1, @@ -39422,7 +39422,7 @@ } }, { - "name": "Target.onnx", + "name": "Target.output", "type": { "tensorType": { "elemType": 1, @@ -39440,7 +39440,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastTreeRegressionTrainer.txt b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastTreeRegressionTrainer.txt index 0f2430bcb4..f82fc040dd 100644 --- a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastTreeRegressionTrainer.txt +++ b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastTreeRegressionTrainer.txt @@ -39317,7 +39317,7 @@ "FeatureVector" ], "output": [ - "FeatureVector.onnx" + "FeatureVector.output" ], "name": "Identity", "opType": "Identity" @@ -39327,7 +39327,7 @@ "Target" ], "output": [ - "Target.onnx" + "Target.output" ], "name": "Identity0", "opType": "Identity" @@ -39337,7 +39337,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -39384,7 +39384,7 @@ ], "output": [ { - "name": "FeatureVector.onnx", + "name": "FeatureVector.output", "type": { "tensorType": { "elemType": 1, @@ -39402,7 +39402,7 @@ } }, { - "name": "Target.onnx", + "name": "Target.output", "type": { "tensorType": { "elemType": 1, @@ -39420,7 +39420,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastTreeTweedieTrainer.txt b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastTreeTweedieTrainer.txt index f3d53a2e14..1526d48766 100644 --- a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastTreeTweedieTrainer.txt +++ b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.FastTree.FastTreeTweedieTrainer.txt @@ -39327,7 +39327,7 @@ "FeatureVector" ], "output": [ - "FeatureVector.onnx" + "FeatureVector.output" ], "name": "Identity", "opType": "Identity" @@ -39337,7 +39337,7 @@ "Target" ], "output": [ - "Target.onnx" + "Target.output" ], "name": "Identity0", "opType": "Identity" @@ -39347,7 +39347,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -39394,7 +39394,7 @@ ], "output": [ { - "name": "FeatureVector.onnx", + "name": "FeatureVector.output", "type": { "tensorType": { "elemType": 1, @@ -39412,7 +39412,7 @@ } }, { - "name": "Target.onnx", + "name": "Target.output", "type": { "tensorType": { "elemType": 1, @@ -39430,7 +39430,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.LbfgsPoissonRegressionTrainer.txt b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.LbfgsPoissonRegressionTrainer.txt index d6528e1225..feee35fcee 100644 --- a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.LbfgsPoissonRegressionTrainer.txt +++ b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.LbfgsPoissonRegressionTrainer.txt @@ -29,15 +29,15 @@ "name": "coefficients", "floats": [ 0.2037472, - 0.005167962, + 0.00516796159, 0.1929681, - 0.01041878, - -0.000658446748, - 0.00338159036, - 0.0447585769, - 0.00602663541, - 0.00161118619, - -0.00189642713, + 0.0104187969, + -0.0006584526, + 0.00338159618, + 0.0447585955, + 0.00602662656, + 0.00161118712, + -0.0018964255, 0.2229219 ], "type": "FLOATS" @@ -67,7 +67,7 @@ "FeatureVector" ], "output": [ - "FeatureVector.onnx" + "FeatureVector.output" ], "name": "Identity", "opType": "Identity" @@ -77,7 +77,7 @@ "Target" ], "output": [ - "Target.onnx" + "Target.output" ], "name": "Identity0", "opType": "Identity" @@ -87,7 +87,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -134,7 +134,7 @@ ], "output": [ { - "name": "FeatureVector.onnx", + "name": "FeatureVector.output", "type": { "tensorType": { "elemType": 1, @@ -152,7 +152,7 @@ } }, { - "name": "Target.onnx", + "name": "Target.output", "type": { "tensorType": { "elemType": 1, @@ -170,7 +170,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.LightGbm.LightGbmRegressionTrainer.txt b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.LightGbm.LightGbmRegressionTrainer.txt index 3f198e12ed..5da774f9c7 100644 --- a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.LightGbm.LightGbmRegressionTrainer.txt +++ b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.LightGbm.LightGbmRegressionTrainer.txt @@ -38277,7 +38277,7 @@ "FeatureVector" ], "output": [ - "FeatureVector.onnx" + "FeatureVector.output" ], "name": "Identity", "opType": "Identity" @@ -38287,7 +38287,7 @@ "Target" ], "output": [ - "Target.onnx" + "Target.output" ], "name": "Identity0", "opType": "Identity" @@ -38297,7 +38297,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -38344,7 +38344,7 @@ ], "output": [ { - "name": "FeatureVector.onnx", + "name": "FeatureVector.output", "type": { "tensorType": { "elemType": 1, @@ -38362,7 +38362,7 @@ } }, { - "name": "Target.onnx", + "name": "Target.output", "type": { "tensorType": { "elemType": 1, @@ -38380,7 +38380,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.OlsTrainer.txt b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.OlsTrainer.txt index cf2a05ff38..eb0d9bc0ca 100644 --- a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.OlsTrainer.txt +++ b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.OlsTrainer.txt @@ -57,7 +57,7 @@ "FeatureVector" ], "output": [ - "FeatureVector.onnx" + "FeatureVector.output" ], "name": "Identity", "opType": "Identity" @@ -67,7 +67,7 @@ "Target" ], "output": [ - "Target.onnx" + "Target.output" ], "name": "Identity0", "opType": "Identity" @@ -77,7 +77,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -124,7 +124,7 @@ ], "output": [ { - "name": "FeatureVector.onnx", + "name": "FeatureVector.output", "type": { "tensorType": { "elemType": 1, @@ -142,7 +142,7 @@ } }, { - "name": "Target.onnx", + "name": "Target.output", "type": { "tensorType": { "elemType": 1, @@ -160,7 +160,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.OnlineGradientDescentTrainer.txt b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.OnlineGradientDescentTrainer.txt index 572cf6fac3..209b5f0924 100644 --- a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.OnlineGradientDescentTrainer.txt +++ b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.OnlineGradientDescentTrainer.txt @@ -57,7 +57,7 @@ "FeatureVector" ], "output": [ - "FeatureVector.onnx" + "FeatureVector.output" ], "name": "Identity", "opType": "Identity" @@ -67,7 +67,7 @@ "Target" ], "output": [ - "Target.onnx" + "Target.output" ], "name": "Identity0", "opType": "Identity" @@ -77,7 +77,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -124,7 +124,7 @@ ], "output": [ { - "name": "FeatureVector.onnx", + "name": "FeatureVector.output", "type": { "tensorType": { "elemType": 1, @@ -142,7 +142,7 @@ } }, { - "name": "Target.onnx", + "name": "Target.output", "type": { "tensorType": { "elemType": 1, @@ -160,7 +160,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.SdcaRegressionTrainer.txt b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.SdcaRegressionTrainer.txt index 62afef40c6..8f8bb14e77 100644 --- a/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.SdcaRegressionTrainer.txt +++ b/test/BaselineOutput/Common/Onnx/Regression/Adult/Microsoft.ML.Trainers.SdcaRegressionTrainer.txt @@ -28,24 +28,24 @@ { "name": "coefficients", "floats": [ - 77.0586548, - 0.008821458, - 74.8481, - -0.0400403664, - -0.0316747874, - 0.0483982079, - 19.31359, - 3.932647, - 0.0116912266, - 0.09054199, - 82.77022 + 77.06203, + 0.00723217, + 74.84655, + -0.0392755158, + -0.03449215, + 0.0474231839, + 19.3112488, + 3.93133354, + 0.008931219, + 0.09011991, + 82.76908 ], "type": "FLOATS" }, { "name": "intercepts", "floats": [ - 373.88443 + 373.885468 ], "type": "FLOATS" } @@ -57,7 +57,7 @@ "FeatureVector" ], "output": [ - "FeatureVector.onnx" + "FeatureVector.output" ], "name": "Identity", "opType": "Identity" @@ -67,7 +67,7 @@ "Target" ], "output": [ - "Target.onnx" + "Target.output" ], "name": "Identity0", "opType": "Identity" @@ -77,7 +77,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -124,7 +124,7 @@ ], "output": [ { - "name": "FeatureVector.onnx", + "name": "FeatureVector.output", "type": { "tensorType": { "elemType": 1, @@ -142,7 +142,7 @@ } }, { - "name": "Target.onnx", + "name": "Target.output", "type": { "tensorType": { "elemType": 1, @@ -160,7 +160,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/Regression/Adult/SimplePipeline.txt b/test/BaselineOutput/Common/Onnx/Regression/Adult/SimplePipeline.txt index 253b2ed684..f41b69f8c4 100644 --- a/test/BaselineOutput/Common/Onnx/Regression/Adult/SimplePipeline.txt +++ b/test/BaselineOutput/Common/Onnx/Regression/Adult/SimplePipeline.txt @@ -104,7 +104,7 @@ "FeatureVector0" ], "output": [ - "FeatureVector.onnx" + "FeatureVector.output" ], "name": "Identity", "opType": "Identity" @@ -114,7 +114,7 @@ "Target" ], "output": [ - "Target.onnx" + "Target.output" ], "name": "Identity0", "opType": "Identity" @@ -124,7 +124,7 @@ "Score" ], "output": [ - "Score.onnx" + "Score.output" ], "name": "Identity1", "opType": "Identity" @@ -171,7 +171,7 @@ ], "output": [ { - "name": "FeatureVector.onnx", + "name": "FeatureVector.output", "type": { "tensorType": { "elemType": 1, @@ -189,7 +189,7 @@ } }, { - "name": "Target.onnx", + "name": "Target.output", "type": { "tensorType": { "elemType": 1, @@ -207,7 +207,7 @@ } }, { - "name": "Score.onnx", + "name": "Score.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/BaselineOutput/Common/Onnx/Transforms/IndicateMissingValues.txt b/test/BaselineOutput/Common/Onnx/Transforms/IndicateMissingValues.txt index f13191abe4..ec818ec7c6 100644 --- a/test/BaselineOutput/Common/Onnx/Transforms/IndicateMissingValues.txt +++ b/test/BaselineOutput/Common/Onnx/Transforms/IndicateMissingValues.txt @@ -37,7 +37,7 @@ "Features" ], "output": [ - "Features.onnx" + "Features.output" ], "name": "Identity", "opType": "Identity" @@ -47,7 +47,7 @@ "MissingIndicator0" ], "output": [ - "MissingIndicator.onnx" + "MissingIndicator.output" ], "name": "Identity0", "opType": "Identity" @@ -76,7 +76,7 @@ ], "output": [ { - "name": "Features.onnx", + "name": "Features.output", "type": { "tensorType": { "elemType": 1, @@ -94,7 +94,7 @@ } }, { - "name": "MissingIndicator.onnx", + "name": "MissingIndicator.output", "type": { "tensorType": { "elemType": 6, diff --git a/test/BaselineOutput/Common/Onnx/Transforms/SelectColumns.txt b/test/BaselineOutput/Common/Onnx/Transforms/SelectColumns.txt index aa5cc455dd..06351fe136 100644 --- a/test/BaselineOutput/Common/Onnx/Transforms/SelectColumns.txt +++ b/test/BaselineOutput/Common/Onnx/Transforms/SelectColumns.txt @@ -75,7 +75,7 @@ "Size1" ], "output": [ - "Size.onnx" + "Size.output" ], "name": "Identity3", "opType": "Identity" @@ -85,7 +85,7 @@ "Shape0" ], "output": [ - "Shape.onnx" + "Shape.output" ], "name": "Identity4", "opType": "Identity" @@ -95,7 +95,7 @@ "Thickness0" ], "output": [ - "Thickness.onnx" + "Thickness.output" ], "name": "Identity5", "opType": "Identity" @@ -105,7 +105,7 @@ "Label0" ], "output": [ - "Label.onnx" + "Label.output" ], "name": "Identity6", "opType": "Identity" @@ -278,7 +278,7 @@ ], "output": [ { - "name": "Size.onnx", + "name": "Size.output", "type": { "tensorType": { "elemType": 1, @@ -296,7 +296,7 @@ } }, { - "name": "Shape.onnx", + "name": "Shape.output", "type": { "tensorType": { "elemType": 6, @@ -314,7 +314,7 @@ } }, { - "name": "Thickness.onnx", + "name": "Thickness.output", "type": { "tensorType": { "elemType": 11, @@ -332,7 +332,7 @@ } }, { - "name": "Label.onnx", + "name": "Label.output", "type": { "tensorType": { "elemType": 9, diff --git a/test/BaselineOutput/Common/Onnx/Transforms/Sentiment/SmallWordEmbed.txt b/test/BaselineOutput/Common/Onnx/Transforms/Sentiment/SmallWordEmbed.txt index 6d1786e598..9a116d6cf8 100644 --- a/test/BaselineOutput/Common/Onnx/Transforms/Sentiment/SmallWordEmbed.txt +++ b/test/BaselineOutput/Common/Onnx/Transforms/Sentiment/SmallWordEmbed.txt @@ -345,7 +345,7 @@ "Tokens" ], "output": [ - "Tokens.onnx" + "Tokens.output" ], "name": "Identity", "opType": "Identity" @@ -355,7 +355,7 @@ "Embed" ], "output": [ - "Embed.onnx" + "Embed.output" ], "name": "Identity0", "opType": "Identity" @@ -1053,7 +1053,7 @@ ], "output": [ { - "name": "Tokens.onnx", + "name": "Tokens.output", "type": { "tensorType": { "elemType": 8, @@ -1071,7 +1071,7 @@ } }, { - "name": "Embed.onnx", + "name": "Embed.output", "type": { "tensorType": { "elemType": 1, diff --git a/test/Microsoft.ML.Functional.Tests/ONNX.cs b/test/Microsoft.ML.Functional.Tests/ONNX.cs index 245917a2f4..e9a20a4817 100644 --- a/test/Microsoft.ML.Functional.Tests/ONNX.cs +++ b/test/Microsoft.ML.Functional.Tests/ONNX.cs @@ -48,16 +48,11 @@ public void SaveOnnxModelLoadAndScoreFastTree() mlContext.Model.ConvertToOnnx(model, data, file); // Load the model as a transform. - // Note that when saving an ML.NET model as an ONNX model, the column types and column names will - // change. The name changes as ONNX doesn't not allow the same name for an input and output within the ONNX model. - // Therefore names maintained but have a number appended to the end of the name. In this case, Score0 is the output - // of the ONNX model. We are renaming Score0 to Score using Copy Columns. - // ONNX also uses tensors and will return an output of a tensor with the dimension of [1,1] for a single float. + // ONNX uses tensors and will return an output of a tensor with the dimension of [1,1] for a single float. // Therefore the VectorScoreColumn class (which contains a float [] field called Score) is used for the return // type on the Prediction engine. // See #2980 and #2981 for more information. - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(modelPath) - .Append(mlContext.Transforms.CopyColumns("Score", "Score.onnx")); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(modelPath); var onnxModel = onnxEstimator.Fit(data); // Create prediction engine and test predictions. @@ -109,7 +104,7 @@ public void SaveOnnxModelLoadAndScoreKMeans() // TODO #2980: ONNX outputs don't match the outputs of the model, so we must hand-correct this for now. // TODO #2981: ONNX models cannot be fit as part of a pipeline, so we must use a workaround like this. var onnxWorkaroundPipeline = onnxModel.Append( - mlContext.Transforms.CopyColumns("Score", "Score.onnx").Fit(onnxModel.Transform(data))); + mlContext.Transforms.CopyColumns("Score", "Score").Fit(onnxModel.Transform(data))); // Create prediction engine and test predictions. var originalPredictionEngine = mlContext.Model.CreatePredictionEngine(model); @@ -158,15 +153,10 @@ public void SaveOnnxModelLoadAndScoreSDCA() var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(modelPath); var onnxModel = onnxEstimator.Fit(data); - // TODO #2980: ONNX outputs don't match the outputs of the model, so we must hand-correct this for now. - // TODO #2981: ONNX models cannot be fit as part of a pipeline, so we must use a workaround like this. - var onnxWorkaroundPipeline = onnxModel.Append( - mlContext.Transforms.CopyColumns("Score", "Score.onnx").Fit(onnxModel.Transform(data))); - // Create prediction engine and test predictions. var originalPredictionEngine = mlContext.Model.CreatePredictionEngine(model); // TODO #2982: ONNX produces vector types and not the original output type. - var onnxPredictionEngine = mlContext.Model.CreatePredictionEngine(onnxWorkaroundPipeline); + var onnxPredictionEngine = mlContext.Model.CreatePredictionEngine(onnxModel); // Take a handful of examples out of the dataset and compute predictions. var dataEnumerator = mlContext.Data.CreateEnumerable(mlContext.Data.TakeRows(data, 5), false); diff --git a/test/Microsoft.ML.Tests/OnnxConversionTest.cs b/test/Microsoft.ML.Tests/OnnxConversionTest.cs index 52cd84c8f8..8d842a65fb 100644 --- a/test/Microsoft.ML.Tests/OnnxConversionTest.cs +++ b/test/Microsoft.ML.Tests/OnnxConversionTest.cs @@ -85,17 +85,15 @@ public void SimpleEndToEndOnnxConversionTest() var onnxModelPath = GetOutputPath(onnxFileName); SaveOnnxModel(onnxModel, onnxModelPath, null); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitProcess) + if (IsOnnxRuntimeSupported()) { // Step 3: Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(data); var onnxResult = onnxTransformer.Transform(data); // Step 4: Compare ONNX and ML.NET results. - CompareSelectedColumns("Score", "Score.onnx", transformedData, onnxResult, 1); + CompareSelectedColumns("Score", "Score", transformedData, onnxResult, 1); } // Step 5: Check ONNX model's text format. This test will be not necessary if Step 3 and Step 4 can run on Linux and @@ -173,20 +171,18 @@ public void KmeansOnnxConversionTest() var onnxModel = mlContext.Model.ConvertToOnnxProtobuf(model, data); + var onnxFileName = "model.onnx"; + var onnxModelPath = GetOutputPath(onnxFileName); + SaveOnnxModel(onnxModel, onnxModelPath, null); + // Compare results produced by ML.NET and ONNX's runtime. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitProcess) + if (IsOnnxRuntimeSupported()) { - var onnxFileName = "model.onnx"; - var onnxModelPath = GetOutputPath(onnxFileName); - SaveOnnxModel(onnxModel, onnxModelPath, null); - // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(data); var onnxResult = onnxTransformer.Transform(data); - CompareSelectedColumns("Score", "Score.onnx", transformedData, onnxResult, 3); + CompareSelectedColumns("Score", "Score", transformedData, onnxResult, 3); } // Check ONNX model's text format. We save the produced ONNX model as a text file and compare it against @@ -229,22 +225,21 @@ public void RegressionTrainersOnnxConversionTest() var model = estimator.Fit(dataView); var transformedData = model.Transform(dataView); var onnxModel = mlContext.Model.ConvertToOnnxProtobuf(model, dataView); + // Compare model scores produced by ML.NET and ONNX's runtime if (IsOnnxRuntimeSupported()) { var onnxFileName = $"{estimator.ToString()}.onnx"; var onnxModelPath = GetOutputPath(onnxFileName); SaveOnnxModel(onnxModel, onnxModelPath, null); - // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns(transformedData.Schema[2].Name, outputNames[2], transformedData, onnxResult, 3); // compare score results + CompareSelectedColumns("Score", "Score", transformedData, onnxResult, 3); } // Compare the Onnx graph to a baseline if OnnxRuntime is not supported - else + //else { var onnxFileName = $"{estimator.ToString()}.txt"; var subDir = Path.Combine("..", "..", "BaselineOutput", "Common", "Onnx", "Regression", "Adult"); @@ -290,20 +285,20 @@ public void BinaryClassificationTrainersOnnxConversionTest() var model = pipeline.Fit(dataView); var transformedData = model.Transform(dataView); var onnxModel = mlContext.Model.ConvertToOnnxProtobuf(model, dataView); + + var onnxFileName = $"{estimator.ToString()}.onnx"; + var onnxModelPath = GetOutputPath(onnxFileName); + SaveOnnxModel(onnxModel, onnxModelPath, null); + // Compare model scores produced by ML.NET and ONNX's runtime. if (IsOnnxRuntimeSupported()) { - var onnxFileName = $"{estimator.ToString()}.onnx"; - var onnxModelPath = GetOutputPath(onnxFileName); - SaveOnnxModel(onnxModel, onnxModelPath, null); // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns(transformedData.Schema[5].Name, outputNames[3], transformedData, onnxResult, 3); //compare scores - CompareSelectedColumns(transformedData.Schema[4].Name, outputNames[2], transformedData, onnxResult); //compare predicted labels + CompareSelectedColumns("Score", "Score", transformedData, onnxResult, 3); //compare scores + CompareSelectedColumns("PredictedLabel", "PredictedLabel", transformedData, onnxResult); //compare predicted labels } } Done(); @@ -326,19 +321,17 @@ public void TestVectorWhiteningOnnxConversionTest() var onnxModel = mlContext.Model.ConvertToOnnxProtobuf(model, dataView); // Compare model scores produced by ML.NET and ONNX's runtime. + var onnxFileName = $"VectorWhitening.onnx"; + var onnxModelPath = GetOutputPath(onnxFileName); + SaveOnnxModel(onnxModel, onnxModelPath, null); + if (IsOnnxRuntimeSupported()) { - var onnxFileName = $"VectorWhitening.onnx"; - var onnxModelPath = GetOutputPath(onnxFileName); - SaveOnnxModel(onnxModel, onnxModelPath, null); - // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns(transformedData.Schema[2].Name, outputNames[2], transformedData, onnxResult); // whitened1 - CompareSelectedColumns(transformedData.Schema[3].Name, outputNames[3], transformedData, onnxResult); // whitened2 + CompareSelectedColumns("whitened1", "whitened1", transformedData, onnxResult); + CompareSelectedColumns("whitened2", "whitened2", transformedData, onnxResult); } Done(); } @@ -381,21 +374,20 @@ public void PlattCalibratorOnnxConversionTest() var transformedData = model.Transform(dataView); var onnxModel = mlContext.Model.ConvertToOnnxProtobuf(model, dataView); + var onnxFileName = $"{estimator.ToString()}-WithPlattCalibrator.onnx"; + var onnxModelPath = GetOutputPath(onnxFileName); + SaveOnnxModel(onnxModel, onnxModelPath, null); + // Compare model scores produced by ML.NET and ONNX's runtime. if (IsOnnxRuntimeSupported()) { - var onnxFileName = $"{estimator.ToString()}-WithPlattCalibrator.onnx"; - var onnxModelPath = GetOutputPath(onnxFileName); - SaveOnnxModel(onnxModel, onnxModelPath, null); // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns(transformedData.Schema[5].Name, outputNames[3], transformedData, onnxResult, 3); //compare scores - CompareSelectedColumns(transformedData.Schema[4].Name, outputNames[2], transformedData, onnxResult); //compare predicted labels - CompareSelectedColumns(transformedData.Schema.Last().Name, outputNames.Last(), transformedData, onnxResult, 3); //compare probabilities + CompareSelectedColumns("Score", "Score", transformedData, onnxResult, 3); + CompareSelectedColumns("PredictedLabel", "PredictedLabel", transformedData, onnxResult); + CompareSelectedColumns("Probability", "Probability", transformedData, onnxResult, 3); } } Done(); @@ -430,20 +422,17 @@ public void PlattCalibratorOnnxConversionTest2() var transformedData = calibratorTransformer.Transform(data); var onnxModel = mlContext.Model.ConvertToOnnxProtobuf(calibratorTransformer, data); + var onnxFileName = $"{calibratorTransformer.ToString()}.onnx"; + var onnxModelPath = GetOutputPath(onnxFileName); + SaveOnnxModel(onnxModel, onnxModelPath, null); + // Compare model scores produced by ML.NET and ONNX's runtime. if (IsOnnxRuntimeSupported()) { - var onnxFileName = $"{calibratorTransformer.ToString()}.onnx"; - var onnxModelPath = GetOutputPath(onnxFileName); - SaveOnnxModel(onnxModel, onnxModelPath, null); - - // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(data); var onnxResult = onnxTransformer.Transform(data); - CompareSelectedColumns(transformedData.Schema.Last().Name, outputNames.Last(), transformedData, onnxResult, 3); //compare probabilities + CompareSelectedColumns("Probability", "Probability", transformedData, onnxResult, 3); //compare probabilities } Done(); } @@ -464,22 +453,21 @@ public void TextNormalizingOnnxConversionTest() var transformedData = model.Transform(dataView); var onnxModel = mlContext.Model.ConvertToOnnxProtobuf(model, dataView); + var onnxFileName = $"TextNormalizing.onnx"; + var onnxModelPath = GetOutputPath(onnxFileName); + SaveOnnxModel(onnxModel, onnxModelPath, null); + // Compare model scores produced by ML.NET and ONNX's runtime. // Skipping test in Linux platforms temporarily if (IsOnnxRuntimeSupported() && !RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { - var onnxFileName = $"TextNormalizing.onnx"; - var onnxModelPath = GetOutputPath(onnxFileName); - SaveOnnxModel(onnxModel, onnxModelPath, null); // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns>(transformedData.Schema[2].Name, outputNames[2], transformedData, onnxResult); //compare NormText - CompareSelectedColumns>(transformedData.Schema[3].Name, outputNames[3], transformedData, onnxResult); //compare UpperText - CompareSelectedColumns>(transformedData.Schema[4].Name, outputNames[4], transformedData, onnxResult); //compare OriginalText + CompareSelectedColumns>("NormText", "NormText", transformedData, onnxResult); + CompareSelectedColumns>("UpperText", "UpperText", transformedData, onnxResult); + CompareSelectedColumns>("OriginalText", "OriginalText", transformedData, onnxResult); } Done(); } @@ -520,15 +508,13 @@ public void LpNormOnnxConversionTest( SaveOnnxModel(onnxModel, onnxModelPath, null); // Compare results produced by ML.NET and ONNX's runtime. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitProcess) + if (IsOnnxRuntimeSupported()) { // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns(nameof(DataPoint.Features), outputNames[0], transformedData, onnxResult, 3); + CompareSelectedColumns("Features", "Features", transformedData, onnxResult, 3); } Done(); @@ -969,19 +955,19 @@ public void TokenizingByCharactersOnnxConversionTest(bool useMarkerCharacters) var model = pipeline.Fit(dataView); var transformedData = model.Transform(dataView); var onnxModel = mlContext.Model.ConvertToOnnxProtobuf(model, dataView); + // Compare model scores produced by ML.NET and ONNX's runtime. + var onnxFileName = $"TokenizingByCharacters.onnx"; + var onnxModelPath = GetOutputPath(onnxFileName); + SaveOnnxModel(onnxModel, onnxModelPath, null); + if (IsOnnxRuntimeSupported()) { - var onnxFileName = $"TokenizingByCharacters.onnx"; - var onnxModelPath = GetOutputPath(onnxFileName); - SaveOnnxModel(onnxModel, onnxModelPath, null); // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns(transformedData.Schema[2].Name, outputNames[2], transformedData, onnxResult); //compare scores + CompareSelectedColumns("TokenizedText", "TokenizedText", transformedData, onnxResult); } Done(); } @@ -1051,15 +1037,13 @@ public void OnnxTypeConversionTest(DataKind fromKind, DataKind toKind) var onnxModelPath = GetOutputPath(onnxFileName); SaveOnnxModel(onnxModel, onnxModelPath, null); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitProcess) + if (IsOnnxRuntimeSupported()) { - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareResults(model.ColumnPairs[0].outputColumnName, outputNames[1], mlnetResult, onnxResult); + CompareResults("ValueConverted", "ValueConverted", mlnetResult, onnxResult); } Done(); @@ -1089,15 +1073,13 @@ public void PcaOnnxConversionTest() SaveOnnxModel(onnxModel, onnxModelPath, null); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitProcess) + if (IsOnnxRuntimeSupported()) { // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns(model.ColumnPairs[0].outputColumnName, outputNames[2], transformedData, onnxResult); + CompareSelectedColumns("pca", "pca", transformedData, onnxResult); } } @@ -1153,12 +1135,10 @@ public void IndicateMissingValuesOnnxConversionTest() if (IsOnnxRuntimeSupported()) { // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns(model.LastTransformer.ColumnPairs[0].outputColumnName, outputNames[1], transformedData, onnxResult); + CompareSelectedColumns("MissingIndicator", "MissingIndicator", transformedData, onnxResult); } CheckEquality(subDir, onnxTextName, parseOption: NumberParseOption.UseSingle); @@ -1193,14 +1173,12 @@ public void ValueToKeyandKeyToValueMappingOnnxConversionTest(DataKind valueType) if (IsOnnxRuntimeSupported()) { - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareResults(mlnetResult.Schema[2].Name, outputNames[2], mlnetResult, onnxResult); //compare output values - CompareSelectedColumns(mlnetResult.Schema[1].Name, outputNames[1], mlnetResult, onnxResult); //compare keys + CompareResults("ValueOutput", "ValueOutput", mlnetResult, onnxResult); + CompareSelectedColumns("Key", "Key", mlnetResult, onnxResult); } Done(); } @@ -1233,15 +1211,14 @@ public void WordTokenizerOnnxConversionTest() var onnxFilename = "Tokenizer.onnx"; var onnxFilePath = GetOutputPath(onnxFilename); SaveOnnxModel(onnxModel, onnxFilePath, null); + if (IsOnnxRuntimeSupported()) { // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxFilePath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxFilePath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns>(transformedData.Schema[1].Name, outputNames[1], transformedData, onnxResult); + CompareSelectedColumns>("Tokens", "Tokens", transformedData, onnxResult); } Done(); @@ -1297,15 +1274,14 @@ public void NgramOnnxConversionTest( var onnxFilename = $"Ngram-{i}-{ngramLength}-{useAllLength}-{weighting}.onnx"; var onnxFilePath = GetOutputPath(onnxFilename); SaveOnnxModel(onnxModel, onnxFilePath, null); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitProcess) + + if (IsOnnxRuntimeSupported()) { - // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxFilePath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxFilePath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns(transformedData.Schema[transformedData.Schema.Count-1].Name, outputNames[outputNames.Length-1], transformedData, onnxResult, 3); //comparing Ngrams + var columnName = i == pipelines.Length - 1 ? "Tokens" : "NGrams"; + CompareSelectedColumns(columnName, columnName, transformedData, onnxResult, 3); } } Done(); @@ -1362,7 +1338,7 @@ public void OptionalColumnOnnxTest(DataKind dataKind) var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareResults("Label", "Label.onnx", outputData, onnxResult); + CompareResults("Label", "Label", outputData, onnxResult); } Done(); } @@ -1392,12 +1368,10 @@ public void KeyToValueOnnxConversionTest() if (IsOnnxRuntimeSupported()) { // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns>(transformedData.Schema[3].Name, outputNames[3], transformedData, onnxResult); + CompareSelectedColumns>("LabelValue", "LabelValue", transformedData, onnxResult); } Done(); @@ -1462,13 +1436,11 @@ public void MulticlassTrainersOnnxConversionTest() if (IsOnnxRuntimeSupported()) { // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns(transformedData.Schema[5].Name, outputNames[2], transformedData, onnxResult); //compare predicted labels - CompareSelectedColumns(transformedData.Schema[6].Name, outputNames[3], transformedData, onnxResult, 4); //compare scores + CompareSelectedColumns("PredictedLabel", "PredictedLabel", transformedData, onnxResult); + CompareSelectedColumns("Score", "Score", transformedData, onnxResult, 4); } } Done(); @@ -1497,12 +1469,10 @@ public void CopyColumnsOnnxTest() if (IsOnnxRuntimeSupported()) { // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns(model.ColumnPairs[0].outputColumnName, outputNames[2], transformedData, onnxResult); + CompareSelectedColumns("Target", "Target1", transformedData, onnxResult); } Done(); } @@ -1575,8 +1545,13 @@ public void UseKeyDataViewTypeAsUInt32InOnnxInput() var onnxEstimator2 = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath2); var onnxResult2 = onnxEstimator2.Fit(originalData).Transform(originalData); + var stdSuffix = ".output"; foreach (var name in outputNames) - CompareResults(name, name, onnxResult, onnxResult2); + { + Assert.EndsWith(stdSuffix, name); + var colName = name.Replace(stdSuffix, ""); + CompareResults(colName, colName, onnxResult, onnxResult2); + } } Done(); @@ -1620,15 +1595,13 @@ public void FeatureSelectionOnnxTest() if (IsOnnxRuntimeSupported()) { // Evaluate the saved ONNX model using the data used to train the ML.NET pipeline. - string[] inputNames = onnxModel.Graph.Input.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - string[] outputNames = onnxModel.Graph.Output.Select(valueInfoProto => valueInfoProto.Name).ToArray(); - var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(outputNames, inputNames, onnxModelPath); + var onnxEstimator = mlContext.Transforms.ApplyOnnxModel(onnxModelPath); var onnxTransformer = onnxEstimator.Fit(dataView); var onnxResult = onnxTransformer.Transform(dataView); - CompareSelectedColumns("FeatureSelectMIScalarFloat", "FeatureSelectMIScalarFloat.onnx", transformedData, onnxResult); - CompareSelectedColumns("FeatureSelectMIVectorFloat", "FeatureSelectMIVectorFloat.onnx", transformedData, onnxResult); - CompareSelectedColumns("ScalFeatureSelectMissing690", "ScalFeatureSelectMissing690.onnx", transformedData, onnxResult); - CompareSelectedColumns("VecFeatureSelectMissing690", "VecFeatureSelectMissing690.onnx", transformedData, onnxResult); + CompareSelectedColumns("FeatureSelectMIScalarFloat", "FeatureSelectMIScalarFloat", transformedData, onnxResult); + CompareSelectedColumns("FeatureSelectMIVectorFloat", "FeatureSelectMIVectorFloat", transformedData, onnxResult); + CompareSelectedColumns("ScalFeatureSelectMissing690", "ScalFeatureSelectMissing690", transformedData, onnxResult); + CompareSelectedColumns("VecFeatureSelectMissing690", "VecFeatureSelectMissing690", transformedData, onnxResult); } Done(); } @@ -1676,15 +1649,15 @@ public void SelectColumnsOnnxTest() // Verify that onnx output has only the four columns we selected from the input Assert.Equal(4, outputNames.Length); - Assert.Equal("Size.onnx", outputNames[0]); - Assert.Equal("Shape.onnx", outputNames[1]); - Assert.Equal("Thickness.onnx", outputNames[2]); - Assert.Equal("Label.onnx", outputNames[3]); - - CompareSelectedColumns("Size", "Size.onnx", transformedData, onnxResult); - CompareSelectedColumns("Shape", "Shape.onnx", transformedData, onnxResult); - CompareSelectedColumns("Thickness", "Thickness.onnx", transformedData, onnxResult); - CompareSelectedColumns("Label", "Label.onnx", transformedData, onnxResult); + Assert.Equal("Size.output", outputNames[0]); + Assert.Equal("Shape.output", outputNames[1]); + Assert.Equal("Thickness.output", outputNames[2]); + Assert.Equal("Label.output", outputNames[3]); + + CompareSelectedColumns("Size", "Size", transformedData, onnxResult); + CompareSelectedColumns("Shape", "Shape", transformedData, onnxResult); + CompareSelectedColumns("Thickness", "Thickness", transformedData, onnxResult); + CompareSelectedColumns("Label", "Label", transformedData, onnxResult); } onnxFileName = "SelectColumns.txt";