From 547a84e050a030b8d7e79b29c2bed14dc4dbaa99 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Thu, 25 Jun 2020 09:38:50 -0700 Subject: [PATCH 01/12] init checkin --- .../TensorflowTransform.cs | 76 ++++++++++++++++++- .../TensorFlowEstimatorTests.cs | 47 ++++++++++++ 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs index 12d1ecf518..186c28dfbf 100644 --- a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs +++ b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs @@ -509,6 +509,7 @@ public Mapper(TensorFlowTransformer parent, DataViewSchema inputSchema) : var shape = originalShape.dims; var colTypeDims = vecType.Dimensions.Select(dim => (int)dim).ToArray(); + var typeDims = (type as VectorDataViewType).Dimensions; if (shape == null || (shape.Length == 0)) _fullySpecifiedShapes[i] = new TensorShape(colTypeDims); else @@ -529,6 +530,24 @@ public Mapper(TensorFlowTransformer parent, DataViewSchema inputSchema) : if (typeValueCount % valCount != 0) throw Contracts.Except($"Input shape mismatch: Input '{_parent.Inputs[i]}' has shape {originalShape.ToString()}, but input data is of length {typeValueCount}."); + //This cover the 2-variable senario e.g. [?,?,?,3] where we can assume W = H and typeDims provides the information of [W, H, C] + var originalShapeDims = originalShape.dims; + var originalShapeNdim = originalShape.ndim; + if (numOfUnkDim == typeDims.Length && originalShapeNdim == numOfUnkDim + 1) + { + if (typeDims.Length != 3) + throw Contracts.Except($"Input '{_parent.Inputs[i]}' Schema does not provide enough information for tensor shape inferencing"); + for (int ishape = 1; ishape < originalShapeNdim; ++ishape) + { + if (originalShapeDims[ishape] == -1) + { + originalShapeDims[ishape] = typeDims.IndexOf(ishape - 1); + valCount *= originalShapeDims[ishape]; + numOfUnkDim--; + } + } + } + // If the shape is multi-dimensional, we should be able to create the length of the vector by plugging // in a single value for the unknown shapes. For example, if the shape is [?,?,3], then there should exist a value // d such that d*d*3 is equal to the length of the input column. @@ -537,8 +556,6 @@ public Mapper(TensorFlowTransformer parent, DataViewSchema inputSchema) : throw Contracts.Except($"Input shape mismatch: Input '{_parent.Inputs[i]}' has shape {originalShape.ToString()}, but input data is of length {typeValueCount}."); // Fill in the unknown dimensions. - var originalShapeNdim = originalShape.ndim; - var originalShapeDims = originalShape.dims; var l = new int[originalShapeNdim]; for (int ishape = 0; ishape < originalShapeNdim; ishape++) l[ishape] = originalShapeDims[ishape] == -1 ? (int)d : originalShapeDims[ishape]; @@ -553,6 +570,61 @@ public Mapper(TensorFlowTransformer parent, DataViewSchema inputSchema) : l[ishape] = _fullySpecifiedShapes[i].dims[ishape - 1]; _fullySpecifiedShapes[i] = new TensorShape(l); } + + /*if (shape == null || (shape.Length == 0)) + _fullySpecifiedShapes[i] = new TensorShape(colTypeDims); + else + { + // If the column is one dimension we make sure that the total size of the TF shape matches. + // Compute the total size of the known dimensions of the shape. + int valCount = 1; + int numOfUnkDim = 0; + foreach (var s in shape) + { + if (s > 0) + valCount *= s; + else + numOfUnkDim++; + } + // The column length should be divisible by this, so that the other dimensions can be integral. + int typeValueCount = type.GetValueCount(); + var typeDims = (type as VectorDataViewType).Dimensions; + + if (typeValueCount % valCount != 0) + throw Contracts.Except($"Input shape mismatch: Input '{_parent.Inputs[i]}' has shape {originalShape.ToString()}, but input data is of length {typeValueCount}."); + + int[] originalShapeDims = originalShape.dims; + if (typeDims.Length == originalShape.ndim) + { + int shapeNDim = originalShape.ndim + (_parent._addBatchDimensionInput ? 1 : 0); + int[] l = new int[shapeNDim]; + l[0] = 1; + for (int rishape = shapeNDim - 1; rishape >= 0; --rishape) + { + if (originalShapeDims[rishape] != -1 && originalShapeDims[rishape] != typeDims.IndexOf(rishape)) + throw Contracts.Except($"Input shape mismatch: Input '{_parent.Inputs[i]}' has shape {originalShape.ToString()}, but input data is of shape {typeDims.ToString()}."); //bugbug + l[rishape] = typeDims.IndexOf(rishape); + } + _fullySpecifiedShapes[i] = new TensorShape(l); + } + else if (typeDims.Length + 1 == originalShape.ndim && _parent._addBatchDimensionInput) + { + int shapeNDim = originalShape.ndim; + int[] l = new int[shapeNDim]; + l[0] = 1; + for (int ishape = 1; ishape < shapeNDim; ++ishape) + { + if (originalShapeDims[ishape] != -1 && originalShapeDims[ishape] != typeDims.ElementAt(ishape - 1)) + throw Contracts.Except($"Input shape mismatch: Input '{_parent.Inputs[i]}' has shape {originalShape.ToString()}, but input data is of shape {typeDims.ToString()}."); //bugbug + l[ishape] = typeDims.IndexOf(ishape - 1); + } + _fullySpecifiedShapes[i] = new TensorShape(l); + } + else + { + throw Contracts.Except($"Input dimension number mismatch: Input '{_parent.Inputs[i]}' has {originalShape.ndim} dimensions, but input data has {typeDims.Length}."); + } + }*/ } _runners = new ConcurrentBag(); diff --git a/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs b/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs index 8aba9b08a5..9295620a6a 100644 --- a/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs +++ b/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs @@ -14,6 +14,7 @@ using Microsoft.ML.TensorFlow; using Xunit; using Xunit.Abstractions; +using static Microsoft.ML.Scenarios.TensorFlowScenariosTests; namespace Microsoft.ML.Tests { @@ -272,5 +273,51 @@ private void ValidateTensorFlowTransformer(IDataView result) } } } + + [TensorFlowFact] + public void MyTest() + { + var mlContext = new MLContext(seed: 1); + + var modelFile = "C:\\Users\\Administrator\\Desktop\\MLNET\\PotatoDetector.pb"; + + var dataFile = GetDataPath("images/images.tsv"); + var imageFolder = Path.GetDirectoryName(dataFile); + + var data = ML.Data.LoadFromTextFile(dataFile, new[] { + new TextLoader.Column("imagePath", DataKind.String, 0), + new TextLoader.Column("name", DataKind.String, 1) + }); + + var pipeline = mlContext.Transforms + .LoadImages("image_tensor", imageFolder, "imagePath") + .Append(mlContext.Transforms.ResizeImages(outputColumnName: "image_tensor", imageWidth: 500, imageHeight: 500)) + .Append(mlContext.Transforms.ExtractPixels(outputColumnName: "image_tensor", interleavePixelColors: true, outputAsFloatArray: false)) + .Append(mlContext.Model.LoadTensorFlowModel(modelFile) + .ScoreTensorFlowModel(outputColumnNames: new[] { "detection_boxes", "detection_scores", "num_detections" }, inputColumnNames: new[] { "image_tensor" }, addBatchDimensionInput: false)); + + var transformer = pipeline.Fit(data); + + /*var modelLocation = "cifar_model/frozen_model.pb"; + + var mlContext = new MLContext(seed: 1); + var imageHeight = 32; + var imageWidth = 32; + var dataFile = GetDataPath("images/images.tsv"); + var imageFolder = Path.GetDirectoryName(dataFile); + + var data = ML.Data.LoadFromTextFile(dataFile, new[] { + new TextLoader.Column("imagePath", DataKind.String, 0), + new TextLoader.Column("name", DataKind.String, 1) + }); + + // Note that CamelCase column names are there to match the TF graph node names. + var pipe = ML.Transforms.LoadImages("Input", imageFolder, "imagePath") + .Append(ML.Transforms.ResizeImages("Input", imageHeight, imageWidth)) + .Append(ML.Transforms.ExtractPixels("Input", interleavePixelColors: true)) + .Append(ML.Model.LoadTensorFlowModel(modelLocation).ScoreTensorFlowModel("Output", "Input")); + + TestEstimatorCore(pipe, data);*/ + } } } From a4bab80c329678896fa4b5ad29c271b0aab6e9e0 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Thu, 25 Jun 2020 09:39:56 -0700 Subject: [PATCH 02/12] remove --- .../TensorflowTransform.cs | 55 ------------------- .../TensorFlowEstimatorTests.cs | 8 +-- 2 files changed, 4 insertions(+), 59 deletions(-) diff --git a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs index 186c28dfbf..108e7d92b1 100644 --- a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs +++ b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs @@ -570,61 +570,6 @@ public Mapper(TensorFlowTransformer parent, DataViewSchema inputSchema) : l[ishape] = _fullySpecifiedShapes[i].dims[ishape - 1]; _fullySpecifiedShapes[i] = new TensorShape(l); } - - /*if (shape == null || (shape.Length == 0)) - _fullySpecifiedShapes[i] = new TensorShape(colTypeDims); - else - { - // If the column is one dimension we make sure that the total size of the TF shape matches. - // Compute the total size of the known dimensions of the shape. - int valCount = 1; - int numOfUnkDim = 0; - foreach (var s in shape) - { - if (s > 0) - valCount *= s; - else - numOfUnkDim++; - } - // The column length should be divisible by this, so that the other dimensions can be integral. - int typeValueCount = type.GetValueCount(); - var typeDims = (type as VectorDataViewType).Dimensions; - - if (typeValueCount % valCount != 0) - throw Contracts.Except($"Input shape mismatch: Input '{_parent.Inputs[i]}' has shape {originalShape.ToString()}, but input data is of length {typeValueCount}."); - - int[] originalShapeDims = originalShape.dims; - if (typeDims.Length == originalShape.ndim) - { - int shapeNDim = originalShape.ndim + (_parent._addBatchDimensionInput ? 1 : 0); - int[] l = new int[shapeNDim]; - l[0] = 1; - for (int rishape = shapeNDim - 1; rishape >= 0; --rishape) - { - if (originalShapeDims[rishape] != -1 && originalShapeDims[rishape] != typeDims.IndexOf(rishape)) - throw Contracts.Except($"Input shape mismatch: Input '{_parent.Inputs[i]}' has shape {originalShape.ToString()}, but input data is of shape {typeDims.ToString()}."); //bugbug - l[rishape] = typeDims.IndexOf(rishape); - } - _fullySpecifiedShapes[i] = new TensorShape(l); - } - else if (typeDims.Length + 1 == originalShape.ndim && _parent._addBatchDimensionInput) - { - int shapeNDim = originalShape.ndim; - int[] l = new int[shapeNDim]; - l[0] = 1; - for (int ishape = 1; ishape < shapeNDim; ++ishape) - { - if (originalShapeDims[ishape] != -1 && originalShapeDims[ishape] != typeDims.ElementAt(ishape - 1)) - throw Contracts.Except($"Input shape mismatch: Input '{_parent.Inputs[i]}' has shape {originalShape.ToString()}, but input data is of shape {typeDims.ToString()}."); //bugbug - l[ishape] = typeDims.IndexOf(ishape - 1); - } - _fullySpecifiedShapes[i] = new TensorShape(l); - } - else - { - throw Contracts.Except($"Input dimension number mismatch: Input '{_parent.Inputs[i]}' has {originalShape.ndim} dimensions, but input data has {typeDims.Length}."); - } - }*/ } _runners = new ConcurrentBag(); diff --git a/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs b/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs index 9295620a6a..9738802129 100644 --- a/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs +++ b/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs @@ -274,7 +274,7 @@ private void ValidateTensorFlowTransformer(IDataView result) } } - [TensorFlowFact] + /*[TensorFlowFact] public void MyTest() { var mlContext = new MLContext(seed: 1); @@ -298,7 +298,7 @@ public void MyTest() var transformer = pipeline.Fit(data); - /*var modelLocation = "cifar_model/frozen_model.pb"; + *//*var modelLocation = "cifar_model/frozen_model.pb"; var mlContext = new MLContext(seed: 1); var imageHeight = 32; @@ -317,7 +317,7 @@ public void MyTest() .Append(ML.Transforms.ExtractPixels("Input", interleavePixelColors: true)) .Append(ML.Model.LoadTensorFlowModel(modelLocation).ScoreTensorFlowModel("Output", "Input")); - TestEstimatorCore(pipe, data);*/ - } + TestEstimatorCore(pipe, data);*//* + }*/ } } From 073d7cfcfde97d88a835e3681a14092886b7d91b Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Thu, 25 Jun 2020 09:42:28 -0700 Subject: [PATCH 03/12] modify comments --- src/Microsoft.ML.TensorFlow/TensorflowTransform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs index 108e7d92b1..8a5ad36d52 100644 --- a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs +++ b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs @@ -530,7 +530,7 @@ public Mapper(TensorFlowTransformer parent, DataViewSchema inputSchema) : if (typeValueCount % valCount != 0) throw Contracts.Except($"Input shape mismatch: Input '{_parent.Inputs[i]}' has shape {originalShape.ToString()}, but input data is of length {typeValueCount}."); - //This cover the 2-variable senario e.g. [?,?,?,3] where we can assume W = H and typeDims provides the information of [W, H, C] + //This cover the 2-variable senario e.g. [?,?,?,3] where we can assume typeDims provides the information of [W, H, C] var originalShapeDims = originalShape.dims; var originalShapeNdim = originalShape.ndim; if (numOfUnkDim == typeDims.Length && originalShapeNdim == numOfUnkDim + 1) From 13eedc8b0a431354fcd43c4629f070a2d05ea131 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Thu, 25 Jun 2020 09:48:07 -0700 Subject: [PATCH 04/12] fix --- src/Microsoft.ML.TensorFlow/TensorflowTransform.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs index 8a5ad36d52..f968c20eec 100644 --- a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs +++ b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs @@ -533,10 +533,8 @@ public Mapper(TensorFlowTransformer parent, DataViewSchema inputSchema) : //This cover the 2-variable senario e.g. [?,?,?,3] where we can assume typeDims provides the information of [W, H, C] var originalShapeDims = originalShape.dims; var originalShapeNdim = originalShape.ndim; - if (numOfUnkDim == typeDims.Length && originalShapeNdim == numOfUnkDim + 1) + if (numOfUnkDim == typeDims.Length && originalShapeNdim == numOfUnkDim + 1 && typeDims.Length == 3) { - if (typeDims.Length != 3) - throw Contracts.Except($"Input '{_parent.Inputs[i]}' Schema does not provide enough information for tensor shape inferencing"); for (int ishape = 1; ishape < originalShapeNdim; ++ishape) { if (originalShapeDims[ishape] == -1) From 44c44d0ec267050e4bcb6aaac0726cc662bb0cb2 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Sat, 27 Jun 2020 01:08:22 -0700 Subject: [PATCH 05/12] add tests --- .../TensorflowTransform.cs | 5 +- .../TensorflowTests.cs | 50 +++++++++++++++++++ .../TensorFlowEstimatorTests.cs | 46 ----------------- 3 files changed, 52 insertions(+), 49 deletions(-) diff --git a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs index f968c20eec..030312b90e 100644 --- a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs +++ b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs @@ -509,7 +509,6 @@ public Mapper(TensorFlowTransformer parent, DataViewSchema inputSchema) : var shape = originalShape.dims; var colTypeDims = vecType.Dimensions.Select(dim => (int)dim).ToArray(); - var typeDims = (type as VectorDataViewType).Dimensions; if (shape == null || (shape.Length == 0)) _fullySpecifiedShapes[i] = new TensorShape(colTypeDims); else @@ -533,13 +532,13 @@ public Mapper(TensorFlowTransformer parent, DataViewSchema inputSchema) : //This cover the 2-variable senario e.g. [?,?,?,3] where we can assume typeDims provides the information of [W, H, C] var originalShapeDims = originalShape.dims; var originalShapeNdim = originalShape.ndim; - if (numOfUnkDim == typeDims.Length && originalShapeNdim == numOfUnkDim + 1 && typeDims.Length == 3) + if (numOfUnkDim == colTypeDims.Length && originalShapeNdim == numOfUnkDim + 1 && colTypeDims.Length == 3) { for (int ishape = 1; ishape < originalShapeNdim; ++ishape) { if (originalShapeDims[ishape] == -1) { - originalShapeDims[ishape] = typeDims.IndexOf(ishape - 1); + originalShapeDims[ishape] = colTypeDims[ishape - 1]; valCount *= originalShapeDims[ishape]; numOfUnkDim--; } diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs index 5130391d23..588a0009ea 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs @@ -23,6 +23,10 @@ using Microsoft.ML.Trainers; using Microsoft.ML.Internal.Utilities; using Microsoft.ML.Runtime; +using Microsoft.ML.Model; +using Microsoft.ML.RunTests; +using Microsoft.ML.Tools; +using static Microsoft.ML.Scenarios.TensorFlowScenariosTests; namespace Microsoft.ML.Scenarios { @@ -1900,5 +1904,51 @@ private static string GetTemporaryDirectory() Directory.CreateDirectory(tempDirectory); return tempDirectory; } + + [TensorFlowFact] + public void MyTest() + { + /*import tensorflow as tf + graph_path = './saved_model.pb' + + def load_frozen_graph(frozen_file): + graph = tf.Graph() + with graph.as_default(): + od_graph_def = tf.compat.v1.GraphDef() + with tf.io.gfile.GFile(frozen_file, 'rb') as fid: + serialized_graph = fid.read() + od_graph_def.ParseFromString(serialized_graph) + tf.import_graph_def(od_graph_def, name = '') + return graph + graph = load_frozen_graph(graph_path) + + new_graph = tf.Graph() + with new_graph.as_default(): + new_input = tf.compat.v1.placeholder(dtype = tf.float32, shape =[None, None, None, 3], name = 'Input') + tf.import_graph_def(graph.as_graph_def(), name = '', input_map ={ 'Input:0': new_input}) + + frozen_file = './new.pb' + with open(frozen_file, 'wb') as f: + f.write(new_graph.as_graph_def().SerializeToString())*/ + var modelLocation = "cifar_model/frozen_model_variadic_input_shape.pb"; + + var imageHeight = 32; + var imageWidth = 32; + var dataFile = GetDataPath("images/images.tsv"); + var imageFolder = Path.GetDirectoryName(dataFile); + + var data = _mlContext.Data.LoadFromTextFile(dataFile, new[] { + new TextLoader.Column("imagePath", DataKind.String, 0), + new TextLoader.Column("name", DataKind.String, 1) + }); + + // Note that CamelCase column names are there to match the TF graph node names. + var pipeline = _mlContext.Transforms.LoadImages("Input", imageFolder, "imagePath") + .Append(_mlContext.Transforms.ResizeImages("Input", imageHeight, imageWidth)) + .Append(_mlContext.Transforms.ExtractPixels("Input", interleavePixelColors: true)) + .Append(_mlContext.Model.LoadTensorFlowModel(modelLocation).ScoreTensorFlowModel("Output", "Input")); + + var transformer = pipeline.Fit(data); + } } } diff --git a/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs b/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs index 9738802129..a727f4d14b 100644 --- a/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs +++ b/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs @@ -273,51 +273,5 @@ private void ValidateTensorFlowTransformer(IDataView result) } } } - - /*[TensorFlowFact] - public void MyTest() - { - var mlContext = new MLContext(seed: 1); - - var modelFile = "C:\\Users\\Administrator\\Desktop\\MLNET\\PotatoDetector.pb"; - - var dataFile = GetDataPath("images/images.tsv"); - var imageFolder = Path.GetDirectoryName(dataFile); - - var data = ML.Data.LoadFromTextFile(dataFile, new[] { - new TextLoader.Column("imagePath", DataKind.String, 0), - new TextLoader.Column("name", DataKind.String, 1) - }); - - var pipeline = mlContext.Transforms - .LoadImages("image_tensor", imageFolder, "imagePath") - .Append(mlContext.Transforms.ResizeImages(outputColumnName: "image_tensor", imageWidth: 500, imageHeight: 500)) - .Append(mlContext.Transforms.ExtractPixels(outputColumnName: "image_tensor", interleavePixelColors: true, outputAsFloatArray: false)) - .Append(mlContext.Model.LoadTensorFlowModel(modelFile) - .ScoreTensorFlowModel(outputColumnNames: new[] { "detection_boxes", "detection_scores", "num_detections" }, inputColumnNames: new[] { "image_tensor" }, addBatchDimensionInput: false)); - - var transformer = pipeline.Fit(data); - - *//*var modelLocation = "cifar_model/frozen_model.pb"; - - var mlContext = new MLContext(seed: 1); - var imageHeight = 32; - var imageWidth = 32; - var dataFile = GetDataPath("images/images.tsv"); - var imageFolder = Path.GetDirectoryName(dataFile); - - var data = ML.Data.LoadFromTextFile(dataFile, new[] { - new TextLoader.Column("imagePath", DataKind.String, 0), - new TextLoader.Column("name", DataKind.String, 1) - }); - - // Note that CamelCase column names are there to match the TF graph node names. - var pipe = ML.Transforms.LoadImages("Input", imageFolder, "imagePath") - .Append(ML.Transforms.ResizeImages("Input", imageHeight, imageWidth)) - .Append(ML.Transforms.ExtractPixels("Input", interleavePixelColors: true)) - .Append(ML.Model.LoadTensorFlowModel(modelLocation).ScoreTensorFlowModel("Output", "Input")); - - TestEstimatorCore(pipe, data);*//* - }*/ } } From e4156194bb1ad6335f4190ef60707615d3daf05f Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Sat, 27 Jun 2020 13:14:33 -0700 Subject: [PATCH 06/12] update --- .../TensorflowTests.cs | 55 +++++++------------ 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs index 588a0009ea..2078623348 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs @@ -7,6 +7,7 @@ using System.IO; using System.IO.Compression; using System.Linq; +using System.Net; using System.Runtime.InteropServices; using Microsoft.ML.Data; using Microsoft.ML.Vision; @@ -23,10 +24,6 @@ using Microsoft.ML.Trainers; using Microsoft.ML.Internal.Utilities; using Microsoft.ML.Runtime; -using Microsoft.ML.Model; -using Microsoft.ML.RunTests; -using Microsoft.ML.Tools; -using static Microsoft.ML.Scenarios.TensorFlowScenariosTests; namespace Microsoft.ML.Scenarios { @@ -1906,49 +1903,39 @@ private static string GetTemporaryDirectory() } [TensorFlowFact] - public void MyTest() + public void TensorflowPlaceholderShapeInferenceTest() { - /*import tensorflow as tf - graph_path = './saved_model.pb' - - def load_frozen_graph(frozen_file): - graph = tf.Graph() - with graph.as_default(): - od_graph_def = tf.compat.v1.GraphDef() - with tf.io.gfile.GFile(frozen_file, 'rb') as fid: - serialized_graph = fid.read() - od_graph_def.ParseFromString(serialized_graph) - tf.import_graph_def(od_graph_def, name = '') - return graph - graph = load_frozen_graph(graph_path) - - new_graph = tf.Graph() - with new_graph.as_default(): - new_input = tf.compat.v1.placeholder(dtype = tf.float32, shape =[None, None, None, 3], name = 'Input') - tf.import_graph_def(graph.as_graph_def(), name = '', input_map ={ 'Input:0': new_input}) - - frozen_file = './new.pb' - with open(frozen_file, 'wb') as f: - f.write(new_graph.as_graph_def().SerializeToString())*/ - var modelLocation = "cifar_model/frozen_model_variadic_input_shape.pb"; + //download the file + string gitPath = "https://github.com/dotnet/machinelearning-testdata/raw/ddf00f8d60ff1b4bb1f3e33639bec318e67fd32e/Microsoft.ML.TensorFlow.TestModels/cifar_model/frozen_model_variadic_input_shape.pb"; + using (WebClient client = new WebClient()) + { + client.DownloadFile(new Uri($"{gitPath}"), "cifar_model/frozen_model_variadic_input_shape.pb"); + } + //frozen_model_variadic_input_shape.pb is modified by frozen_model.pb + //the shape of placeholder is changed from [?, w, h, c] to [?, ?, ?, c] + string modelLocation = "cifar_model/frozen_model_variadic_input_shape.pb"; - var imageHeight = 32; - var imageWidth = 32; - var dataFile = GetDataPath("images/images.tsv"); - var imageFolder = Path.GetDirectoryName(dataFile); + int imageHeight = 32; + int imageWidth = 32; + string dataFile = GetDataPath("images/images.tsv"); + string imageFolder = Path.GetDirectoryName(dataFile); - var data = _mlContext.Data.LoadFromTextFile(dataFile, new[] { + IDataView data = _mlContext.Data.LoadFromTextFile(dataFile, new[] { new TextLoader.Column("imagePath", DataKind.String, 0), new TextLoader.Column("name", DataKind.String, 1) }); - // Note that CamelCase column names are there to match the TF graph node names. var pipeline = _mlContext.Transforms.LoadImages("Input", imageFolder, "imagePath") .Append(_mlContext.Transforms.ResizeImages("Input", imageHeight, imageWidth)) .Append(_mlContext.Transforms.ExtractPixels("Input", interleavePixelColors: true)) .Append(_mlContext.Model.LoadTensorFlowModel(modelLocation).ScoreTensorFlowModel("Output", "Input")); var transformer = pipeline.Fit(data); + + Tensorflow.TensorShape[] tfInputShape = transformer.LastTransformer.TFInputShapes; + + Assert.Equal(imageHeight, tfInputShape.ElementAt(0)[1].dims[0]); + Assert.Equal(imageWidth, tfInputShape.ElementAt(0)[2].dims[0]); } } } From 3af9c63e10a1e6891481d9b75e8aa195bd5ffe24 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Sat, 27 Jun 2020 16:13:34 -0700 Subject: [PATCH 07/12] remove uncessary lines --- .../ScenariosWithDirectInstantiation/TensorflowTests.cs | 2 +- test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs index 2078623348..259a2db787 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs @@ -1905,7 +1905,7 @@ private static string GetTemporaryDirectory() [TensorFlowFact] public void TensorflowPlaceholderShapeInferenceTest() { - //download the file + //download the pb file string gitPath = "https://github.com/dotnet/machinelearning-testdata/raw/ddf00f8d60ff1b4bb1f3e33639bec318e67fd32e/Microsoft.ML.TensorFlow.TestModels/cifar_model/frozen_model_variadic_input_shape.pb"; using (WebClient client = new WebClient()) { diff --git a/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs b/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs index a727f4d14b..8aba9b08a5 100644 --- a/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs +++ b/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs @@ -14,7 +14,6 @@ using Microsoft.ML.TensorFlow; using Xunit; using Xunit.Abstractions; -using static Microsoft.ML.Scenarios.TensorFlowScenariosTests; namespace Microsoft.ML.Tests { From 10f0c7f0a17d7766391e432291386ddc66d5c8d1 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Wed, 1 Jul 2020 11:19:55 -0700 Subject: [PATCH 08/12] fix one of the comment --- .../TensorflowTests.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs index 259a2db787..6842cffd7a 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs @@ -1925,14 +1925,19 @@ public void TensorflowPlaceholderShapeInferenceTest() new TextLoader.Column("name", DataKind.String, 1) }); - var pipeline = _mlContext.Transforms.LoadImages("Input", imageFolder, "imagePath") - .Append(_mlContext.Transforms.ResizeImages("Input", imageHeight, imageWidth)) - .Append(_mlContext.Transforms.ExtractPixels("Input", interleavePixelColors: true)) - .Append(_mlContext.Model.LoadTensorFlowModel(modelLocation).ScoreTensorFlowModel("Output", "Input")); + Tensorflow.TensorShape[] tfInputShape; - var transformer = pipeline.Fit(data); + using (var tfModel = _mlContext.Model.LoadTensorFlowModel(modelLocation)) + { + var pipeline = _mlContext.Transforms.LoadImages("Input", imageFolder, "imagePath") + .Append(_mlContext.Transforms.ResizeImages("Input", imageHeight, imageWidth)) + .Append(_mlContext.Transforms.ExtractPixels("Input", interleavePixelColors: true)) + .Append(tfModel.ScoreTensorFlowModel("Output", "Input")); + + var transformer = pipeline.Fit(data); - Tensorflow.TensorShape[] tfInputShape = transformer.LastTransformer.TFInputShapes; + tfInputShape = transformer.LastTransformer.TFInputShapes; + } Assert.Equal(imageHeight, tfInputShape.ElementAt(0)[1].dims[0]); Assert.Equal(imageWidth, tfInputShape.ElementAt(0)[2].dims[0]); From 7a073766787a865f84dc4d3f56fe0181112e45c9 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Wed, 1 Jul 2020 14:06:37 -0700 Subject: [PATCH 09/12] update tensorflow test data version --- build/Dependencies.props | 2 +- .../ScenariosWithDirectInstantiation/TensorflowTests.cs | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/build/Dependencies.props b/build/Dependencies.props index 903b984a40..8bb8fceb5e 100644 --- a/build/Dependencies.props +++ b/build/Dependencies.props @@ -55,7 +55,7 @@ 3.0.1 0.0.6-test 0.0.6-test - 0.0.11-test + 0.0.12-test 0.0.6-test 4.6.1 1.2.7 diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs index 6842cffd7a..619c56f9c7 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs @@ -1905,12 +1905,6 @@ private static string GetTemporaryDirectory() [TensorFlowFact] public void TensorflowPlaceholderShapeInferenceTest() { - //download the pb file - string gitPath = "https://github.com/dotnet/machinelearning-testdata/raw/ddf00f8d60ff1b4bb1f3e33639bec318e67fd32e/Microsoft.ML.TensorFlow.TestModels/cifar_model/frozen_model_variadic_input_shape.pb"; - using (WebClient client = new WebClient()) - { - client.DownloadFile(new Uri($"{gitPath}"), "cifar_model/frozen_model_variadic_input_shape.pb"); - } //frozen_model_variadic_input_shape.pb is modified by frozen_model.pb //the shape of placeholder is changed from [?, w, h, c] to [?, ?, ?, c] string modelLocation = "cifar_model/frozen_model_variadic_input_shape.pb"; From bd8f2e3f4c3d1f314cfd335cc26b3973e610d479 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Wed, 1 Jul 2020 15:51:04 -0700 Subject: [PATCH 10/12] remove uncessary depencency --- .../ScenariosWithDirectInstantiation/TensorflowTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs index 619c56f9c7..d908ab247c 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs @@ -7,7 +7,6 @@ using System.IO; using System.IO.Compression; using System.Linq; -using System.Net; using System.Runtime.InteropServices; using Microsoft.ML.Data; using Microsoft.ML.Vision; From 8ff47fb6dcd6afa3eec8145111f420920656b33e Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Wed, 1 Jul 2020 16:02:32 -0700 Subject: [PATCH 11/12] fix comments --- src/Microsoft.ML.TensorFlow/TensorflowTransform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs index 030312b90e..6fd0a04d11 100644 --- a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs +++ b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs @@ -532,7 +532,7 @@ public Mapper(TensorFlowTransformer parent, DataViewSchema inputSchema) : //This cover the 2-variable senario e.g. [?,?,?,3] where we can assume typeDims provides the information of [W, H, C] var originalShapeDims = originalShape.dims; var originalShapeNdim = originalShape.ndim; - if (numOfUnkDim == colTypeDims.Length && originalShapeNdim == numOfUnkDim + 1 && colTypeDims.Length == 3) + if (numOfUnkDim == 3 && colTypeDims.Length == 3 && originalShapeNdim == numOfUnkDim + 1) { for (int ishape = 1; ishape < originalShapeNdim; ++ishape) { From 240d35e0288ebb19379c9b9d62b98c58acdbc089 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Wed, 1 Jul 2020 17:06:29 -0700 Subject: [PATCH 12/12] readability --- .../TensorflowTransform.cs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs index 6fd0a04d11..6c46f59b2d 100644 --- a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs +++ b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs @@ -529,20 +529,16 @@ public Mapper(TensorFlowTransformer parent, DataViewSchema inputSchema) : if (typeValueCount % valCount != 0) throw Contracts.Except($"Input shape mismatch: Input '{_parent.Inputs[i]}' has shape {originalShape.ToString()}, but input data is of length {typeValueCount}."); - //This cover the 2-variable senario e.g. [?,?,?,3] where we can assume typeDims provides the information of [W, H, C] + // This cover the 2-variable senario e.g. [?, ?, ?, C] where we can assume typeDims provides the information of [W, H, C] + // The shape will become [?, W, H, C] var originalShapeDims = originalShape.dims; var originalShapeNdim = originalShape.ndim; - if (numOfUnkDim == 3 && colTypeDims.Length == 3 && originalShapeNdim == numOfUnkDim + 1) + if (numOfUnkDim == 3 && colTypeDims.Length == 3 && originalShapeNdim == numOfUnkDim + 1 && originalShapeDims[1] == -1) { - for (int ishape = 1; ishape < originalShapeNdim; ++ishape) - { - if (originalShapeDims[ishape] == -1) - { - originalShapeDims[ishape] = colTypeDims[ishape - 1]; - valCount *= originalShapeDims[ishape]; - numOfUnkDim--; - } - } + originalShapeDims[1] = colTypeDims[0]; + originalShapeDims[2] = colTypeDims[1]; + valCount *= originalShapeDims[1] * originalShapeDims[2]; + numOfUnkDim -= 2; } // If the shape is multi-dimensional, we should be able to create the length of the vector by plugging