Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
1007955
building transform from ground up
abgoswam Sep 6, 2018
40fbedc
dummy transform works after fixing the getters
abgoswam Sep 6, 2018
48d14c6
SavedModel format works for Train, but fails for Save&Predict
abgoswam Sep 6, 2018
35ff43a
remove dummy transform
abgoswam Sep 6, 2018
6291d0d
remove dummy unit test
abgoswam Sep 7, 2018
57508d3
Works with non-frozen models
abgoswam Sep 7, 2018
cfcd70f
building transform from ground up
abgoswam Sep 6, 2018
236de73
dummy transform works after fixing the getters
abgoswam Sep 6, 2018
781cff0
SavedModel format works for Train, but fails for Save&Predict
abgoswam Sep 6, 2018
07b15a0
remove dummy transform
abgoswam Sep 6, 2018
47f75b5
remove dummy unit test
abgoswam Sep 7, 2018
c304257
Merge branch 'abgoswam/tf_savedmodel' of https://github.com/abgoswam/…
abgoswam Sep 7, 2018
d0430b5
merge with master
abgoswam Sep 7, 2018
950a210
fix compilation issues; verify existing tests work fine
abgoswam Sep 7, 2018
97eb497
works locally; need to refactor code
abgoswam Sep 8, 2018
173729f
refactored code; keeping only 1 version of the convenience API
abgoswam Sep 10, 2018
292140b
Merge branch 'master' into abgoswam/tf_savedmodel
abgoswam Sep 10, 2018
655a8aa
added class for directory structure
abgoswam Sep 11, 2018
be5285a
using latest nuget package (0.0.3) for Microsoft.ML.TensorFlow.TestMo…
abgoswam Sep 11, 2018
46c04a3
delete temporary files used when loading/saving models
abgoswam Sep 11, 2018
e705f93
delete local models; the updated nuget version (0.0.3) for Microsoft.…
abgoswam Sep 11, 2018
84214e2
modified logic for load/restore of models
abgoswam Sep 12, 2018
04d02b8
modified logic for load&restore of unfrozen models
abgoswam Sep 13, 2018
89693bd
merge with latest dotnet/master
abgoswam Sep 13, 2018
8c8d92e
model version update to support non-frozen models
abgoswam Sep 13, 2018
d8edc64
based on the code review comments, we now infer if the provided model…
abgoswam Sep 13, 2018
eea524e
simplify the logic in Save() related to loading of SavedModel.
abgoswam Sep 13, 2018
b609ffd
trying Eric's suggestion
abgoswam Sep 13, 2018
74b8899
revert back to previous changes
abgoswam Sep 13, 2018
3382a83
attempt to use stream copy approach instead of in-memory
abgoswam Sep 14, 2018
aa8e844
taking care of some code review comments
abgoswam Sep 14, 2018
25b1e64
deleting some commented out code
abgoswam Sep 14, 2018
e32acca
Ensure we only copy the file segment & cleanup path logic
ericstj Sep 14, 2018
ac45539
added finalizer that closes the session (if it isn't closed) and dele…
abgoswam Sep 14, 2018
ce4efef
move away from using Dictionary<string, byte[]> and instead use strea…
abgoswam Sep 14, 2018
8b8764b
cleanup + misc review comments
abgoswam Sep 15, 2018
f955488
Merge branch 'master' into abgoswam/tf_savedmodel
abgoswam Sep 17, 2018
6e11f2c
trying to create temp dir with proper ACLs for high priviledge users
abgoswam Sep 19, 2018
ed71513
create temp dir with proper ACLs for high-privilege processes
abgoswam Sep 19, 2018
7df343d
Merge branch 'master' into abgoswam/tf_savedmodel
abgoswam Sep 19, 2018
f883d78
fix build after merge with latest master
abgoswam Sep 19, 2018
ae672d6
taking care of review comments related to model versioning of TFTrans…
abgoswam Sep 19, 2018
fac8dae
remove IDisposable from the TensorFlowTransform; renaming some methods
abgoswam Sep 20, 2018
2b1a576
refactor code so we have only 1 constructor for the TensorFlowTransfo…
abgoswam Sep 20, 2018
21879f6
merge with latest master
abgoswam Sep 20, 2018
a1d912d
fix issues with nuget packaging; refactored the code + added comments
abgoswam Sep 21, 2018
f6a1c84
add checks in code to make sure that the input is not a variable leng…
abgoswam Sep 21, 2018
5957c53
merge with latest master
abgoswam Sep 22, 2018
5120bb9
fix typo in name of package
abgoswam Sep 22, 2018
a624a3b
(1) added SavedModel test for MNIST model (2) added try/finally for d…
abgoswam Sep 24, 2018
8d9fdc5
remove and sort usings in file TrainSaveModelAndPredict.cs
abgoswam Sep 24, 2018
685ab99
using spaces in nupkgproj
abgoswam Sep 25, 2018
2d0ec1e
error checking for passed in IHostEnvironment
abgoswam Sep 25, 2018
8d8b986
fix TargetFramework version (netcore 2.0) of DnnAnalyzer to match tha…
abgoswam Sep 25, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Microsoft.ML.TensorFlow/TensorFlow/Tensorflow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,7 @@ public IEnumerable<DeviceAttributes> ListDevices(TFStatus status = null)
/// here: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/README.md
/// </para>
/// </remarks>
public TFSession FromSavedModel(TFSessionOptions sessionOptions, TFBuffer runOptions, string exportDir, string[] tags, TFGraph graph, TFBuffer metaGraphDef, TFStatus status = null)
public static TFSession FromSavedModel(TFSessionOptions sessionOptions, TFBuffer runOptions, string exportDir, string[] tags, TFGraph graph, TFBuffer metaGraphDef, TFStatus status = null)
{
if (graph == null)
throw new ArgumentNullException(nameof(graph));
Expand Down
195 changes: 141 additions & 54 deletions src/Microsoft.ML.TensorFlow/TensorflowTransform.cs

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions src/Microsoft.ML/CSharpApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15785,9 +15785,14 @@ public sealed partial class TensorFlowScorer : Microsoft.ML.Runtime.EntryPoints.


/// <summary>
/// This is the frozen protobuf model file. Please see https://www.tensorflow.org/mobile/prepare_models for more details.
/// TensorFlow model used by the transform. Please see https://www.tensorflow.org/mobile/prepare_models for more details.
/// </summary>
public string ModelFile { get; set; }
public string Model { get; set; }

/// <summary>
/// Indicator for frozen models
/// </summary>
public bool IsFrozen { get; set; } = true;

/// <summary>
/// The names of the model inputs
Expand Down
37 changes: 23 additions & 14 deletions test/BaselineOutput/Common/EntryPoints/core_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -21716,14 +21716,31 @@
"ShortName": "TFTransform",
"Inputs": [
{
"Name": "ModelFile",
"Name": "Model",
"Type": "String",
"Desc": "This is the frozen protobuf model file. Please see https://www.tensorflow.org/mobile/prepare_models for more details.",
"Desc": "TensorFlow model used by the transform. Please see https://www.tensorflow.org/mobile/prepare_models for more details.",
"Required": true,
"SortOrder": 0.0,
"IsNullable": false
},
{
"Name": "IsFrozen",
"Type": "Bool",
"Desc": "Indicator for frozen models",
"Aliases": [
"model"
"frozen"
],
"Required": false,
"SortOrder": 1.0,
"IsNullable": false,
"Default": true
},
{
"Name": "Data",
"Type": "DataView",
"Desc": "Input dataset",
"Required": true,
"SortOrder": 0.0,
"SortOrder": 1.0,
"IsNullable": false
},
{
Expand All @@ -21737,15 +21754,7 @@
"inputs"
],
"Required": true,
"SortOrder": 1.0,
"IsNullable": false
},
{
"Name": "Data",
"Type": "DataView",
"Desc": "Input dataset",
"Required": true,
"SortOrder": 1.0,
"SortOrder": 2.0,
"IsNullable": false
},
{
Expand All @@ -21759,7 +21768,7 @@
"outputs"
],
"Required": true,
"SortOrder": 2.0,
"SortOrder": 3.0,
"IsNullable": false
}
],
Expand Down
2 changes: 1 addition & 1 deletion test/Microsoft.ML.Core.Tests/UnitTests/TestCSharpApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -977,9 +977,9 @@ public void TestTensorFlowEntryPoint()
var tfTransformInput = new ML.Transforms.TensorFlowScorer
{
Data = importOutput.Data,
Model = "mnist_model/frozen_saved_model.pb",
InputColumns = new[] { "Placeholder" },
OutputColumns = new[] { "Softmax" },
ModelFile = "mnist_model/frozen_saved_model.pb"
};
var tfTransformOutput = experiment.Add(tfTransformInput);

Expand Down
2 changes: 1 addition & 1 deletion test/Microsoft.ML.Core.Tests/UnitTests/TestEntryPoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3741,7 +3741,7 @@ public void EntryPointTensorFlowTransform()
new[]
{
@"'InputColumns': [ 'Placeholder' ],
'ModelFile': 'mnist_model/frozen_saved_model.pb',
'Model': 'mnist_model/frozen_saved_model.pb',
'OutputColumns': [ 'Softmax' ]"
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
// See the LICENSE file in the project root for more information.

using Microsoft.ML.Data;
using Microsoft.ML.Scenarios;
using Microsoft.ML.Trainers;
using Microsoft.ML.Transforms;
using Microsoft.ML.Transforms.TensorFlow;
using System.IO;
using Xunit;

namespace Microsoft.ML.Tests.Scenarios.PipelineApi
Expand Down Expand Up @@ -38,5 +41,81 @@ public async void TrainSaveModelAndPredict()
Assert.True(singlePrediction.Sentiment);

}

[Fact]
public async void TensorFlowTransformTrainSaveModelAndPredict()
{
var imageHeight = 32;
var imageWidth = 32;
var model_location = "cifar_saved_model";
var dataFile = GetDataPath("images/images.tsv");
var imageFolder = Path.GetDirectoryName(dataFile);

var pipeline = new LearningPipeline(seed: 1);
pipeline.Add(new TextLoader(dataFile).CreateFrom<CifarData>(useHeader: false));
pipeline.Add(new ImageLoader(("ImagePath", "ImageReal"))
{
ImageFolder = imageFolder
});

pipeline.Add(new ImageResizer(("ImageReal", "ImageCropped"))
{
ImageHeight = imageHeight,
ImageWidth = imageWidth,
Resizing = ImageResizerTransformResizingKind.IsoCrop
});

pipeline.Add(new ImagePixelExtractor(("ImageCropped", "Input"))
{
UseAlpha = false,
InterleaveArgb = true
});

pipeline.Add(new TensorFlowScorer()
{
Model = model_location,
IsFrozen = false,
InputColumns = new[] { "Input" },
OutputColumns = new[] { "Output" },
});

pipeline.Add(new ColumnConcatenator(outputColumn: "Features", "Output"));
pipeline.Add(new TextToKeyConverter("Label"));
pipeline.Add(new StochasticDualCoordinateAscentClassifier());

TensorFlowUtils.Initialize();
var model = pipeline.Train<CifarData, CifarPrediction>();

var modelName = "tf_TrainSaveAndPredictdModel.zip";
DeleteOutputPath(modelName);
await model.WriteAsync(modelName);

var loadedModel = await PredictionModel.ReadAsync<CifarData, CifarPrediction>(modelName);

string[] scoreLabels;
loadedModel.TryGetScoreLabelNames(out scoreLabels);

Assert.NotNull(scoreLabels);
Assert.Equal(3, scoreLabels.Length);
Assert.Equal("banana", scoreLabels[0]);
Assert.Equal("hotdog", scoreLabels[1]);
Assert.Equal("tomato", scoreLabels[2]);

CifarPrediction prediction = loadedModel.Predict(new CifarData()
{
ImagePath = GetDataPath("images/banana.jpg")
});
Assert.Equal(1, prediction.PredictedLabels[0], 2);
Assert.Equal(0, prediction.PredictedLabels[1], 2);
Assert.Equal(0, prediction.PredictedLabels[2], 2);

prediction = loadedModel.Predict(new CifarData()
{
ImagePath = GetDataPath("images/hotdog.jpg")
});
Assert.Equal(0, prediction.PredictedLabels[0], 2);
Assert.Equal(1, prediction.PredictedLabels[1], 2);
Assert.Equal(0, prediction.PredictedLabels[2], 2);
}
}
}
2 changes: 1 addition & 1 deletion test/Microsoft.ML.Tests/Scenarios/TensorflowTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void TensorFlowTransformCifarLearningPipelineTest()

pipeline.Add(new TensorFlowScorer()
{
ModelFile = model_location,
Model = model_location,
InputColumns = new[] { "Input" },
OutputColumns = new[] { "Output" }
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void TensorFlowTransformMatrixMultiplicationTest()
b = new[] { 3.0f, 3.0f,
3.0f, 3.0f } } }));

var trans = TensorFlowTransform.Create(env, loader, model_location, "c", "a", "b");
var trans = TensorFlowTransform.Create(env, loader, model_location, new[] { "c" }, new[] { "a", "b" });

using (var cursor = trans.GetRowCursor(a => true))
{
Expand Down Expand Up @@ -202,7 +202,61 @@ public void TensorFlowTransformCifar()
}, cropped);


IDataView trans = TensorFlowTransform.Create(env, pixels, model_location, "Output", "Input");
IDataView trans = TensorFlowTransform.Create(env, pixels, model_location, new[] { "Output" }, new[] { "Input" });

trans.Schema.TryGetColumnIndex("Output", out int output);
using (var cursor = trans.GetRowCursor(col => col == output))
{
var buffer = default(VBuffer<float>);
var getter = cursor.GetGetter<VBuffer<float>>(output);
var numRows = 0;
while (cursor.MoveNext())
{
getter(ref buffer);
Assert.Equal(10, buffer.Length);
numRows += 1;
}
Assert.Equal(3, numRows);
}
}
}

[Fact]
public void TensorFlowTransformCifarSavedModel()
{
var model_location = "cifar_saved_model";

using (var env = new TlcEnvironment())
{
var imageHeight = 32;
var imageWidth = 32;
var dataFile = GetDataPath("images/images.tsv");
var imageFolder = Path.GetDirectoryName(dataFile);
var data = env.CreateLoader("Text{col=ImagePath:TX:0 col=Name:TX:1}", new MultiFileSource(dataFile));
var images = ImageLoaderTransform.Create(env, new ImageLoaderTransform.Arguments()
{
Column = new ImageLoaderTransform.Column[1]
{
new ImageLoaderTransform.Column() { Source= "ImagePath", Name="ImageReal" }
},
ImageFolder = imageFolder
}, data);
var cropped = ImageResizerTransform.Create(env, new ImageResizerTransform.Arguments()
{
Column = new ImageResizerTransform.Column[1]{
new ImageResizerTransform.Column() { Source = "ImageReal", Name= "ImageCropped", ImageHeight =imageHeight, ImageWidth = imageWidth, Resizing = ImageResizerTransform.ResizingKind.IsoCrop}
}
}, images);

var pixels = ImagePixelExtractorTransform.Create(env, new ImagePixelExtractorTransform.Arguments()
{
Column = new ImagePixelExtractorTransform.Column[1]{
new ImagePixelExtractorTransform.Column() { Source= "ImageCropped", Name = "Input", UseAlpha=false, InterleaveArgb=true}
}
}, cropped);


IDataView trans = TensorFlowTransform.Create(env, pixels, model_location, new[] { "Output" }, new[] { "Input" }, false);

trans.Schema.TryGetColumnIndex("Output", out int output);
using (var cursor = trans.GetRowCursor(col => col == output))
Expand Down Expand Up @@ -259,7 +313,7 @@ public void TensorFlowTransformCifarInvalidShape()
var thrown = false;
try
{
IDataView trans = TensorFlowTransform.Create(env, pixels, model_location, "Output", "Input");
IDataView trans = TensorFlowTransform.Create(env, pixels, model_location, new[] { "Output" }, new[] { "Input" });
}
catch
{
Expand Down