diff --git a/src/Microsoft.ML.AutoML/CodeGen/estimator-schema.json b/src/Microsoft.ML.AutoML/CodeGen/estimator-schema.json index 44ee31b892..79853140c9 100644 --- a/src/Microsoft.ML.AutoML/CodeGen/estimator-schema.json +++ b/src/Microsoft.ML.AutoML/CodeGen/estimator-schema.json @@ -71,7 +71,7 @@ "DnnFeaturizerImage", "Naive", "ForecastBySsa", - "TextClassifcation" + "TextClassification" ] }, "nugetDependencies": { diff --git a/src/Microsoft.ML.AutoML/CodeGen/trainer-estimators.json b/src/Microsoft.ML.AutoML/CodeGen/trainer-estimators.json index 4deeb9b804..cfd6c55c07 100644 --- a/src/Microsoft.ML.AutoML/CodeGen/trainer-estimators.json +++ b/src/Microsoft.ML.AutoML/CodeGen/trainer-estimators.json @@ -512,7 +512,7 @@ "searchOption": "image_classification_option" }, { - "functionName": "TextClassifcation", + "functionName": "TextClassification", "estimatorTypes": [ "MultiClassification" ], "arguments": [ { diff --git a/src/Microsoft.ML.AutoML/SweepableEstimator/Estimators/TextClassification.cs b/src/Microsoft.ML.AutoML/SweepableEstimator/Estimators/TextClassification.cs index ddd6a508ed..85e4734715 100644 --- a/src/Microsoft.ML.AutoML/SweepableEstimator/Estimators/TextClassification.cs +++ b/src/Microsoft.ML.AutoML/SweepableEstimator/Estimators/TextClassification.cs @@ -10,7 +10,7 @@ namespace Microsoft.ML.AutoML.CodeGen { - internal partial class TextClassifcationMulti + internal partial class TextClassificationMulti { public override IEstimator BuildFromOption(MLContext context, TextClassificationOption param) { diff --git a/src/Microsoft.ML.AutoML/Tuner/PipelineProposer.cs b/src/Microsoft.ML.AutoML/Tuner/PipelineProposer.cs index d59ad14104..2d63b680ea 100644 --- a/src/Microsoft.ML.AutoML/Tuner/PipelineProposer.cs +++ b/src/Microsoft.ML.AutoML/Tuner/PipelineProposer.cs @@ -128,7 +128,7 @@ public void Update(TrialResult result, string schema) { var loss = result.Loss; var duration = result.DurationInMilliseconds / 1000; - var isSuccess = duration != 0; + var isSuccess = duration != 0 && !double.IsNaN(loss) && !double.IsInfinity(loss); // if k1 is null, it means this is the first completed trial. // in that case, initialize k1, k2, e1, e2 in the following way: diff --git a/test/Microsoft.ML.AutoML.Tests/TunerTests.cs b/test/Microsoft.ML.AutoML.Tests/TunerTests.cs index bdacd5fbaf..be10b6856e 100644 --- a/test/Microsoft.ML.AutoML.Tests/TunerTests.cs +++ b/test/Microsoft.ML.AutoML.Tests/TunerTests.cs @@ -127,6 +127,40 @@ public void CFO_should_start_from_init_point_if_provided() (x * x + y * y + z * z).Should().Be(0); } + [Fact] + public void EciCfo_should_handle_trial_result_with_nan_value() + { + // this test verify if tuner can find max value for LSE. + var context = new MLContext(1); + var pipeline = this.CreateDummySweepablePipeline(context); + var searchSpace = new SearchSpace.SearchSpace(); + searchSpace["_pipeline_"] = pipeline.SearchSpace; + var tuner = new EciCostFrugalTuner(pipeline, new AutoMLExperiment.AutoMLExperimentSettings + { + SearchSpace = searchSpace, + Seed = 1, + }); + var invalidLosses = new[] { double.NaN, double.NegativeInfinity, double.PositiveInfinity }; + var id = 0; + foreach (var loss in invalidLosses) + { + var trialSetting = new TrialSettings + { + TrialId = id++, + Parameter = Parameter.CreateNestedParameter(), + }; + var parameter = tuner.Propose(trialSetting); + trialSetting.Parameter = parameter; + var trialResult = new TrialResult + { + TrialSettings = trialSetting, + DurationInMilliseconds = 10000, + Loss = double.NaN, + }; + tuner.Update(trialResult); + } + } + [Fact] public void LSE_maximize_test() { @@ -346,5 +380,16 @@ private class LSE3DSearchSpace [Range(-10.0, 10.0, 0.0, false)] public double Z { get; set; } } + + private SweepablePipeline CreateDummySweepablePipeline(MLContext context) + { + var mapKeyToValue = SweepableEstimatorFactory.CreateMapKeyToValue(new MapKeyToValueOption + { + InputColumnName = "input", + OutputColumnName = "output", + }); + + return mapKeyToValue.Append(context.Auto().BinaryClassification()); + } } }