-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Image Classification API: Fix processing incomplete batch(<batchSize), images processed per epoch , enable EarlyStopping without Validation Set. Fixes #4274 and #4286 #4289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
b451c25
6f2915b
995b227
123f31f
3b614eb
034ce8e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -186,6 +186,8 @@ private void CheckTrainingParameters(ImageClassificationEstimator.Options option | |
|
|
||
| if (_session.graph.OperationByName(_labelTensor.name.Split(':')[0]) == null) | ||
| throw Host.ExceptParam(nameof(options.TensorFlowLabel), $"'{options.TensorFlowLabel}' does not exist in the model"); | ||
| if (options.EarlyStoppingCriteria != null && options.ValidationSet == null && options.TestOnTrainSet == false) | ||
| throw Host.ExceptParam(nameof(options.EarlyStoppingCriteria), $"No Validation dataset provided and testing on Train disabled, Early Stopping not supported."); | ||
| } | ||
|
|
||
| private (Tensor, Tensor) AddJpegDecoding(int height, int width, int depth) | ||
|
|
@@ -378,6 +380,7 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath, | |
| float crossentropy = 0; | ||
| for (int epoch = 0; epoch < epochs; epoch += 1) | ||
| { | ||
| batchIndex = 0; | ||
| metrics.Train.Accuracy = 0; | ||
| metrics.Train.CrossEntropy = 0; | ||
| metrics.Train.BatchProcessedCount = 0; | ||
|
|
@@ -429,6 +432,42 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath, | |
| } | ||
| } | ||
|
|
||
| //Process last incomplete batch | ||
| if (batchIndex > 0) | ||
| { | ||
| featureTensorShape[0] = batchIndex; | ||
| featureBatchSizeInBytes = sizeof(float) * featureBatch.Length * batchIndex / batchSize; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
sizeof(float) * featureLength * batchIndex |
||
| labelTensorShape[0] = batchIndex; | ||
| labelBatchSizeInBytes = sizeof(long) * batchIndex; | ||
| runner.AddInput(new Tensor(featureBatchPtr, featureTensorShape, TF_DataType.TF_FLOAT, featureBatchSizeInBytes), 0) | ||
| .AddInput(new Tensor(labelBatchPtr, labelTensorShape, TF_DataType.TF_INT64, labelBatchSizeInBytes), 1) | ||
| .Run(); | ||
|
|
||
|
ashbhandare marked this conversation as resolved.
|
||
| metrics.Train.BatchProcessedCount += 1; | ||
|
|
||
| if (options.TestOnTrainSet && statisticsCallback != null) | ||
| { | ||
| var outputTensors = testEvalRunner | ||
| .AddInput(new Tensor(featureBatchPtr, featureTensorShape, TF_DataType.TF_FLOAT, featureBatchSizeInBytes), 0) | ||
| .AddInput(new Tensor(labelBatchPtr, labelTensorShape, TF_DataType.TF_INT64, labelBatchSizeInBytes), 1) | ||
| .Run(); | ||
|
|
||
| outputTensors[0].ToScalar<float>(ref accuracy); | ||
| outputTensors[1].ToScalar<float>(ref crossentropy); | ||
| metrics.Train.Accuracy += accuracy; | ||
| metrics.Train.CrossEntropy += crossentropy; | ||
|
|
||
| outputTensors[0].Dispose(); | ||
| outputTensors[1].Dispose(); | ||
| } | ||
|
|
||
| batchIndex = 0; | ||
| featureTensorShape[0] = batchSize; | ||
| featureBatchSizeInBytes = sizeof(float) * featureBatch.Length; | ||
| labelTensorShape[0] = batchSize; | ||
| labelBatchSizeInBytes = sizeof(long) * batchSize; | ||
| } | ||
|
|
||
| if (options.TestOnTrainSet && statisticsCallback != null) | ||
| { | ||
| metrics.Train.Epoch = epoch; | ||
|
|
@@ -440,7 +479,15 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath, | |
| } | ||
|
|
||
| if (validationSet == null) | ||
| { | ||
| //Early stopping check | ||
| if (options.EarlyStoppingCriteria != null) | ||
| { | ||
| if (options.EarlyStoppingCriteria.ShouldStop(metrics.Train)) | ||
| break; | ||
| } | ||
| continue; | ||
| } | ||
|
|
||
| batchIndex = 0; | ||
| metrics.Train.BatchProcessedCount = 0; | ||
|
|
@@ -478,6 +525,31 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath, | |
| } | ||
| } | ||
|
|
||
| //Process last incomplete batch | ||
| if(batchIndex > 0) | ||
| { | ||
| featureTensorShape[0] = batchIndex; | ||
| featureBatchSizeInBytes = sizeof(float) * featureBatch.Length * batchIndex / batchSize; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
sizeof(float) * featureLength * batchIndex |
||
| labelTensorShape[0] = batchIndex; | ||
| labelBatchSizeInBytes = sizeof(long) * batchIndex; | ||
| var outputTensors = validationEvalRunner | ||
| .AddInput(new Tensor(featureBatchPtr, featureTensorShape, TF_DataType.TF_FLOAT, featureBatchSizeInBytes), 0) | ||
| .AddInput(new Tensor(labelBatchPtr, labelTensorShape, TF_DataType.TF_INT64, labelBatchSizeInBytes), 1) | ||
| .Run(); | ||
|
|
||
| outputTensors[0].ToScalar<float>(ref accuracy); | ||
| metrics.Train.Accuracy += accuracy; | ||
| metrics.Train.BatchProcessedCount += 1; | ||
| batchIndex = 0; | ||
|
|
||
| featureTensorShape[0] = batchSize; | ||
| featureBatchSizeInBytes = sizeof(float) * featureBatch.Length; | ||
| labelTensorShape[0] = batchSize; | ||
| labelBatchSizeInBytes = sizeof(long) * batchSize; | ||
|
|
||
| outputTensors[0].Dispose(); | ||
| } | ||
|
ashbhandare marked this conversation as resolved.
|
||
|
|
||
| if (statisticsCallback != null) | ||
| { | ||
| metrics.Train.Epoch = epoch; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets improve the exception message "Early stopping enabled but unable to find a validation set and/or train set testing disabled. Please disable early stopping or either provide a validation set or enable train set training."