From f3f3125096ffbb9ea941a48476eecbe6eb64b6bc Mon Sep 17 00:00:00 2001 From: Mustafa Bal <5262061+mstfbl@users.noreply.github.com> Date: Wed, 24 Jun 2020 02:11:47 -0700 Subject: [PATCH 1/8] Added cross entropy to validation training, simplified metric reporting --- .../ImageClassificationTrainer.cs | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs index 79973cd23b..b7edf6192f 100644 --- a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs +++ b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs @@ -169,12 +169,8 @@ public sealed class TrainMetrics /// public override string ToString() { - if (DatasetUsed == ImageClassificationMetrics.Dataset.Train) - return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}, Learning Rate: {LearningRate,10} " + - $"Epoch: {Epoch,3}, Accuracy: {Accuracy,10}, Cross-Entropy: {CrossEntropy,10}"; - else - return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}, " + - $"Epoch: {Epoch,3}, Accuracy: {Accuracy,10}"; + return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}, Learning Rate: {LearningRate,10} " + + $"Epoch: {Epoch,3}, Accuracy: {Accuracy,10}, Cross-Entropy: {CrossEntropy,10}"; } } @@ -951,8 +947,9 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath, if (validationNeeded) { - validationEvalRunner = new Runner(_session, new[] { _bottleneckInput.name, _labelTensor.name }, - new[] { _evaluationStep.name }); + validationEvalRunner = new Runner(_session, runnerInputTensorNames.ToArray(), + runnerOutputTensorNames.Count() > 0 ? runnerOutputTensorNames.ToArray() : null, + new[] { _trainStep.name }); } runner = new Runner(_session, runnerInputTensorNames.ToArray(), @@ -1029,21 +1026,25 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath, // Evaluate. TrainAndEvaluateClassificationLayerCore(epoch, learningRate, featureFileStartOffset, - metrics, labelTensorShape, featureTensorShape, batchSize, - validationSetLabelReader, validationSetFeatureReader, labelBuffer, featuresBuffer, - labelBufferSizeInBytes, featureBufferSizeInBytes, featureFileRecordSize, null, + metrics, labelTensorShape, featureTensorShape, batchSize, validationSetLabelReader, + validationSetFeatureReader, labelBuffer, featuresBuffer, labelBufferSizeInBytes, + featureBufferSizeInBytes, featureFileRecordSize, _options.LearningRateScheduler, trainState, validationEvalRunner, featureBufferPtr, labelBufferPtr, (outputTensors, metrics) => { outputTensors[0].ToScalar(ref accuracy); + outputTensors[1].ToScalar(ref crossentropy); metrics.Train.Accuracy += accuracy; + metrics.Train.CrossEntropy += crossentropy; outputTensors[0].Dispose(); + outputTensors[1].Dispose(); }); if (statisticsCallback != null) { metrics.Train.Epoch = epoch; metrics.Train.Accuracy /= metrics.Train.BatchProcessedCount; + metrics.Train.CrossEntropy /= metrics.Train.BatchProcessedCount; metrics.Train.DatasetUsed = ImageClassificationMetrics.Dataset.Validation; statisticsCallback(metrics); } From bdcddf34c7982e721fe7270f07f24c1afb0a12f2 Mon Sep 17 00:00:00 2001 From: Mustafa Bal <5262061+mstfbl@users.noreply.github.com> Date: Thu, 25 Jun 2020 04:17:34 -0700 Subject: [PATCH 2/8] Edited runnerOutputTensorNames for validation runner, and added test for decaying LR in validation --- .../ImageClassificationTrainer.cs | 3 +-- .../TensorflowTests.cs | 13 ++++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs index b7edf6192f..a043cadb6b 100644 --- a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs +++ b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs @@ -948,8 +948,7 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath, if (validationNeeded) { validationEvalRunner = new Runner(_session, runnerInputTensorNames.ToArray(), - runnerOutputTensorNames.Count() > 0 ? runnerOutputTensorNames.ToArray() : null, - new[] { _trainStep.name }); + new[] { _evaluationStep.name, _crossEntropy.name }, new[] { _trainStep.name }); } runner = new Runner(_session, runnerInputTensorNames.ToArray(), diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs index 5130391d23..a55a0e820e 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs @@ -1532,7 +1532,18 @@ internal void TensorFlowImageClassificationWithLRScheduling(LearningRateSchedule Epoch = epoch, BatchSize = 10, LearningRate = 0.01f, - MetricsCallback = (metric) => Console.WriteLine(metric), + MetricsCallback = (metric) => + { + //Check that learning rate in metrics from both the training and validation phases decays + if (metric.Train != null) + { + // At epoch 50, validation training starts with default learning rate, which decays + // at each successive epoch + if (epoch > 1 && epoch != 50) + Assert.True(metric.Train.LearningRate < 0.01f); + } + Console.WriteLine(metric); + }, ValidationSet = validationSet, WorkspacePath = workspacePath, TrainSetBottleneckCachedValuesFileName = trainSetBottleneckCachedValuesFileName, From 63058ba6f306cf2b4cdc07b3f9b8cb5d265307ba Mon Sep 17 00:00:00 2001 From: Mustafa Bal <5262061+mstfbl@users.noreply.github.com> Date: Thu, 25 Jun 2020 15:06:09 -0700 Subject: [PATCH 3/8] Added more tests to validate learning rate schedulers in validation and training --- .../TensorflowTests.cs | 72 ++++++++++++++++--- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs index a55a0e820e..b61e61e338 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs @@ -1483,17 +1483,19 @@ public void TensorFlowImageClassification(ImageClassificationTrainer.Architectur [TensorFlowFact] public void TensorFlowImageClassificationWithExponentialLRScheduling() { - TensorFlowImageClassificationWithLRScheduling(new ExponentialLRDecay(), 50); + ExponentialLRDecay exponentialLRDecay = new ExponentialLRDecay(); + TensorFlowImageClassificationWithLRScheduling(exponentialLRDecay, 50, (int)exponentialLRDecay.NumEpochsPerDecay); } [TensorFlowFact] public void TensorFlowImageClassificationWithPolynomialLRScheduling() { - - TensorFlowImageClassificationWithLRScheduling(new PolynomialLRDecay(), 50); + PolynomialLRDecay polynomialLRDecay = new PolynomialLRDecay(); + TensorFlowImageClassificationWithLRScheduling(polynomialLRDecay, 50, (int)polynomialLRDecay.NumEpochsPerDecay, polynomialLRDecay.EndLearningRate); } - internal void TensorFlowImageClassificationWithLRScheduling(LearningRateScheduler learningRateScheduler, int epoch) + internal void TensorFlowImageClassificationWithLRScheduling( + LearningRateScheduler learningRateScheduler, int epoch, int numEpochsPerDecay, float endLearningRate = 0.0f) { //Load all the original images info IEnumerable images = LoadImagesFromDirectory( @@ -1521,6 +1523,11 @@ internal void TensorFlowImageClassificationWithLRScheduling(LearningRateSchedule var (trainSetBottleneckCachedValuesFileName, validationSetBottleneckCachedValuesFileName, workspacePath, isReuse) = getInitialParameters(ImageClassificationTrainer.Architecture.ResnetV2101, _finalImagesFolderName); + float[] learningRatesTraining = new float[epoch]; + float[] learningRatesValidation = new float[epoch]; + float[] crossEntropyTraining = new float[epoch]; + float[] crossEntropyValidation = new float[epoch]; + float baseLearningRate = 0.01f; var options = new ImageClassificationTrainer.Options() { FeatureColumnName = "Image", @@ -1531,16 +1538,61 @@ internal void TensorFlowImageClassificationWithLRScheduling(LearningRateSchedule Arch = ImageClassificationTrainer.Architecture.ResnetV2101, Epoch = epoch, BatchSize = 10, - LearningRate = 0.01f, + LearningRate = baseLearningRate, MetricsCallback = (metric) => { - //Check that learning rate in metrics from both the training and validation phases decays + // Check that learning rates in metrics from both the training and validation phases decay and are sensible if (metric.Train != null) { - // At epoch 50, validation training starts with default learning rate, which decays - // at each successive epoch - if (epoch > 1 && epoch != 50) - Assert.True(metric.Train.LearningRate < 0.01f); + if (metric.Train.Epoch > 1) + { + Assert.InRange(metric.Train.LearningRate, 0, baseLearningRate); + Assert.True(metric.Train.CrossEntropy > 0); + } + // Save learning rate and cross entropy values in training phase + if (metric.Train.DatasetUsed == ImageClassificationTrainer.ImageClassificationMetrics.Dataset.Train) + { + learningRatesTraining[metric.Train.Epoch] = metric.Train.LearningRate; + crossEntropyTraining[metric.Train.Epoch] = metric.Train.CrossEntropy; + // Check that learning rates over each epoch-per-decay are decreasing, and that cross entropy is also decreasing + if (metric.Train.Epoch > 1) + { + // Testing PolynomialLRDecay training + if (endLearningRate != 0.0) + { + Assert.True(learningRatesTraining[metric.Train.Epoch - numEpochsPerDecay] > learningRatesTraining[metric.Train.Epoch] + || learningRatesTraining[metric.Train.Epoch] == endLearningRate); + } + // Testing ExponentialLRDecay training + else + { + Assert.True(learningRatesTraining[metric.Train.Epoch - numEpochsPerDecay] > learningRatesTraining[metric.Train.Epoch]); + } + Assert.True(crossEntropyTraining[metric.Train.Epoch - numEpochsPerDecay] > crossEntropyTraining[metric.Train.Epoch]); + } + } + // Save learning rate and cross entropy values in validation phase + else + { + learningRatesValidation[metric.Train.Epoch] = metric.Train.LearningRate; + crossEntropyValidation[metric.Train.Epoch] = metric.Train.CrossEntropy; + // Check that learning rates over each epoch-per-decay are decreasing, and that cross entropy is also decreasing + if (metric.Train.Epoch > 1) + { + // Testing PolynomialLRDecay validation + if (endLearningRate != 0.0) + { + Assert.True(learningRatesValidation[metric.Train.Epoch - numEpochsPerDecay] > learningRatesValidation[metric.Train.Epoch] + || learningRatesValidation[metric.Train.Epoch] == endLearningRate); + } + // Testing ExponentialLRDecay validation + else + { + Assert.True(learningRatesValidation[metric.Train.Epoch - numEpochsPerDecay] > learningRatesValidation[metric.Train.Epoch]); + } + Assert.True(crossEntropyValidation[metric.Train.Epoch - numEpochsPerDecay] > crossEntropyValidation[metric.Train.Epoch]); + } + } } Console.WriteLine(metric); }, From 062458b782b249fb27908432b55b8a5efaaf03db Mon Sep 17 00:00:00 2001 From: Mustafa Bal <5262061+mstfbl@users.noreply.github.com> Date: Wed, 1 Jul 2020 01:49:46 -0700 Subject: [PATCH 4/8] Removed learning rate decay from validation phase --- .../ImageClassificationTrainer.cs | 14 ++-- .../TensorflowTests.cs | 64 ++++--------------- 2 files changed, 22 insertions(+), 56 deletions(-) diff --git a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs index a043cadb6b..6e006b5a51 100644 --- a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs +++ b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs @@ -169,8 +169,12 @@ public sealed class TrainMetrics /// public override string ToString() { - return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}, Learning Rate: {LearningRate,10} " + - $"Epoch: {Epoch,3}, Accuracy: {Accuracy,10}, Cross-Entropy: {CrossEntropy,10}"; + if (DatasetUsed == ImageClassificationMetrics.Dataset.Train) + return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}, Learning Rate: {LearningRate,10} " + + $"Epoch: {Epoch,3}, Accuracy: {Accuracy,10}, Cross-Entropy: {CrossEntropy,10}"; + else + return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}, " + + $"Epoch: {Epoch,3}, Accuracy: {Accuracy,10}, Cross-Entropy: {CrossEntropy,10}"; } } @@ -1025,9 +1029,9 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath, // Evaluate. TrainAndEvaluateClassificationLayerCore(epoch, learningRate, featureFileStartOffset, - metrics, labelTensorShape, featureTensorShape, batchSize, validationSetLabelReader, - validationSetFeatureReader, labelBuffer, featuresBuffer, labelBufferSizeInBytes, - featureBufferSizeInBytes, featureFileRecordSize, _options.LearningRateScheduler, + metrics, labelTensorShape, featureTensorShape, batchSize, + validationSetLabelReader, validationSetFeatureReader, labelBuffer, featuresBuffer, + labelBufferSizeInBytes, featureBufferSizeInBytes, featureFileRecordSize, null, trainState, validationEvalRunner, featureBufferPtr, labelBufferPtr, (outputTensors, metrics) => { diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs index b61e61e338..cae62113a3 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs @@ -1483,19 +1483,16 @@ public void TensorFlowImageClassification(ImageClassificationTrainer.Architectur [TensorFlowFact] public void TensorFlowImageClassificationWithExponentialLRScheduling() { - ExponentialLRDecay exponentialLRDecay = new ExponentialLRDecay(); - TensorFlowImageClassificationWithLRScheduling(exponentialLRDecay, 50, (int)exponentialLRDecay.NumEpochsPerDecay); + TensorFlowImageClassificationWithLRScheduling(new ExponentialLRDecay(), 50); } [TensorFlowFact] public void TensorFlowImageClassificationWithPolynomialLRScheduling() { - PolynomialLRDecay polynomialLRDecay = new PolynomialLRDecay(); - TensorFlowImageClassificationWithLRScheduling(polynomialLRDecay, 50, (int)polynomialLRDecay.NumEpochsPerDecay, polynomialLRDecay.EndLearningRate); + TensorFlowImageClassificationWithLRScheduling(new PolynomialLRDecay(), 50); } - internal void TensorFlowImageClassificationWithLRScheduling( - LearningRateScheduler learningRateScheduler, int epoch, int numEpochsPerDecay, float endLearningRate = 0.0f) + internal void TensorFlowImageClassificationWithLRScheduling(LearningRateScheduler learningRateScheduler, int epoch) { //Load all the original images info IEnumerable images = LoadImagesFromDirectory( @@ -1523,8 +1520,6 @@ internal void TensorFlowImageClassificationWithLRScheduling( var (trainSetBottleneckCachedValuesFileName, validationSetBottleneckCachedValuesFileName, workspacePath, isReuse) = getInitialParameters(ImageClassificationTrainer.Architecture.ResnetV2101, _finalImagesFolderName); - float[] learningRatesTraining = new float[epoch]; - float[] learningRatesValidation = new float[epoch]; float[] crossEntropyTraining = new float[epoch]; float[] crossEntropyValidation = new float[epoch]; float baseLearningRate = 0.01f; @@ -1541,57 +1536,24 @@ internal void TensorFlowImageClassificationWithLRScheduling( LearningRate = baseLearningRate, MetricsCallback = (metric) => { - // Check that learning rates in metrics from both the training and validation phases decay and are sensible if (metric.Train != null) { - if (metric.Train.Epoch > 1) - { - Assert.InRange(metric.Train.LearningRate, 0, baseLearningRate); - Assert.True(metric.Train.CrossEntropy > 0); - } - // Save learning rate and cross entropy values in training phase + // Check that cross validation rates during both the training and validation phases are decreasing and are sensible if (metric.Train.DatasetUsed == ImageClassificationTrainer.ImageClassificationMetrics.Dataset.Train) - { - learningRatesTraining[metric.Train.Epoch] = metric.Train.LearningRate; + { + // Save cross entropy values in training phase crossEntropyTraining[metric.Train.Epoch] = metric.Train.CrossEntropy; - // Check that learning rates over each epoch-per-decay are decreasing, and that cross entropy is also decreasing - if (metric.Train.Epoch > 1) - { - // Testing PolynomialLRDecay training - if (endLearningRate != 0.0) - { - Assert.True(learningRatesTraining[metric.Train.Epoch - numEpochsPerDecay] > learningRatesTraining[metric.Train.Epoch] - || learningRatesTraining[metric.Train.Epoch] == endLearningRate); - } - // Testing ExponentialLRDecay training - else - { - Assert.True(learningRatesTraining[metric.Train.Epoch - numEpochsPerDecay] > learningRatesTraining[metric.Train.Epoch]); - } - Assert.True(crossEntropyTraining[metric.Train.Epoch - numEpochsPerDecay] > crossEntropyTraining[metric.Train.Epoch]); - } + // Check that cross entropy values over each epoch-per-decay are decreasing in training phase + if (metric.Train.Epoch > 0) + Assert.True(crossEntropyTraining[metric.Train.Epoch - 1] > crossEntropyTraining[metric.Train.Epoch]); } - // Save learning rate and cross entropy values in validation phase else { - learningRatesValidation[metric.Train.Epoch] = metric.Train.LearningRate; + // Save cross entropy values in validation phase crossEntropyValidation[metric.Train.Epoch] = metric.Train.CrossEntropy; - // Check that learning rates over each epoch-per-decay are decreasing, and that cross entropy is also decreasing - if (metric.Train.Epoch > 1) - { - // Testing PolynomialLRDecay validation - if (endLearningRate != 0.0) - { - Assert.True(learningRatesValidation[metric.Train.Epoch - numEpochsPerDecay] > learningRatesValidation[metric.Train.Epoch] - || learningRatesValidation[metric.Train.Epoch] == endLearningRate); - } - // Testing ExponentialLRDecay validation - else - { - Assert.True(learningRatesValidation[metric.Train.Epoch - numEpochsPerDecay] > learningRatesValidation[metric.Train.Epoch]); - } - Assert.True(crossEntropyValidation[metric.Train.Epoch - numEpochsPerDecay] > crossEntropyValidation[metric.Train.Epoch]); - } + // Check that cross entropy values over each epoch-per-decay are decreasing in validation phase + if (metric.Train.Epoch > 0) + Assert.True(crossEntropyValidation[metric.Train.Epoch - 1] > crossEntropyValidation[metric.Train.Epoch]); } } Console.WriteLine(metric); From 76d2a001c08eac3a34e344dea0a1b461752199c2 Mon Sep 17 00:00:00 2001 From: Mustafa Bal <5262061+mstfbl@users.noreply.github.com> Date: Wed, 1 Jul 2020 04:18:47 -0700 Subject: [PATCH 5/8] Update validationEvalRunner --- src/Microsoft.ML.Vision/ImageClassificationTrainer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs index 6e006b5a51..d0c9cb61df 100644 --- a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs +++ b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs @@ -952,7 +952,8 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath, if (validationNeeded) { validationEvalRunner = new Runner(_session, runnerInputTensorNames.ToArray(), - new[] { _evaluationStep.name, _crossEntropy.name }, new[] { _trainStep.name }); + runnerOutputTensorNames.Count() > 0 ? runnerOutputTensorNames.ToArray() : null, + new[] { _trainStep.name }); } runner = new Runner(_session, runnerInputTensorNames.ToArray(), From 8ca3f79f9e2e18ab83501b61fc520d247cbdc866 Mon Sep 17 00:00:00 2001 From: Mustafa Bal <5262061+mstfbl@users.noreply.github.com> Date: Wed, 1 Jul 2020 21:56:45 -0700 Subject: [PATCH 6/8] Set learning rate scheduler to null during validation, update ToString() --- src/Microsoft.ML.Vision/ImageClassificationTrainer.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs index d0c9cb61df..73a6f29faa 100644 --- a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs +++ b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs @@ -170,8 +170,8 @@ public sealed class TrainMetrics public override string ToString() { if (DatasetUsed == ImageClassificationMetrics.Dataset.Train) - return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}, Learning Rate: {LearningRate,10} " + - $"Epoch: {Epoch,3}, Accuracy: {Accuracy,10}, Cross-Entropy: {CrossEntropy,10}"; + return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}" + + $"Epoch: {Epoch,3}, Accuracy: {Accuracy,10}, Cross-Entropy: {CrossEntropy,10}, Learning Rate: {LearningRate,10}"; else return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}, " + $"Epoch: {Epoch,3}, Accuracy: {Accuracy,10}, Cross-Entropy: {CrossEntropy,10}"; @@ -951,9 +951,8 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath, if (validationNeeded) { - validationEvalRunner = new Runner(_session, runnerInputTensorNames.ToArray(), - runnerOutputTensorNames.Count() > 0 ? runnerOutputTensorNames.ToArray() : null, - new[] { _trainStep.name }); + validationEvalRunner = new Runner(_session, new[] { _bottleneckInput.name, _labelTensor.name }, + new[] { _evaluationStep.name, _crossEntropy.name }); } runner = new Runner(_session, runnerInputTensorNames.ToArray(), From 35018d648dbe620d2a4e8f4c66f73ed8ecab93dd Mon Sep 17 00:00:00 2001 From: Mustafa Bal <5262061+mstfbl@users.noreply.github.com> Date: Wed, 1 Jul 2020 21:59:17 -0700 Subject: [PATCH 7/8] Update ToString() for uniform alignment --- src/Microsoft.ML.Vision/ImageClassificationTrainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs index 73a6f29faa..5f94ff282b 100644 --- a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs +++ b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs @@ -170,7 +170,7 @@ public sealed class TrainMetrics public override string ToString() { if (DatasetUsed == ImageClassificationMetrics.Dataset.Train) - return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}" + + return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}, " + $"Epoch: {Epoch,3}, Accuracy: {Accuracy,10}, Cross-Entropy: {CrossEntropy,10}, Learning Rate: {LearningRate,10}"; else return $"Phase: Training, Dataset used: {DatasetUsed.ToString(),10}, Batch Processed Count: {BatchProcessedCount,3}, " + From dbe3bafed9ae622e113f349f1ff578cbc3fc8e01 Mon Sep 17 00:00:00 2001 From: Mustafa Bal <5262061+mstfbl@users.noreply.github.com> Date: Wed, 1 Jul 2020 22:02:16 -0700 Subject: [PATCH 8/8] Update TensorflowTests.cs --- .../ScenariosWithDirectInstantiation/TensorflowTests.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs index cae62113a3..f4a1ecf76c 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs @@ -1522,7 +1522,6 @@ internal void TensorFlowImageClassificationWithLRScheduling(LearningRateSchedule float[] crossEntropyTraining = new float[epoch]; float[] crossEntropyValidation = new float[epoch]; - float baseLearningRate = 0.01f; var options = new ImageClassificationTrainer.Options() { FeatureColumnName = "Image", @@ -1533,7 +1532,7 @@ internal void TensorFlowImageClassificationWithLRScheduling(LearningRateSchedule Arch = ImageClassificationTrainer.Architecture.ResnetV2101, Epoch = epoch, BatchSize = 10, - LearningRate = baseLearningRate, + LearningRate = 0.01f, MetricsCallback = (metric) => { if (metric.Train != null)