Skip to content

Commit 49f3798

Browse files
Merge branch 'master' into featurizers-project
2 parents 3019f8c + 36fab9b commit 49f3798

File tree

75 files changed

+748
-639
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+748
-639
lines changed

Microsoft.ML.sln

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.ML.CodeGenerator"
291291
EndProject
292292
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.Vision", "src\Microsoft.ML.Vision\Microsoft.ML.Vision.csproj", "{419F93D5-4135-4DA0-A76E-EFC23E04093D}"
293293
EndProject
294+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.TestFrameworkCommon", "test\Microsoft.ML.TestFrameworkCommon\Microsoft.ML.TestFrameworkCommon.csproj", "{A22FAD27-77E8-4460-8B92-EC7090B7173A}"
295+
EndProject
294296
Global
295297
GlobalSection(SolutionConfigurationPlatforms) = preSolution
296298
Debug|Any CPU = Debug|Any CPU
@@ -1722,6 +1724,30 @@ Global
17221724
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release-netfx|Any CPU.Build.0 = Release-netfx|Any CPU
17231725
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release-netfx|x64.ActiveCfg = Release-netfx|Any CPU
17241726
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release-netfx|x64.Build.0 = Release-netfx|Any CPU
1727+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1728+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug|Any CPU.Build.0 = Debug|Any CPU
1729+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug|x64.ActiveCfg = Debug|Any CPU
1730+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug|x64.Build.0 = Debug|Any CPU
1731+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug-netcoreapp3_0|Any CPU.ActiveCfg = Debug-netcoreapp3_0|Any CPU
1732+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug-netcoreapp3_0|Any CPU.Build.0 = Debug-netcoreapp3_0|Any CPU
1733+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug-netcoreapp3_0|x64.ActiveCfg = Debug-netcoreapp3_0|Any CPU
1734+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug-netcoreapp3_0|x64.Build.0 = Debug-netcoreapp3_0|Any CPU
1735+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug-netfx|Any CPU.ActiveCfg = Debug-netfx|Any CPU
1736+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug-netfx|Any CPU.Build.0 = Debug-netfx|Any CPU
1737+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug-netfx|x64.ActiveCfg = Debug-netfx|Any CPU
1738+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Debug-netfx|x64.Build.0 = Debug-netfx|Any CPU
1739+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release|Any CPU.ActiveCfg = Release|Any CPU
1740+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release|Any CPU.Build.0 = Release|Any CPU
1741+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release|x64.ActiveCfg = Release|Any CPU
1742+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release|x64.Build.0 = Release|Any CPU
1743+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release-netcoreapp3_0|Any CPU.ActiveCfg = Release-netcoreapp3_0|Any CPU
1744+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release-netcoreapp3_0|Any CPU.Build.0 = Release-netcoreapp3_0|Any CPU
1745+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release-netcoreapp3_0|x64.ActiveCfg = Release-netcoreapp3_0|Any CPU
1746+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release-netcoreapp3_0|x64.Build.0 = Release-netcoreapp3_0|Any CPU
1747+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release-netfx|Any CPU.ActiveCfg = Release-netfx|Any CPU
1748+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release-netfx|Any CPU.Build.0 = Release-netfx|Any CPU
1749+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release-netfx|x64.ActiveCfg = Release-netfx|Any CPU
1750+
{A22FAD27-77E8-4460-8B92-EC7090B7173A}.Release-netfx|x64.Build.0 = Release-netfx|Any CPU
17251751
EndGlobalSection
17261752
GlobalSection(SolutionProperties) = preSolution
17271753
HideSolutionNode = FALSE
@@ -1813,6 +1839,7 @@ Global
18131839
{419F93D5-4135-4DA0-A76E-EFC23E04093D} = {09EADF06-BE25-4228-AB53-95AE3E15B530}
18141840
{E2DD0721-5B0F-4606-8182-4C7EFB834518} = {09EADF06-BE25-4228-AB53-95AE3E15B530}
18151841
{1BA5C784-52E8-4A87-8525-26B2452F2882} = {D3D38B03-B557-484D-8348-8BADEE4DF592}
1842+
{A22FAD27-77E8-4460-8B92-EC7090B7173A} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4}
18161843
EndGlobalSection
18171844
GlobalSection(ExtensibilityGlobals) = postSolution
18181845
SolutionGuid = {41165AF1-35BB-4832-A189-73060F82B01D}

build/BranchInfo.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
Microsoft.ML.TimeSeries;
2020
Microsoft.ML.TensorFlow;
2121
Microsoft.ML.OnnxTransformer;
22+
Microsoft.ML.Vision;
2223
</StableProjects>
2324
<_NormalizedStableProjectName Condition="'$(MSBuildProjectName.Contains(.symbols))' == 'true'">$(MSBuildProjectName.Substring(0, $(MSBuildProjectName.IndexOf(.symbols))))</_NormalizedStableProjectName>
2425
<_NormalizedStableProjectName Condition="'$(_NormalizedStableProjectName)' == ''">$(MSBuildProjectName)</_NormalizedStableProjectName>

src/Microsoft.ML.TensorFlow/TensorflowUtils.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,5 +561,11 @@ public Tensor[] Run()
561561
}
562562

563563
}
564+
internal static string GetTemporaryDirectory()
565+
{
566+
string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
567+
Directory.CreateDirectory(tempDirectory);
568+
return tempDirectory;
569+
}
564570
}
565571
}

src/Microsoft.ML.Vision/ImageClassificationTrainer.cs

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -392,10 +392,10 @@ public sealed class Options : TrainerInputBaseWithLabel
392392
public Action<ImageClassificationMetrics> MetricsCallback = null;
393393

394394
/// <summary>
395-
/// Indicates the path where the newly retrained model should be saved.
395+
/// Indicates the path where the models get downloaded to and cache files saved, default is a new temporary directory
396396
/// </summary>
397-
[Argument(ArgumentType.AtMostOnce, HelpText = "Indicates the path where the newly retrained model should be saved.", SortOrder = 15)]
398-
public string ModelSavePath = null;
397+
[Argument(ArgumentType.AtMostOnce, HelpText = "Indicates the path where the models get downloaded to and cache files saved, default is a new temporary directory.", SortOrder = 15)]
398+
public string WorkspacePath = null;
399399

400400
/// <summary>
401401
/// Indicates to evaluate the model on train set after every epoch.
@@ -422,16 +422,16 @@ public sealed class Options : TrainerInputBaseWithLabel
422422
public IDataView ValidationSet;
423423

424424
/// <summary>
425-
/// Indicates the file path to store trainset bottleneck values for caching.
425+
/// Indicates the file name within the workspace to store trainset bottleneck values for caching.
426426
/// </summary>
427-
[Argument(ArgumentType.AtMostOnce, HelpText = "Indicates the file path to store trainset bottleneck values for caching.", SortOrder = 15)]
428-
public string TrainSetBottleneckCachedValuesFilePath = "trainSetBottleneckFile.csv";
427+
[Argument(ArgumentType.AtMostOnce, HelpText = "Indicates the file name to store trainset bottleneck values for caching.", SortOrder = 15)]
428+
public string TrainSetBottleneckCachedValuesFileName = "trainSetBottleneckFile.csv";
429429

430430
/// <summary>
431-
/// Indicates the file path to store validationset bottleneck values for caching.
431+
/// Indicates the file name within the workspace to store validationset bottleneck values for caching.
432432
/// </summary>
433-
[Argument(ArgumentType.AtMostOnce, HelpText = "Indicates the file path to store validationset bottleneck values for caching.", SortOrder = 15)]
434-
public string ValidationSetBottleneckCachedValuesFilePath = "validationSetBottleneckFile.csv";
433+
[Argument(ArgumentType.AtMostOnce, HelpText = "Indicates the file name to store validationset bottleneck values for caching.", SortOrder = 15)]
434+
public string ValidationSetBottleneckCachedValuesFileName = "validationSetBottleneckFile.csv";
435435

436436
/// <summary>
437437
/// A class that performs learning rate scheduling.
@@ -515,10 +515,26 @@ internal ImageClassificationTrainer(IHostEnvironment env, Options options)
515515
Host.CheckNonEmpty(options.ScoreColumnName, nameof(options.ScoreColumnName));
516516
Host.CheckNonEmpty(options.PredictedLabelColumnName, nameof(options.PredictedLabelColumnName));
517517

518+
if (string.IsNullOrEmpty(options.WorkspacePath))
519+
{
520+
options.WorkspacePath = GetTemporaryDirectory();
521+
}
522+
523+
if (string.IsNullOrEmpty(options.TrainSetBottleneckCachedValuesFileName))
524+
{
525+
//If the user decided to set to null reset back to default value
526+
options.TrainSetBottleneckCachedValuesFileName = _options.TrainSetBottleneckCachedValuesFileName;
527+
}
528+
529+
if (string.IsNullOrEmpty(options.ValidationSetBottleneckCachedValuesFileName))
530+
{
531+
//If the user decided to set to null reset back to default value
532+
options.ValidationSetBottleneckCachedValuesFileName = _options.ValidationSetBottleneckCachedValuesFileName;
533+
}
534+
518535
_options = options;
519536
_useLRScheduling = _options.LearningRateScheduler != null;
520-
_checkpointPath = _options.ModelSavePath ??
521-
Path.Combine(Directory.GetCurrentDirectory(), _options.FinalModelPrefix +
537+
_checkpointPath = Path.Combine(_options.WorkspacePath, _options.FinalModelPrefix +
522538
ModelFileName[_options.Arch]);
523539

524540
// Configure bottleneck tensor based on the model.
@@ -558,7 +574,7 @@ private void InitializeTrainingGraph(IDataView input)
558574

559575
_classCount = labelCount == 1 ? 2 : (int)labelCount;
560576
var imageSize = ImagePreprocessingSize[_options.Arch];
561-
_session = LoadTensorFlowSessionFromMetaGraph(Host, _options.Arch).Session;
577+
_session = LoadTensorFlowSessionFromMetaGraph(Host, _options.Arch, _options.WorkspacePath).Session;
562578
(_jpegData, _resizedImage) = AddJpegDecoding(imageSize.Item1, imageSize.Item2, 3);
563579
_jpegDataTensorName = _jpegData.name;
564580
_resizedImageTensorName = _resizedImage.name;
@@ -604,12 +620,14 @@ private protected override ImageClassificationModelParameters TrainModelCore(Tra
604620
var validationSet = trainContext.ValidationSet?.Data ?? _options.ValidationSet;
605621
var imageProcessor = new ImageProcessor(_session, _jpegDataTensorName, _resizedImageTensorName);
606622
int trainingsetSize = -1;
623+
string trainSetBottleneckCachedValuesFilePath = Path.Combine(_options.WorkspacePath, _options.TrainSetBottleneckCachedValuesFileName);
624+
string validationSetBottleneckCachedValuesFilePath = Path.Combine(_options.WorkspacePath, _options.ValidationSetBottleneckCachedValuesFileName);
607625
if (!_options.ReuseTrainSetBottleneckCachedValues ||
608-
!File.Exists(_options.TrainSetBottleneckCachedValuesFilePath))
626+
!File.Exists(trainSetBottleneckCachedValuesFilePath))
609627
{
610628
trainingsetSize = CacheFeaturizedImagesToDisk(trainContext.TrainingSet.Data, _options.LabelColumnName,
611629
_options.FeatureColumnName, imageProcessor,
612-
_inputTensorName, _bottleneckTensor.name, _options.TrainSetBottleneckCachedValuesFilePath,
630+
_inputTensorName, _bottleneckTensor.name, trainSetBottleneckCachedValuesFilePath,
613631
ImageClassificationMetrics.Dataset.Train, _options.MetricsCallback);
614632

615633
// Write training set size to a file for use during training
@@ -618,16 +636,16 @@ private protected override ImageClassificationModelParameters TrainModelCore(Tra
618636

619637
if (validationSet != null &&
620638
(!_options.ReuseTrainSetBottleneckCachedValues ||
621-
!File.Exists(_options.ValidationSetBottleneckCachedValuesFilePath)))
639+
!File.Exists(validationSetBottleneckCachedValuesFilePath)))
622640
{
623641
CacheFeaturizedImagesToDisk(validationSet, _options.LabelColumnName,
624642
_options.FeatureColumnName, imageProcessor, _inputTensorName, _bottleneckTensor.name,
625-
_options.ValidationSetBottleneckCachedValuesFilePath,
643+
validationSetBottleneckCachedValuesFilePath,
626644
ImageClassificationMetrics.Dataset.Validation, _options.MetricsCallback);
627645
}
628646

629-
TrainAndEvaluateClassificationLayer(_options.TrainSetBottleneckCachedValuesFilePath, _options,
630-
_options.ValidationSetBottleneckCachedValuesFilePath, trainingsetSize);
647+
TrainAndEvaluateClassificationLayer(trainSetBottleneckCachedValuesFilePath, _options,
648+
validationSetBottleneckCachedValuesFilePath, trainingsetSize);
631649

632650
// Leave the ownership of _session so that it is not disposed/closed when this object goes out of scope
633651
// since it will be used by ImageClassificationModelParameters class (new owner that will take care of
@@ -858,7 +876,7 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath,
858876
Saver trainSaver = null;
859877
FileWriter trainWriter = null;
860878
Tensor merged = tf.summary.merge_all();
861-
trainWriter = tf.summary.FileWriter(Path.Combine(Directory.GetCurrentDirectory(), "train"),
879+
trainWriter = tf.summary.FileWriter(Path.Combine(_options.WorkspacePath, "train"),
862880
_session.graph);
863881

864882
trainSaver = tf.train.Saver();
@@ -1109,7 +1127,7 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath,
11091127

11101128
private (Session, Tensor, Tensor, Tensor) BuildEvaluationSession(int classCount)
11111129
{
1112-
var evalGraph = LoadMetaGraph(ModelFileName[_options.Arch]);
1130+
var evalGraph = LoadMetaGraph(Path.Combine(_options.WorkspacePath, ModelFileName[_options.Arch]));
11131131
var evalSess = tf.Session(graph: evalGraph);
11141132
Tensor evaluationStep = null;
11151133
Tensor prediction = null;
@@ -1267,20 +1285,25 @@ private void AddTransferLearningLayer(string labelColumn,
12671285

12681286
}
12691287

1270-
private static TensorFlowSessionWrapper LoadTensorFlowSessionFromMetaGraph(IHostEnvironment env, Architecture arch)
1288+
private static TensorFlowSessionWrapper LoadTensorFlowSessionFromMetaGraph(IHostEnvironment env, Architecture arch, string path)
12711289
{
1290+
if (string.IsNullOrEmpty(path))
1291+
{
1292+
path = GetTemporaryDirectory();
1293+
}
1294+
12721295
var modelFileName = ModelFileName[arch];
1296+
var modelFilePath = Path.Combine(path, modelFileName);
12731297
int timeout = 10 * 60 * 1000;
1274-
string currentDirectory = Directory.GetCurrentDirectory();
1275-
DownloadIfNeeded(env, modelFileName, currentDirectory, modelFileName, timeout);
1298+
DownloadIfNeeded(env, modelFileName, path, modelFileName, timeout);
12761299
if (arch == Architecture.InceptionV3)
12771300
{
1278-
DownloadIfNeeded(env, @"tfhub_modules.zip", currentDirectory, @"tfhub_modules.zip", timeout);
1301+
DownloadIfNeeded(env, @"tfhub_modules.zip", path, @"tfhub_modules.zip", timeout);
12791302
if (!Directory.Exists(@"tfhub_modules"))
1280-
ZipFile.ExtractToDirectory(Path.Combine(currentDirectory, @"tfhub_modules.zip"), @"tfhub_modules");
1303+
ZipFile.ExtractToDirectory(Path.Combine(path, @"tfhub_modules.zip"), @"tfhub_modules");
12811304
}
12821305

1283-
return new TensorFlowSessionWrapper(GetSession(env, modelFileName, true), modelFileName);
1306+
return new TensorFlowSessionWrapper(GetSession(env, modelFilePath, true), modelFilePath);
12841307
}
12851308

12861309
~ImageClassificationTrainer()

src/Microsoft.ML.Vision/Microsoft.ML.Vision.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<IncludeInPackage>Microsoft.ML.Vision</IncludeInPackage>
66
<DefineConstants>CORECLR</DefineConstants>
77
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
8+
<RunApiCompat>false</RunApiCompat>
89
</PropertyGroup>
910

1011
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

test/Microsoft.ML.AutoML.Tests/AutoFitTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Runtime.InteropServices;
99
using Microsoft.ML.Data;
1010
using Microsoft.ML.RunTests;
11+
using Microsoft.ML.TestFrameworkCommon;
1112
using Microsoft.ML.TestFramework.Attributes;
1213
using Xunit;
1314
using static Microsoft.ML.DataOperationsCatalog;

test/Microsoft.ML.Benchmarks/ImageClassificationBench.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ namespace Microsoft.ML.Benchmarks
2020
[Config(typeof(TrainConfig))]
2121
public class ImageClassificationBench
2222
{
23-
private string assetsPath;
2423
private MLContext mlContext;
2524
private IDataView trainDataset;
2625
private IDataView testDataset;
@@ -36,7 +35,7 @@ public void SetupData()
3635
* level up to prevent issues with saving data.
3736
*/
3837
string assetsRelativePath = @"../../../../assets";
39-
assetsPath = GetAbsolutePath(assetsRelativePath);
38+
string assetsPath = GetAbsolutePath(assetsRelativePath);
4039

4140
var outputMlNetModelFilePath = Path.Combine(assetsPath, "outputs",
4241
"imageClassifier.zip");
@@ -87,8 +86,7 @@ public TransformerChain<KeyToValueMappingTransformer> TrainResnetV250()
8786
BatchSize = 10,
8887
LearningRate = 0.01f,
8988
EarlyStoppingCriteria = new ImageClassificationTrainer.EarlyStopping(minDelta: 0.001f, patience: 20, metric: ImageClassificationTrainer.EarlyStoppingMetric.Loss),
90-
ValidationSet = testDataset,
91-
ModelSavePath = assetsPath
89+
ValidationSet = testDataset
9290
};
9391
var pipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(options)
9492
.Append(mlContext.Transforms.Conversion.MapKeyToValue(

test/Microsoft.ML.Benchmarks/Numeric/Ranking.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
using BenchmarkDotNet.Attributes;
77
using Microsoft.ML.Data;
88
using Microsoft.ML.Trainers.LightGbm;
9-
using Microsoft.ML.RunTests;
109
using Microsoft.ML.TestFramework;
1110
using Microsoft.ML.Trainers;
1211
using Microsoft.ML.Trainers.FastTree;
1312
using Microsoft.ML.Transforms;
13+
using Microsoft.ML.TestFrameworkCommon;
1414

1515
namespace Microsoft.ML.Benchmarks
1616
{

test/Microsoft.ML.Benchmarks/RffTransform.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Microsoft.ML.Data;
99
using Microsoft.ML.RunTests;
1010
using Microsoft.ML.TestFramework;
11+
using Microsoft.ML.TestFrameworkCommon;
1112
using Microsoft.ML.Transforms;
1213

1314
namespace Microsoft.ML.Benchmarks

test/Microsoft.ML.Benchmarks/Text/MultiClassClassification.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Microsoft.ML.TestFramework;
1111
using Microsoft.ML.Trainers;
1212
using Microsoft.ML.Transforms;
13+
using Microsoft.ML.TestFrameworkCommon;
1314

1415
namespace Microsoft.ML.Benchmarks
1516
{

0 commit comments

Comments
 (0)