Skip to content

Commit 7961575

Browse files
handle exception during GetNextPipeline for AutoML (#5455)
* handle exception during GetNextPipeline for AutoML * take comments
1 parent 6ccf479 commit 7961575

3 files changed

Lines changed: 41 additions & 23 deletions

File tree

src/Microsoft.ML.AutoML/Experiment/Experiment.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public IList<TRunDetail> Execute()
6363
// get next pipeline
6464
var getPipelineStopwatch = Stopwatch.StartNew();
6565
var pipeline = PipelineSuggester.GetNextInferredPipeline(_context, _history, _datasetColumnInfo, _task,
66-
_optimizingMetricInfo.IsMaximizing, _experimentSettings.CacheBeforeTrainer, _trainerAllowList);
66+
_optimizingMetricInfo.IsMaximizing, _experimentSettings.CacheBeforeTrainer, _logger, _trainerAllowList);
6767

6868
var pipelineInferenceTimeInSeconds = getPipelineStopwatch.Elapsed.TotalSeconds;
6969

src/Microsoft.ML.AutoML/PipelineSuggesters/PipelineSuggester.cs

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using System.Collections.Generic;
77
using System.Linq;
88
using Microsoft.ML.Data;
9+
using Microsoft.ML.Internal.Utilities;
10+
using Microsoft.ML.Runtime;
911

1012
namespace Microsoft.ML.AutoML
1113
{
@@ -17,10 +19,11 @@ public static Pipeline GetNextPipeline(MLContext context,
1719
IEnumerable<PipelineScore> history,
1820
DatasetColumnInfo[] columns,
1921
TaskKind task,
22+
IChannel logger,
2023
bool isMaximizingMetric = true)
2124
{
2225
var inferredHistory = history.Select(r => SuggestedPipelineRunDetail.FromPipelineRunResult(context, r));
23-
var nextInferredPipeline = GetNextInferredPipeline(context, inferredHistory, columns, task, isMaximizingMetric, CacheBeforeTrainer.Auto);
26+
var nextInferredPipeline = GetNextInferredPipeline(context, inferredHistory, columns, task, isMaximizingMetric, CacheBeforeTrainer.Auto, logger);
2427
return nextInferredPipeline?.ToPipeline();
2528
}
2629

@@ -30,6 +33,7 @@ public static SuggestedPipeline GetNextInferredPipeline(MLContext context,
3033
TaskKind task,
3134
bool isMaximizingMetric,
3235
CacheBeforeTrainer cacheBeforeTrainer,
36+
IChannel logger,
3337
IEnumerable<TrainerName> trainerAllowList = null)
3438
{
3539
var availableTrainers = RecipeInference.AllowedTrainers(context, task,
@@ -64,7 +68,7 @@ public static SuggestedPipeline GetNextInferredPipeline(MLContext context,
6468
do
6569
{
6670
// sample new hyperparameters for the learner
67-
if (!SampleHyperparameters(context, newTrainer, history, isMaximizingMetric))
71+
if (!SampleHyperparameters(context, newTrainer, history, isMaximizingMetric, logger))
6872
{
6973
// if unable to sample new hyperparameters for the learner
7074
// (ie SMAC returned 0 suggestions), break
@@ -188,30 +192,42 @@ private static IValueGenerator[] ConvertToValueGenerators(IEnumerable<SweepableP
188192
/// Samples new hyperparameters for the trainer, and sets them.
189193
/// Returns true if success (new hyperparameters were suggested and set). Else, returns false.
190194
/// </summary>
191-
private static bool SampleHyperparameters(MLContext context, SuggestedTrainer trainer, IEnumerable<SuggestedPipelineRunDetail> history, bool isMaximizingMetric)
195+
private static bool SampleHyperparameters(MLContext context, SuggestedTrainer trainer,
196+
IEnumerable<SuggestedPipelineRunDetail> history, bool isMaximizingMetric, IChannel logger)
192197
{
193-
var sps = ConvertToValueGenerators(trainer.SweepParams);
194-
var sweeper = new SmacSweeper(context,
195-
new SmacSweeper.Arguments
198+
try
199+
{
200+
var sps = ConvertToValueGenerators(trainer.SweepParams);
201+
var sweeper = new SmacSweeper(context,
202+
new SmacSweeper.Arguments
203+
{
204+
SweptParameters = sps
205+
});
206+
207+
IEnumerable<SuggestedPipelineRunDetail> historyToUse = history
208+
.Where(r => r.RunSucceeded && r.Pipeline.Trainer.TrainerName == trainer.TrainerName &&
209+
r.Pipeline.Trainer.HyperParamSet != null &&
210+
r.Pipeline.Trainer.HyperParamSet.Any() &&
211+
FloatUtils.IsFinite(r.Score));
212+
213+
// get new set of hyperparameter values
214+
var proposedParamSet = sweeper.ProposeSweeps(1, historyToUse.Select(h => h.ToRunResult(isMaximizingMetric))).FirstOrDefault();
215+
if (!proposedParamSet.Any())
196216
{
197-
SweptParameters = sps
198-
});
217+
return false;
218+
}
199219

200-
IEnumerable<SuggestedPipelineRunDetail> historyToUse = history
201-
.Where(r => r.RunSucceeded && r.Pipeline.Trainer.TrainerName == trainer.TrainerName && r.Pipeline.Trainer.HyperParamSet != null && r.Pipeline.Trainer.HyperParamSet.Any());
220+
// associate proposed parameter set with trainer, so that smart hyperparameter
221+
// sweepers (like KDO) can map them back.
222+
trainer.SetHyperparamValues(proposedParamSet);
202223

203-
// get new set of hyperparameter values
204-
var proposedParamSet = sweeper.ProposeSweeps(1, historyToUse.Select(h => h.ToRunResult(isMaximizingMetric))).First();
205-
if (!proposedParamSet.Any())
224+
return true;
225+
}
226+
catch (Exception ex)
206227
{
207-
return false;
228+
logger.Error($"SampleHyperparameters failed with exception: {ex}");
229+
throw;
208230
}
209-
210-
// associate proposed parameter set with trainer, so that smart hyperparameter
211-
// sweepers (like KDO) can map them back.
212-
trainer.SetHyperparamValues(proposedParamSet);
213-
214-
return true;
215231
}
216232
}
217233
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Newtonsoft.Json;
1010
using Microsoft.ML.TestFramework;
1111
using Xunit.Abstractions;
12+
using Microsoft.ML.Runtime;
1213

1314
namespace Microsoft.ML.AutoML.Test
1415
{
@@ -27,7 +28,8 @@ public void GetNextPipeline()
2728
var columns = DatasetColumnInfoUtil.GetDatasetColumnInfo(context, uciAdult, new ColumnInformation() { LabelColumnName = DatasetUtil.UciAdultLabel });
2829

2930
// get next pipeline
30-
var pipeline = PipelineSuggester.GetNextPipeline(context, new List<PipelineScore>(), columns, TaskKind.BinaryClassification);
31+
var pipeline = PipelineSuggester.GetNextPipeline(context, new List<PipelineScore>(), columns,
32+
TaskKind.BinaryClassification, ((IChannelProvider)context).Start("AutoMLTest"));
3133

3234
// serialize & deserialize pipeline
3335
var serialized = JsonConvert.SerializeObject(pipeline);
@@ -57,7 +59,7 @@ public void GetNextPipelineMock()
5759
for (var i = 0; i < maxIterations; i++)
5860
{
5961
// Get next pipeline
60-
var pipeline = PipelineSuggester.GetNextPipeline(context, history, columns, task);
62+
var pipeline = PipelineSuggester.GetNextPipeline(context, history, columns, task, ((IChannelProvider)context).Start("AutoMLTest"));
6163
if (pipeline == null)
6264
{
6365
break;

0 commit comments

Comments
 (0)