Skip to content

Commit 09117b1

Browse files
add epison to probability (#6668)
1 parent 4a11ac0 commit 09117b1

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

src/Microsoft.ML.AutoML/Tuner/PipelineProposer.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ public string ProposeSearchSpace()
101101
{
102102
var probabilities = _pipelineSchemas.Select(id => _eci[id]).ToArray();
103103
probabilities = ArrayMath.Inverse(probabilities);
104+
// _eci (estimator improve cost) might be infinity, which means the estimator cost for finding an improvement is positive infinity
105+
// in that case, we used to set the probability to be a very small number, in some cases it can be zero ( 1 / double.infinity), so that it will be very unlikely to be picked.
106+
// however, there's a special situation where all the estimators have infinity eci
107+
// which could happen when all the estimators have been tried, all retrieves perfect loss and no improvement can be made.
108+
// in which case, all probablities will be zero and in that case, we will never be able to pick any of them.
109+
// Therefore, we need to make sure non of the probabilities is zero, and we can do that by adding a very small number (double.epsilon) to each of them after inverse.
110+
probabilities = probabilities.Select(p => p + double.Epsilon).ToArray();
104111
probabilities = ArrayMath.Normalize(probabilities);
105112

106113
// sample

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

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ public void EciCfo_should_handle_trial_result_with_nan_value()
140140
SearchSpace = searchSpace,
141141
Seed = 1,
142142
});
143-
var invalidLosses = new[] { double.NaN, double.NegativeInfinity, double.PositiveInfinity };
143+
var invalidLosses = Enumerable.Repeat(new[] { double.NaN, double.NegativeInfinity, double.PositiveInfinity }, 100)
144+
.SelectMany(loss => loss);
144145
var id = 0;
145146
foreach (var loss in invalidLosses)
146147
{
@@ -155,7 +156,42 @@ public void EciCfo_should_handle_trial_result_with_nan_value()
155156
{
156157
TrialSettings = trialSetting,
157158
DurationInMilliseconds = 10000,
158-
Loss = double.NaN,
159+
Loss = loss,
160+
};
161+
tuner.Update(trialResult);
162+
}
163+
}
164+
165+
[Fact]
166+
public void EciCfo_should_handle_trial_result_with_no_improvements_over_losses()
167+
{
168+
// this test verify if tuner can find max value for LSE.
169+
var context = new MLContext(1);
170+
var pipeline = this.CreateDummySweepablePipeline(context);
171+
var searchSpace = new SearchSpace.SearchSpace();
172+
searchSpace["_pipeline_"] = pipeline.SearchSpace;
173+
var tuner = new EciCostFrugalTuner(pipeline, new AutoMLExperiment.AutoMLExperimentSettings
174+
{
175+
SearchSpace = searchSpace,
176+
Seed = 1,
177+
});
178+
var zeroLosses = Enumerable.Repeat(0.0, 100);
179+
var randomLosses = Enumerable.Range(0, 100).Select(i => i * 0.1);
180+
var id = 0;
181+
foreach (var loss in zeroLosses.Concat(randomLosses))
182+
{
183+
var trialSetting = new TrialSettings
184+
{
185+
TrialId = id++,
186+
Parameter = Parameter.CreateNestedParameter(),
187+
};
188+
var parameter = tuner.Propose(trialSetting);
189+
trialSetting.Parameter = parameter;
190+
var trialResult = new TrialResult
191+
{
192+
TrialSettings = trialSetting,
193+
DurationInMilliseconds = 10000,
194+
Loss = loss,
159195
};
160196
tuner.Update(trialResult);
161197
}

0 commit comments

Comments
 (0)