diff --git a/docs/samples/Microsoft.ML.Samples.GPU/Microsoft.ML.Samples.GPU.csproj b/docs/samples/Microsoft.ML.Samples.GPU/Microsoft.ML.Samples.GPU.csproj
index c2cf24bf76..ebe0fde3b1 100644
--- a/docs/samples/Microsoft.ML.Samples.GPU/Microsoft.ML.Samples.GPU.csproj
+++ b/docs/samples/Microsoft.ML.Samples.GPU/Microsoft.ML.Samples.GPU.csproj
@@ -44,6 +44,7 @@
+
diff --git a/docs/samples/Microsoft.ML.Samples/Microsoft.ML.Samples.csproj b/docs/samples/Microsoft.ML.Samples/Microsoft.ML.Samples.csproj
index e343bdbfe5..caba26f5cc 100644
--- a/docs/samples/Microsoft.ML.Samples/Microsoft.ML.Samples.csproj
+++ b/docs/samples/Microsoft.ML.Samples/Microsoft.ML.Samples.csproj
@@ -977,6 +977,7 @@
+
diff --git a/src/Microsoft.ML.Console/Microsoft.ML.Console.csproj b/src/Microsoft.ML.Console/Microsoft.ML.Console.csproj
index f4331b79fb..78a1e768af 100644
--- a/src/Microsoft.ML.Console/Microsoft.ML.Console.csproj
+++ b/src/Microsoft.ML.Console/Microsoft.ML.Console.csproj
@@ -1,7 +1,7 @@
- netcoreapp3.1
+ net6.0
Exe
MML
Microsoft.ML.Tools.Console.Console
@@ -27,6 +27,7 @@
+
diff --git a/src/Microsoft.ML.SearchSpace/Converter/ChoiceOptionConverter.cs b/src/Microsoft.ML.SearchSpace/Converter/ChoiceOptionConverter.cs
new file mode 100644
index 0000000000..0cf010475f
--- /dev/null
+++ b/src/Microsoft.ML.SearchSpace/Converter/ChoiceOptionConverter.cs
@@ -0,0 +1,46 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Microsoft.ML.SearchSpace.Option;
+
+namespace Microsoft.ML.SearchSpace.Converter
+{
+ internal class ChoiceOptionConverter : JsonConverter
+ {
+ class Schema
+ {
+ ///
+ /// must be one of "int" | "float" | "double"
+ ///
+ [JsonPropertyName("default")]
+ public object Default { get; set; }
+
+ [JsonPropertyName("choices")]
+ public object[] Choices { get; set; }
+ }
+
+ public override ChoiceOption Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ var schema = JsonSerializer.Deserialize(ref reader, options);
+
+ return new ChoiceOption(schema.Choices, schema.Default);
+ }
+
+ public override void Write(Utf8JsonWriter writer, ChoiceOption value, JsonSerializerOptions options)
+ {
+ var schema = new Schema
+ {
+ Choices = value.Choices,
+ Default = value.SampleFromFeatureSpace(value.Default),
+ };
+
+ JsonSerializer.Serialize(writer, schema, options);
+ }
+ }
+}
diff --git a/src/Microsoft.ML.SearchSpace/Converter/NumericOptionConverter.cs b/src/Microsoft.ML.SearchSpace/Converter/NumericOptionConverter.cs
new file mode 100644
index 0000000000..709213c69b
--- /dev/null
+++ b/src/Microsoft.ML.SearchSpace/Converter/NumericOptionConverter.cs
@@ -0,0 +1,84 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Microsoft.ML.SearchSpace.Option;
+
+namespace Microsoft.ML.SearchSpace.Converter
+{
+ internal class NumericOptionConverter : JsonConverter
+ {
+ class Schema
+ {
+ ///
+ /// must be one of "int" | "float" | "double"
+ ///
+ [JsonPropertyName("type")]
+ public string Type { get; set; }
+
+ [JsonPropertyName("default")]
+ public object Default { get; set; }
+
+ [JsonPropertyName("min")]
+ public object Min { get; set; }
+
+ [JsonPropertyName("max")]
+ public object Max { get; set; }
+
+ [JsonPropertyName("log_base")]
+ public bool LogBase { get; set; }
+ }
+
+ public override UniformNumericOption Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ var schema = JsonSerializer.Deserialize(ref reader, options);
+
+ return schema.Type switch
+ {
+ "int" => new UniformIntOption(Convert.ToInt32(schema.Min), Convert.ToInt32(schema.Max), schema.LogBase, Convert.ToInt32(schema.Default)),
+ "float" => new UniformSingleOption(Convert.ToSingle(schema.Min), Convert.ToSingle(schema.Max), schema.LogBase, Convert.ToSingle(schema.Default)),
+ "double" => new UniformDoubleOption(Convert.ToDouble(schema.Min), Convert.ToDouble(schema.Max), schema.LogBase, Convert.ToDouble(schema.Default)),
+ _ => throw new ArgumentException($"unknown schema type: {schema.Type}"),
+ };
+ }
+
+ public override void Write(Utf8JsonWriter writer, UniformNumericOption value, JsonSerializerOptions options)
+ {
+ var schema = value switch
+ {
+ UniformIntOption intOption => new Schema
+ {
+ Type = "int",
+ Default = intOption.SampleFromFeatureSpace(intOption.Default).AsType(),
+ Min = Convert.ToInt32(intOption.Min),
+ Max = Convert.ToInt32(intOption.Max),
+ LogBase = intOption.LogBase,
+ },
+ UniformDoubleOption doubleOption => new Schema
+ {
+ Type = "double",
+ Default = doubleOption.SampleFromFeatureSpace(doubleOption.Default).AsType(),
+ Min = doubleOption.Min,
+ Max = doubleOption.Max,
+ LogBase = doubleOption.LogBase,
+ },
+ UniformSingleOption singleOption => new Schema
+ {
+ Type = "float",
+ Default = singleOption.SampleFromFeatureSpace(singleOption.Default).AsType(),
+ Min = Convert.ToSingle(singleOption.Min),
+ Max = Convert.ToSingle(singleOption.Max),
+ LogBase = singleOption.LogBase,
+ },
+ _ => throw new ArgumentException("unknown type"),
+ };
+
+ JsonSerializer.Serialize(writer, schema, options);
+ }
+ }
+}
diff --git a/src/Microsoft.ML.SearchSpace/Converter/OptionConverter.cs b/src/Microsoft.ML.SearchSpace/Converter/OptionConverter.cs
new file mode 100644
index 0000000000..ef2eb58e9a
--- /dev/null
+++ b/src/Microsoft.ML.SearchSpace/Converter/OptionConverter.cs
@@ -0,0 +1,66 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Microsoft.ML.SearchSpace.Option;
+
+namespace Microsoft.ML.SearchSpace.Converter
+{
+ internal class OptionConverter : JsonConverter
+ {
+ public override OptionBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ try
+ {
+ return JsonSerializer.Deserialize(ref reader, options);
+ }
+ catch (Exception)
+ {
+ // try choice option
+ }
+
+ try
+ {
+ return JsonSerializer.Deserialize(ref reader, options);
+ }
+ catch (Exception)
+ {
+ // try numeric option
+ }
+
+ try
+ {
+ return JsonSerializer.Deserialize(ref reader, options);
+ }
+ catch (Exception)
+ {
+ throw new ArgumentException("unknown option type");
+ }
+ }
+
+ public override void Write(Utf8JsonWriter writer, OptionBase value, JsonSerializerOptions options)
+ {
+ if (value is SearchSpace ss)
+ {
+ JsonSerializer.Serialize(writer, ss, options);
+ }
+ else if (value is ChoiceOption choiceOption)
+ {
+ JsonSerializer.Serialize(writer, choiceOption, options);
+ }
+ else if (value is UniformNumericOption uniformNumericOption)
+ {
+ JsonSerializer.Serialize(writer, uniformNumericOption, options);
+ }
+ else
+ {
+ throw new ArgumentException("unknown option type");
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.ML.SearchSpace/Converter/SearchSpaceConverter.cs b/src/Microsoft.ML.SearchSpace/Converter/SearchSpaceConverter.cs
new file mode 100644
index 0000000000..f0f9165c00
--- /dev/null
+++ b/src/Microsoft.ML.SearchSpace/Converter/SearchSpaceConverter.cs
@@ -0,0 +1,28 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Microsoft.ML.SearchSpace.Option;
+
+namespace Microsoft.ML.SearchSpace.Converter
+{
+ internal class SearchSpaceConverter : JsonConverter
+ {
+ public override SearchSpace Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ var optionKVPairs = JsonSerializer.Deserialize>(ref reader, options);
+
+ return new SearchSpace(optionKVPairs);
+ }
+
+ public override void Write(Utf8JsonWriter writer, SearchSpace value, JsonSerializerOptions options)
+ {
+ JsonSerializer.Serialize>(value, options);
+ }
+ }
+}
diff --git a/src/Microsoft.ML.SearchSpace/Microsoft.ML.SearchSpace.csproj b/src/Microsoft.ML.SearchSpace/Microsoft.ML.SearchSpace.csproj
index 85b50459f7..155feb6f84 100644
--- a/src/Microsoft.ML.SearchSpace/Microsoft.ML.SearchSpace.csproj
+++ b/src/Microsoft.ML.SearchSpace/Microsoft.ML.SearchSpace.csproj
@@ -2,7 +2,7 @@
netstandard2.0
- Microsoft.ML.AutoML
+ Microsoft.ML.Core
true
MSML_ContractsCheckMessageNotLiteralOrIdentifier
9.0
diff --git a/src/Microsoft.ML.SearchSpace/Option/ChoiceOption.cs b/src/Microsoft.ML.SearchSpace/Option/ChoiceOption.cs
index 3a66ce1fff..8f14f679e8 100644
--- a/src/Microsoft.ML.SearchSpace/Option/ChoiceOption.cs
+++ b/src/Microsoft.ML.SearchSpace/Option/ChoiceOption.cs
@@ -5,6 +5,8 @@
using System;
using System.Diagnostics.Contracts;
using System.Linq;
+using System.Text.Json.Serialization;
+using Microsoft.ML.SearchSpace.Converter;
#nullable enable
@@ -13,6 +15,7 @@ namespace Microsoft.ML.SearchSpace.Option
///
/// This class represent option for discrete value, such as string, enum, etc..
///
+ [JsonConverter(typeof(ChoiceOptionConverter))]
public sealed class ChoiceOption : OptionBase
{
private readonly UniformSingleOption _option;
diff --git a/src/Microsoft.ML.SearchSpace/Option/NestOption.cs b/src/Microsoft.ML.SearchSpace/Option/NestOption.cs
index a31aa74516..08c0847276 100644
--- a/src/Microsoft.ML.SearchSpace/Option/NestOption.cs
+++ b/src/Microsoft.ML.SearchSpace/Option/NestOption.cs
@@ -11,9 +11,9 @@
namespace Microsoft.ML.SearchSpace.Option
{
///
- /// This class represent nest option, which is an option that contains other options, like , or even itself.
+ /// This class represent nest option, which is an option that contains other options, like , or even itself.
///
- public sealed class NestOption : OptionBase, IDictionary
+ public sealed class SearchSpace : OptionBase, IDictionary
{
private readonly Dictionary _options = new Dictionary();
diff --git a/src/Microsoft.ML.SearchSpace/Option/OptionBase.cs b/src/Microsoft.ML.SearchSpace/Option/OptionBase.cs
index 6b218d242c..281e4137fc 100644
--- a/src/Microsoft.ML.SearchSpace/Option/OptionBase.cs
+++ b/src/Microsoft.ML.SearchSpace/Option/OptionBase.cs
@@ -5,11 +5,15 @@
#nullable enable
+using System.Text.Json.Serialization;
+using Microsoft.ML.SearchSpace.Converter;
+
namespace Microsoft.ML.SearchSpace.Option
{
///
/// abstrace class for Option.
///
+ [JsonConverter(typeof(OptionConverter))]
public abstract class OptionBase
{
///
@@ -37,7 +41,7 @@ public abstract class OptionBase
///
/// Gets the step of this option. The is used to determine the number of grid this option should be divided into. In , it's always the length of
- /// . And in , it's always [null]. And in , it's a combination of all in its options.
+ /// . And in , it's always [null]. And in , it's a combination of all in its options.
///
public abstract int?[] Step { get; }
}
diff --git a/src/Microsoft.ML.SearchSpace/Option/UniformNumericOption.cs b/src/Microsoft.ML.SearchSpace/Option/UniformNumericOption.cs
index 7680538889..a03bcbab0e 100644
--- a/src/Microsoft.ML.SearchSpace/Option/UniformNumericOption.cs
+++ b/src/Microsoft.ML.SearchSpace/Option/UniformNumericOption.cs
@@ -5,12 +5,15 @@
using System;
using System.Diagnostics.Contracts;
using System.Linq;
+using System.Text.Json.Serialization;
+using Microsoft.ML.SearchSpace.Converter;
namespace Microsoft.ML.SearchSpace.Option
{
///
/// abstract class for numeric option.
///
+ [JsonConverter(typeof(NumericOptionConverter))]
public abstract class UniformNumericOption : OptionBase
{
///
diff --git a/src/Microsoft.ML.SearchSpace/Schema/SchemaBase.cs b/src/Microsoft.ML.SearchSpace/Schema/SchemaBase.cs
deleted file mode 100644
index d0b52142d9..0000000000
--- a/src/Microsoft.ML.SearchSpace/Schema/SchemaBase.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Text.Json.Serialization;
-
-namespace Microsoft.ML.SearchSpace.Schema
-{
- [JsonConverter(typeof(JsonStringEnumConverter))]
- internal enum SchemaType
- {
- UniformDoubleOption = 0,
- IntegerOption = 1,
- ChoiceOption = 2,
- NestOption = 3,
- }
-
- internal abstract class SchemaBase
- {
- [JsonPropertyName("schema_type")]
- public abstract SchemaType SchemaType { get; }
-
- [JsonPropertyName("schema_type")]
- public abstract int Version { get; }
- }
-}
diff --git a/src/Microsoft.ML.SearchSpace/Schema/UniformDoubleOptionSchemaV0.cs b/src/Microsoft.ML.SearchSpace/Schema/UniformDoubleOptionSchemaV0.cs
deleted file mode 100644
index 21402fc3a0..0000000000
--- a/src/Microsoft.ML.SearchSpace/Schema/UniformDoubleOptionSchemaV0.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Text.Json.Serialization;
-
-namespace Microsoft.ML.SearchSpace.Schema
-{
- internal class UniformDoubleOptionSchemaV0 : SchemaBase
- {
- public override SchemaType SchemaType => SchemaType.UniformDoubleOption;
-
- public override int Version => 0;
-
- [JsonPropertyName("min")]
- public double Min { get; set; }
-
- [JsonPropertyName("max")]
- public double Max { get; set; }
-
- [JsonPropertyName("log_base")]
- public bool? LogBase { get; set; }
- }
-}
diff --git a/src/Microsoft.ML.SearchSpace/SearchSpace.cs b/src/Microsoft.ML.SearchSpace/SearchSpace.cs
index b40651947c..84c2da890d 100644
--- a/src/Microsoft.ML.SearchSpace/SearchSpace.cs
+++ b/src/Microsoft.ML.SearchSpace/SearchSpace.cs
@@ -8,13 +8,15 @@
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
+using Microsoft.ML.SearchSpace.Converter;
using Microsoft.ML.SearchSpace.Option;
namespace Microsoft.ML.SearchSpace
{
///
- /// This class is used to represent a set of , which can be either one of , or .
+ /// This class is used to represent a set of , which can be either one of , or another nested search space.
///
+ [JsonConverter(typeof(SearchSpaceConverter))]
public class SearchSpace : OptionBase, IDictionary
{
private readonly Dictionary _options;
@@ -168,11 +170,11 @@ private Dictionary GetOptionsFromType(Type typeInfo)
}
- private NestOption GetNestOptionFromType(Type typeInfo)
+ private SearchSpace GetSearchSpaceOptionFromType(Type typeInfo)
{
var propertyOptions = GetOptionsFromProperty(typeInfo);
var fieldOptions = GetOptionsFromField(typeInfo);
- var nestOption = new NestOption();
+ var nestOption = new SearchSpace();
foreach (var kv in propertyOptions.Concat(fieldOptions))
{
nestOption[kv.Key] = kv.Value;
@@ -208,7 +210,7 @@ private Dictionary GetOptionsFromField(Type typeInfo)
ChoiceAttribute choice => choice.Option,
RangeAttribute range => range.Option,
BooleanChoiceAttribute booleanChoice => booleanChoice.Option,
- NestOptionAttribute nest => GetNestOptionFromType(field.FieldType),
+ NestOptionAttribute nest => GetSearchSpaceOptionFromType(field.FieldType),
_ => throw new NotImplementedException(),
};
@@ -246,7 +248,7 @@ private Dictionary GetOptionsFromProperty(Type typeInfo)
ChoiceAttribute choice => choice.Option,
RangeAttribute range => range.Option,
BooleanChoiceAttribute booleanChoice => booleanChoice.Option,
- NestOptionAttribute nest => GetNestOptionFromType(property.PropertyType),
+ NestOptionAttribute nest => GetSearchSpaceOptionFromType(property.PropertyType),
_ => throw new NotImplementedException(),
};
diff --git a/src/Microsoft.ML.StandardTrainers/LdSvm/LdSvmTrainer.cs b/src/Microsoft.ML.StandardTrainers/LdSvm/LdSvmTrainer.cs
index 538fdce114..d749875d9d 100644
--- a/src/Microsoft.ML.StandardTrainers/LdSvm/LdSvmTrainer.cs
+++ b/src/Microsoft.ML.StandardTrainers/LdSvm/LdSvmTrainer.cs
@@ -13,6 +13,7 @@
using Microsoft.ML.Internal.Utilities;
using Microsoft.ML.Numeric;
using Microsoft.ML.Runtime;
+using Microsoft.ML.SearchSpace;
using Microsoft.ML.Trainers;
[assembly: LoadableClass(LdSvmTrainer.Summary, typeof(LdSvmTrainer), typeof(LdSvmTrainer.Options),
@@ -77,6 +78,7 @@ public sealed class Options : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "Depth of Local Deep SVM tree", ShortName = "depth", SortOrder = 50)]
[TGUI(SuggestedSweeps = "1,3,5,7")]
[TlcModule.SweepableDiscreteParam("TreeDepth", new object[] { 1, 3, 5, 7 })]
+ [Range(1, 128, 1, true)]
public int TreeDepth = Defaults.TreeDepth;
///
@@ -85,6 +87,7 @@ public sealed class Options : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "Regularizer for classifier parameter W", ShortName = "lw", SortOrder = 50)]
[TGUI(SuggestedSweeps = "0.1,0.01,0.001")]
[TlcModule.SweepableDiscreteParam("LambdaW", new object[] { 0.1f, 0.01f, 0.001f })]
+ [Range(1e-4f, 1f, 1e-4f, true)]
public float LambdaW = Defaults.LambdaW;
///
@@ -93,6 +96,7 @@ public sealed class Options : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "Regularizer for kernel parameter Theta", ShortName = "lt", SortOrder = 50)]
[TGUI(SuggestedSweeps = "0.1,0.01,0.001")]
[TlcModule.SweepableDiscreteParam("LambdaTheta", new object[] { 0.1f, 0.01f, 0.001f })]
+ [Range(1e-4f, 1f, 1e-4f, true)]
public float LambdaTheta = Defaults.LambdaTheta;
///
@@ -101,6 +105,7 @@ public sealed class Options : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "Regularizer for kernel parameter Thetaprime", ShortName = "lp", SortOrder = 50)]
[TGUI(SuggestedSweeps = "0.1,0.01,0.001")]
[TlcModule.SweepableDiscreteParam("LambdaThetaprime", new object[] { 0.1f, 0.01f, 0.001f })]
+ [Range(1e-4f, 1f, 1e-4f, true)]
public float LambdaThetaprime = Defaults.LambdaThetaprime;
///
@@ -109,6 +114,7 @@ public sealed class Options : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "Parameter for sigmoid sharpness", ShortName = "s", SortOrder = 50)]
[TGUI(SuggestedSweeps = "1.0,0.1,0.01")]
[TlcModule.SweepableDiscreteParam("Sigma", new object[] { 1.0f, 0.1f, 0.01f })]
+ [Range(1e-4f, 1f, 1e-4f, true)]
public float Sigma = Defaults.Sigma;
///
@@ -116,6 +122,7 @@ public sealed class Options : TrainerInputBaseWithWeight
///
[Argument(ArgumentType.AtMostOnce, HelpText = "No bias", ShortName = "bias")]
[TlcModule.SweepableDiscreteParam("NoBias", null, isBool: true)]
+ [BooleanChoice(true)]
public bool UseBias = Defaults.UseBias;
///
@@ -125,6 +132,7 @@ public sealed class Options : TrainerInputBaseWithWeight
HelpText = "Number of iterations", ShortName = "iter,NumIterations", SortOrder = 50)]
[TGUI(SuggestedSweeps = "10000,15000")]
[TlcModule.SweepableDiscreteParam("NumIterations", new object[] { 10000, 15000 })]
+ [Range(1, int.MaxValue, 1, true)]
public int NumberOfIterations = Defaults.NumberOfIterations;
[Argument(ArgumentType.AtMostOnce, HelpText = "The calibrator kind to apply to the predictor. Specify null for no calibration", Visibility = ArgumentAttribute.VisibilityType.EntryPointsOnly)]
diff --git a/src/Microsoft.ML.StandardTrainers/Microsoft.ML.StandardTrainers.csproj b/src/Microsoft.ML.StandardTrainers/Microsoft.ML.StandardTrainers.csproj
index f3b20954de..d3a7a06c3c 100644
--- a/src/Microsoft.ML.StandardTrainers/Microsoft.ML.StandardTrainers.csproj
+++ b/src/Microsoft.ML.StandardTrainers/Microsoft.ML.StandardTrainers.csproj
@@ -10,6 +10,10 @@
+
+ all
+ true
+
diff --git a/src/Microsoft.ML.StandardTrainers/Standard/LogisticRegression/LbfgsPredictorBase.cs b/src/Microsoft.ML.StandardTrainers/Standard/LogisticRegression/LbfgsPredictorBase.cs
index 5de100fba6..c5008a76ca 100644
--- a/src/Microsoft.ML.StandardTrainers/Standard/LogisticRegression/LbfgsPredictorBase.cs
+++ b/src/Microsoft.ML.StandardTrainers/Standard/LogisticRegression/LbfgsPredictorBase.cs
@@ -13,6 +13,7 @@
using Microsoft.ML.Internal.Utilities;
using Microsoft.ML.Numeric;
using Microsoft.ML.Runtime;
+using Microsoft.ML.SearchSpace;
namespace Microsoft.ML.Trainers
{
@@ -44,6 +45,7 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "L2 regularization weight", ShortName = "l2, L2Weight", SortOrder = 50)]
[TGUI(Label = "L2 Weight", Description = "Weight of L2 regularizer term", SuggestedSweeps = "0,0.1,1")]
[TlcModule.SweepableFloatParamAttribute(0.0f, 1.0f, numSteps: 4)]
+ [Range(0.03125f, 32768f, 1, true)]
public float L2Regularization = Defaults.L2Regularization;
///
@@ -52,6 +54,7 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "L1 regularization weight", ShortName = "l1, L1Weight", SortOrder = 50)]
[TGUI(Label = "L1 Weight", Description = "Weight of L1 regularizer term", SuggestedSweeps = "0,0.1,1")]
[TlcModule.SweepableFloatParamAttribute(0.0f, 1.0f, numSteps: 4)]
+ [Range(0.03125f, 32768f, 1, true)]
public float L1Regularization = Defaults.L1Regularization;
///
@@ -61,6 +64,7 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
ShortName = "ot, OptTol", SortOrder = 50)]
[TGUI(Label = "Optimization Tolerance", Description = "Threshold for optimizer convergence", SuggestedSweeps = "1e-4,1e-7")]
[TlcModule.SweepableDiscreteParamAttribute(new object[] { 1e-4f, 1e-7f })]
+ [Range(1e-7f, 1e-1f, 1e-4f, true)]
public float OptimizationTolerance = Defaults.OptimizationTolerance;
///
@@ -69,6 +73,7 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "Memory size for L-BFGS. Low=faster, less accurate", ShortName = "m, MemorySize", SortOrder = 50)]
[TGUI(Description = "Memory size for L-BFGS", SuggestedSweeps = "5,20,50")]
[TlcModule.SweepableDiscreteParamAttribute("MemorySize", new object[] { 5, 20, 50 })]
+ [Range(2, 512, 2, true)]
public int HistorySize = Defaults.HistorySize;
///
@@ -77,6 +82,7 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "Maximum iterations.", ShortName = "maxiter, MaxIterations, NumberOfIterations")]
[TGUI(Label = "Max Number of Iterations")]
[TlcModule.SweepableLongParamAttribute("MaxIterations", 1, int.MaxValue)]
+ [Range(1, int.MaxValue, 1, true)]
public int MaximumNumberOfIterations = Defaults.MaximumNumberOfIterations;
///
@@ -106,6 +112,7 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.LastOccurrenceWins, HelpText = "Init weights diameter", ShortName = "initwts, InitWtsDiameter", SortOrder = 140)]
[TGUI(Label = "Initial Weights Scale", SuggestedSweeps = "0,0.1,0.5,1")]
[TlcModule.SweepableFloatParamAttribute("InitWtsDiameter", 0.0f, 1.0f, numSteps: 5)]
+ [Range(0f, 1f, 0f, false)]
public float InitialWeightsDiameter = 0;
// Deprecated
@@ -124,12 +131,14 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
///
[Argument(ArgumentType.AtMostOnce, HelpText = "Force densification of the internal optimization vectors", ShortName = "do")]
[TlcModule.SweepableDiscreteParamAttribute("DenseOptimizer", new object[] { false, true })]
+ [BooleanChoice]
public bool DenseOptimizer = false;
///
/// Enforce non-negative weights. Default is false.
///
[Argument(ArgumentType.AtMostOnce, HelpText = "Enforce non-negative weights", ShortName = "nn", SortOrder = 90)]
+ [BooleanChoice]
public bool EnforceNonNegativity = Defaults.EnforceNonNegativity;
[BestFriend]
diff --git a/src/Microsoft.ML.StandardTrainers/Standard/Online/AveragedLinear.cs b/src/Microsoft.ML.StandardTrainers/Standard/Online/AveragedLinear.cs
index 6197e0b4c5..e666caca3e 100644
--- a/src/Microsoft.ML.StandardTrainers/Standard/Online/AveragedLinear.cs
+++ b/src/Microsoft.ML.StandardTrainers/Standard/Online/AveragedLinear.cs
@@ -10,6 +10,7 @@
using Microsoft.ML.Internal.Utilities;
using Microsoft.ML.Numeric;
using Microsoft.ML.Runtime;
+using Microsoft.ML.SearchSpace;
// TODO: Check if it works properly if Averaged is set to false
@@ -26,6 +27,7 @@ public abstract class AveragedLinearOptions : OnlineLinearOptions
[Argument(ArgumentType.AtMostOnce, HelpText = "Learning rate", ShortName = "lr", SortOrder = 50)]
[TGUI(Label = "Learning rate", SuggestedSweeps = "0.01,0.1,0.5,1.0")]
[TlcModule.SweepableDiscreteParam("LearningRate", new object[] { 0.01, 0.1, 0.5, 1.0 })]
+ [Range(1e-4f, 1f, 1f, true)]
public float LearningRate = AveragedDefault.LearningRate;
///
@@ -38,6 +40,7 @@ public abstract class AveragedLinearOptions : OnlineLinearOptions
[Argument(ArgumentType.AtMostOnce, HelpText = "Decrease learning rate", ShortName = "decreaselr", SortOrder = 50)]
[TGUI(Label = "Decrease Learning Rate", Description = "Decrease learning rate as iterations progress")]
[TlcModule.SweepableDiscreteParam("DecreaseLearningRate", new object[] { false, true })]
+ [BooleanChoice]
public bool DecreaseLearningRate = AveragedDefault.DecreaseLearningRate;
///
@@ -66,6 +69,7 @@ public abstract class AveragedLinearOptions : OnlineLinearOptions
[Argument(ArgumentType.AtMostOnce, HelpText = "L2 Regularization Weight", ShortName = "reg,L2RegularizerWeight", SortOrder = 50)]
[TGUI(Label = "L2 Regularization Weight")]
[TlcModule.SweepableFloatParam("L2RegularizerWeight", 0.0f, 0.4f)]
+ [Range(0f, 32768f, 0f, false)]
public float L2Regularization = AveragedDefault.L2Regularization;
///
diff --git a/src/Microsoft.ML.StandardTrainers/Standard/Online/LinearSvm.cs b/src/Microsoft.ML.StandardTrainers/Standard/Online/LinearSvm.cs
index 1991df054a..2776eb94d3 100644
--- a/src/Microsoft.ML.StandardTrainers/Standard/Online/LinearSvm.cs
+++ b/src/Microsoft.ML.StandardTrainers/Standard/Online/LinearSvm.cs
@@ -13,6 +13,7 @@
using Microsoft.ML.Model;
using Microsoft.ML.Numeric;
using Microsoft.ML.Runtime;
+using Microsoft.ML.SearchSpace;
using Microsoft.ML.Trainers;
[assembly: LoadableClass(LinearSvmTrainer.Summary, typeof(LinearSvmTrainer), typeof(LinearSvmTrainer.Options),
@@ -82,18 +83,22 @@ public sealed class Options : OnlineLinearOptions
[Argument(ArgumentType.AtMostOnce, HelpText = "Regularizer constant", ShortName = "lambda", SortOrder = 50)]
[TGUI(SuggestedSweeps = "0.00001-0.1;log;inc:10")]
[TlcModule.SweepableFloatParamAttribute("Lambda", 0.00001f, 0.1f, 10, isLogScale: true)]
+ [Range(1e-6f, 1f, 1e-4f, true)]
public float Lambda = 0.001f;
[Argument(ArgumentType.AtMostOnce, HelpText = "Batch size", ShortName = "batch", SortOrder = 190)]
[TGUI(Label = "Batch Size")]
+ [Range(1, 128, 1, true)]
public int BatchSize = 1;
[Argument(ArgumentType.AtMostOnce, HelpText = "Perform projection to unit-ball? Typically used with batch size > 1.", ShortName = "project", SortOrder = 50)]
[TlcModule.SweepableDiscreteParam("PerformProjection", null, isBool: true)]
+ [BooleanChoice(defaultValue: false)]
public bool PerformProjection = false;
[Argument(ArgumentType.AtMostOnce, HelpText = "No bias")]
[TlcModule.SweepableDiscreteParam("NoBias", null, isBool: true)]
+ [BooleanChoice(defaultValue: false)]
public bool NoBias = false;
[Argument(ArgumentType.AtMostOnce, HelpText = "The calibrator kind to apply to the predictor. Specify null for no calibration", Visibility = ArgumentAttribute.VisibilityType.EntryPointsOnly)]
diff --git a/src/Microsoft.ML.StandardTrainers/Standard/Online/OnlineLinear.cs b/src/Microsoft.ML.StandardTrainers/Standard/Online/OnlineLinear.cs
index 9efe9d72f8..7bfd2e2afa 100644
--- a/src/Microsoft.ML.StandardTrainers/Standard/Online/OnlineLinear.cs
+++ b/src/Microsoft.ML.StandardTrainers/Standard/Online/OnlineLinear.cs
@@ -12,6 +12,7 @@
using Microsoft.ML.Model;
using Microsoft.ML.Numeric;
using Microsoft.ML.Runtime;
+using Microsoft.ML.SearchSpace;
namespace Microsoft.ML.Trainers
{
@@ -26,6 +27,7 @@ public abstract class OnlineLinearOptions : TrainerInputBaseWithLabel
[Argument(ArgumentType.AtMostOnce, HelpText = "Number of iterations", ShortName = "iter,numIterations", SortOrder = 50)]
[TGUI(Label = "Number of Iterations", Description = "Number of training iterations through data", SuggestedSweeps = "1,10,100")]
[TlcModule.SweepableLongParamAttribute("NumIterations", 1, 100, stepSize: 10, isLogScale: true)]
+ [Range(1, 512, 1, true)]
public int NumberOfIterations = OnlineDefault.NumberOfIterations;
///
@@ -45,6 +47,7 @@ public abstract class OnlineLinearOptions : TrainerInputBaseWithLabel
[Argument(ArgumentType.AtMostOnce, HelpText = "Init weights diameter", ShortName = "initwts,initWtsDiameter", SortOrder = 140)]
[TGUI(Label = "Initial Weights Scale", SuggestedSweeps = "0,0.1,0.5,1")]
[TlcModule.SweepableFloatParamAttribute("InitWtsDiameter", 0.0f, 1.0f, numSteps: 5)]
+ [Range(0f, 1f, 0f, false)]
public float InitialWeightsDiameter = 0;
///
diff --git a/src/Microsoft.ML.StandardTrainers/Standard/SdcaBinary.cs b/src/Microsoft.ML.StandardTrainers/Standard/SdcaBinary.cs
index a1e16ad283..d19bfc8c42 100644
--- a/src/Microsoft.ML.StandardTrainers/Standard/SdcaBinary.cs
+++ b/src/Microsoft.ML.StandardTrainers/Standard/SdcaBinary.cs
@@ -19,6 +19,7 @@
using Microsoft.ML.Model;
using Microsoft.ML.Numeric;
using Microsoft.ML.Runtime;
+using Microsoft.ML.SearchSpace;
using Microsoft.ML.Trainers;
using Microsoft.ML.Transforms;
@@ -162,6 +163,7 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "L2 regularizer constant. By default the l2 constant is automatically inferred based on data set.", NullName = "", ShortName = "l2, L2Const", SortOrder = 1)]
[TGUI(Label = "L2 Regularizer Constant", SuggestedSweeps = ",1e-7,1e-6,1e-5,1e-4,1e-3,1e-2")]
[TlcModule.SweepableDiscreteParam("L2Const", new object[] { "", 1e-7f, 1e-6f, 1e-5f, 1e-4f, 1e-3f, 1e-2f })]
+ [Range(1e-7f, 32768f, 1e-7f, true)]
public float? L2Regularization;
// REVIEW: make the default positive when we know how to consume a sparse model
@@ -172,6 +174,7 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
NullName = "", Name = "L1Threshold", ShortName = "l1", SortOrder = 2)]
[TGUI(Label = "L1 Soft Threshold", SuggestedSweeps = ",0,0.25,0.5,0.75,1")]
[TlcModule.SweepableDiscreteParam("L1Threshold", new object[] { "", 0f, 0.25f, 0.5f, 0.75f, 1f })]
+ [Range(1e-7f, 32768f, 1e-7f, true)]
public float? L1Regularization;
///
@@ -190,6 +193,7 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "The tolerance for the ratio between duality gap and primal loss for convergence checking.", ShortName = "tol")]
[TGUI(SuggestedSweeps = "0.001, 0.01, 0.1, 0.2")]
[TlcModule.SweepableDiscreteParam("ConvergenceTolerance", new object[] { 0.001f, 0.01f, 0.1f, 0.2f })]
+ [Range(1e-7f, 1f, 1e-7f, true)]
public float ConvergenceTolerance = 0.1f;
///
@@ -201,6 +205,7 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "Maximum number of iterations; set to 1 to simulate online learning. Defaults to automatic.", NullName = "", ShortName = "iter, MaxIterations, NumberOfIterations")]
[TGUI(Label = "Max number of iterations", SuggestedSweeps = ",10,20,100")]
[TlcModule.SweepableDiscreteParam("MaxIterations", new object[] { "", 10, 20, 100 })]
+ [Range(10, 1000, 10, true)]
public int? MaximumNumberOfIterations;
///
@@ -229,6 +234,7 @@ public abstract class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "The learning rate for adjusting bias from being regularized.", ShortName = "blr")]
[TGUI(SuggestedSweeps = "0, 0.01, 0.1, 1")]
[TlcModule.SweepableDiscreteParam("BiasLearningRate", new object[] { 0.0f, 0.01f, 0.1f, 1f })]
+ [Range(1e-7f, 1f, 1e-7f, true)]
public float BiasLearningRate = 0;
internal virtual void Check(IHostEnvironment env)
@@ -1834,6 +1840,7 @@ public class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "L2 Regularization constant", ShortName = "l2, L2Weight", SortOrder = 50)]
[TGUI(Label = "L2 Regularization Constant", SuggestedSweeps = "1e-7,5e-7,1e-6,5e-6,1e-5")]
[TlcModule.SweepableDiscreteParam("L2Const", new object[] { 1e-7f, 5e-7f, 1e-6f, 5e-6f, 1e-5f })]
+ [Range((float)0.03125, (float)32768, init: (float)1F, logBase: true)]
public float L2Regularization = Defaults.L2Regularization;
///
@@ -1853,6 +1860,7 @@ public class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "Exponential moving averaged improvement tolerance for convergence", ShortName = "tol")]
[TGUI(SuggestedSweeps = "1e-2,1e-3,1e-4,1e-5")]
[TlcModule.SweepableDiscreteParam("ConvergenceTolerance", new object[] { 1e-2f, 1e-3f, 1e-4f, 1e-5f })]
+ [Range(1e-6, 1e-1, init: 1e-1, logBase: true)]
public double ConvergenceTolerance = 1e-4;
///
@@ -1864,6 +1872,7 @@ public class OptionsBase : TrainerInputBaseWithWeight
[Argument(ArgumentType.AtMostOnce, HelpText = "Maximum number of iterations; set to 1 to simulate online learning.", ShortName = "iter, MaxIterations")]
[TGUI(Label = "Max number of iterations", SuggestedSweeps = "1,5,10,20")]
[TlcModule.SweepableDiscreteParam("MaxIterations", new object[] { 1, 5, 10, 20 })]
+ [Range((int)1, 20, init: 1, logBase: true)]
public int NumberOfIterations = Defaults.NumberOfIterations;
///
@@ -1871,6 +1880,7 @@ public class OptionsBase : TrainerInputBaseWithWeight
///
[Argument(ArgumentType.AtMostOnce, HelpText = "Initial learning rate (only used by SGD)", Name = "InitialLearningRate", ShortName = "ilr,lr,InitLearningRate")]
[TGUI(Label = "Initial Learning Rate (for SGD)")]
+ [Range(1e-3, 1, init: 1e-3, logBase: true)]
public double LearningRate = Defaults.LearningRate;
///
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Sgd_default_search_space_test.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Sgd_default_search_space_test.approved.txt
new file mode 100644
index 0000000000..3c0051da0a
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Sgd_default_search_space_test.approved.txt
@@ -0,0 +1,26 @@
+{
+ "L2Regularization": {
+ "default": 1,
+ "min": 0.03125,
+ "max": 32768,
+ "log_base": true
+ },
+ "ConvergenceTolerance": {
+ "default": 0.1,
+ "min": 1E-06,
+ "max": 0.1,
+ "log_base": true
+ },
+ "NumberOfIterations": {
+ "default": 1,
+ "min": 1,
+ "max": 20,
+ "log_base": true
+ },
+ "LearningRate": {
+ "default": 0.001,
+ "min": 0.001,
+ "max": 1,
+ "log_base": true
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.AveragedPerceptronTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.AveragedPerceptronTrainer+Options.approved.txt
new file mode 100644
index 0000000000..b803726231
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.AveragedPerceptronTrainer+Options.approved.txt
@@ -0,0 +1,37 @@
+{
+ "LearningRate": {
+ "type": "float",
+ "default": 1,
+ "min": 0.00010,
+ "max": 1,
+ "log_base": true
+ },
+ "DecreaseLearningRate": {
+ "default": true,
+ "choices": [
+ true,
+ false
+ ]
+ },
+ "L2Regularization": {
+ "type": "float",
+ "default": 0,
+ "min": 0,
+ "max": 32768,
+ "log_base": false
+ },
+ "NumberOfIterations": {
+ "type": "int",
+ "default": 1,
+ "min": 1,
+ "max": 512,
+ "log_base": true
+ },
+ "InitialWeightsDiameter": {
+ "type": "float",
+ "default": 0,
+ "min": 0,
+ "max": 1,
+ "log_base": false
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LbfgsLogisticRegressionBinaryTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LbfgsLogisticRegressionBinaryTrainer+Options.approved.txt
new file mode 100644
index 0000000000..e3c66ec1e5
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LbfgsLogisticRegressionBinaryTrainer+Options.approved.txt
@@ -0,0 +1,58 @@
+{
+ "L2Regularization": {
+ "type": "float",
+ "default": 1,
+ "min": 0.03125,
+ "max": 32768,
+ "log_base": true
+ },
+ "L1Regularization": {
+ "type": "float",
+ "default": 1,
+ "min": 0.03125,
+ "max": 32768,
+ "log_base": true
+ },
+ "OptimizationTolerance": {
+ "type": "float",
+ "default": 0.00010,
+ "min": 0.0000001,
+ "max": 0.1,
+ "log_base": true
+ },
+ "HistorySize": {
+ "type": "int",
+ "default": 2,
+ "min": 2,
+ "max": 512,
+ "log_base": true
+ },
+ "MaximumNumberOfIterations": {
+ "type": "int",
+ "default": 1,
+ "min": 1,
+ "max": 2147483647,
+ "log_base": true
+ },
+ "InitialWeightsDiameter": {
+ "type": "float",
+ "default": 0,
+ "min": 0,
+ "max": 1,
+ "log_base": false
+ },
+ "DenseOptimizer": {
+ "default": true,
+ "choices": [
+ true,
+ false
+ ]
+ },
+ "EnforceNonNegativity": {
+ "default": true,
+ "choices": [
+ true,
+ false
+ ]
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LbfgsMaximumEntropyMulticlassTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LbfgsMaximumEntropyMulticlassTrainer+Options.approved.txt
new file mode 100644
index 0000000000..e3c66ec1e5
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LbfgsMaximumEntropyMulticlassTrainer+Options.approved.txt
@@ -0,0 +1,58 @@
+{
+ "L2Regularization": {
+ "type": "float",
+ "default": 1,
+ "min": 0.03125,
+ "max": 32768,
+ "log_base": true
+ },
+ "L1Regularization": {
+ "type": "float",
+ "default": 1,
+ "min": 0.03125,
+ "max": 32768,
+ "log_base": true
+ },
+ "OptimizationTolerance": {
+ "type": "float",
+ "default": 0.00010,
+ "min": 0.0000001,
+ "max": 0.1,
+ "log_base": true
+ },
+ "HistorySize": {
+ "type": "int",
+ "default": 2,
+ "min": 2,
+ "max": 512,
+ "log_base": true
+ },
+ "MaximumNumberOfIterations": {
+ "type": "int",
+ "default": 1,
+ "min": 1,
+ "max": 2147483647,
+ "log_base": true
+ },
+ "InitialWeightsDiameter": {
+ "type": "float",
+ "default": 0,
+ "min": 0,
+ "max": 1,
+ "log_base": false
+ },
+ "DenseOptimizer": {
+ "default": true,
+ "choices": [
+ true,
+ false
+ ]
+ },
+ "EnforceNonNegativity": {
+ "default": true,
+ "choices": [
+ true,
+ false
+ ]
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LbfgsPoissonRegressionTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LbfgsPoissonRegressionTrainer+Options.approved.txt
new file mode 100644
index 0000000000..e3c66ec1e5
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LbfgsPoissonRegressionTrainer+Options.approved.txt
@@ -0,0 +1,58 @@
+{
+ "L2Regularization": {
+ "type": "float",
+ "default": 1,
+ "min": 0.03125,
+ "max": 32768,
+ "log_base": true
+ },
+ "L1Regularization": {
+ "type": "float",
+ "default": 1,
+ "min": 0.03125,
+ "max": 32768,
+ "log_base": true
+ },
+ "OptimizationTolerance": {
+ "type": "float",
+ "default": 0.00010,
+ "min": 0.0000001,
+ "max": 0.1,
+ "log_base": true
+ },
+ "HistorySize": {
+ "type": "int",
+ "default": 2,
+ "min": 2,
+ "max": 512,
+ "log_base": true
+ },
+ "MaximumNumberOfIterations": {
+ "type": "int",
+ "default": 1,
+ "min": 1,
+ "max": 2147483647,
+ "log_base": true
+ },
+ "InitialWeightsDiameter": {
+ "type": "float",
+ "default": 0,
+ "min": 0,
+ "max": 1,
+ "log_base": false
+ },
+ "DenseOptimizer": {
+ "default": true,
+ "choices": [
+ true,
+ false
+ ]
+ },
+ "EnforceNonNegativity": {
+ "default": true,
+ "choices": [
+ true,
+ false
+ ]
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LdSvmTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LdSvmTrainer+Options.approved.txt
new file mode 100644
index 0000000000..96a6f98401
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LdSvmTrainer+Options.approved.txt
@@ -0,0 +1,51 @@
+{
+ "TreeDepth": {
+ "type": "int",
+ "default": 1,
+ "min": 1,
+ "max": 128,
+ "log_base": true
+ },
+ "LambdaW": {
+ "type": "float",
+ "default": 0.00010,
+ "min": 0.00010,
+ "max": 1,
+ "log_base": true
+ },
+ "LambdaTheta": {
+ "type": "float",
+ "default": 0.00010,
+ "min": 0.00010,
+ "max": 1,
+ "log_base": true
+ },
+ "LambdaThetaprime": {
+ "type": "float",
+ "default": 0.00010,
+ "min": 0.00010,
+ "max": 1,
+ "log_base": true
+ },
+ "Sigma": {
+ "type": "float",
+ "default": 0.00010,
+ "min": 0.00010,
+ "max": 1,
+ "log_base": true
+ },
+ "UseBias": {
+ "default": true,
+ "choices": [
+ true,
+ false
+ ]
+ },
+ "NumberOfIterations": {
+ "type": "int",
+ "default": 1,
+ "min": 1,
+ "max": 2147483647,
+ "log_base": true
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LinearSvmTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LinearSvmTrainer+Options.approved.txt
new file mode 100644
index 0000000000..5551bab2f3
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.LinearSvmTrainer+Options.approved.txt
@@ -0,0 +1,44 @@
+{
+ "Lambda": {
+ "type": "float",
+ "default": 0.00010,
+ "min": 0.0000010,
+ "max": 1,
+ "log_base": true
+ },
+ "BatchSize": {
+ "type": "int",
+ "default": 1,
+ "min": 1,
+ "max": 128,
+ "log_base": true
+ },
+ "PerformProjection": {
+ "default": false,
+ "choices": [
+ true,
+ false
+ ]
+ },
+ "NoBias": {
+ "default": false,
+ "choices": [
+ true,
+ false
+ ]
+ },
+ "NumberOfIterations": {
+ "type": "int",
+ "default": 1,
+ "min": 1,
+ "max": 512,
+ "log_base": true
+ },
+ "InitialWeightsDiameter": {
+ "type": "float",
+ "default": 0,
+ "min": 0,
+ "max": 1,
+ "log_base": false
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.OnlineGradientDescentTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.OnlineGradientDescentTrainer+Options.approved.txt
new file mode 100644
index 0000000000..b803726231
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.OnlineGradientDescentTrainer+Options.approved.txt
@@ -0,0 +1,37 @@
+{
+ "LearningRate": {
+ "type": "float",
+ "default": 1,
+ "min": 0.00010,
+ "max": 1,
+ "log_base": true
+ },
+ "DecreaseLearningRate": {
+ "default": true,
+ "choices": [
+ true,
+ false
+ ]
+ },
+ "L2Regularization": {
+ "type": "float",
+ "default": 0,
+ "min": 0,
+ "max": 32768,
+ "log_base": false
+ },
+ "NumberOfIterations": {
+ "type": "int",
+ "default": 1,
+ "min": 1,
+ "max": 512,
+ "log_base": true
+ },
+ "InitialWeightsDiameter": {
+ "type": "float",
+ "default": 0,
+ "min": 0,
+ "max": 1,
+ "log_base": false
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaLogisticRegressionBinaryTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaLogisticRegressionBinaryTrainer+Options.approved.txt
new file mode 100644
index 0000000000..4ecb6de5da
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaLogisticRegressionBinaryTrainer+Options.approved.txt
@@ -0,0 +1,37 @@
+{
+ "L2Regularization": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 32768,
+ "log_base": true
+ },
+ "L1Regularization": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 32768,
+ "log_base": true
+ },
+ "ConvergenceTolerance": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 1,
+ "log_base": true
+ },
+ "MaximumNumberOfIterations": {
+ "type": "int",
+ "default": 10,
+ "min": 10,
+ "max": 1000,
+ "log_base": true
+ },
+ "BiasLearningRate": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 1,
+ "log_base": true
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaMaximumEntropyMulticlassTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaMaximumEntropyMulticlassTrainer+Options.approved.txt
new file mode 100644
index 0000000000..4ecb6de5da
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaMaximumEntropyMulticlassTrainer+Options.approved.txt
@@ -0,0 +1,37 @@
+{
+ "L2Regularization": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 32768,
+ "log_base": true
+ },
+ "L1Regularization": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 32768,
+ "log_base": true
+ },
+ "ConvergenceTolerance": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 1,
+ "log_base": true
+ },
+ "MaximumNumberOfIterations": {
+ "type": "int",
+ "default": 10,
+ "min": 10,
+ "max": 1000,
+ "log_base": true
+ },
+ "BiasLearningRate": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 1,
+ "log_base": true
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaNonCalibratedBinaryTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaNonCalibratedBinaryTrainer+Options.approved.txt
new file mode 100644
index 0000000000..4ecb6de5da
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaNonCalibratedBinaryTrainer+Options.approved.txt
@@ -0,0 +1,37 @@
+{
+ "L2Regularization": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 32768,
+ "log_base": true
+ },
+ "L1Regularization": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 32768,
+ "log_base": true
+ },
+ "ConvergenceTolerance": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 1,
+ "log_base": true
+ },
+ "MaximumNumberOfIterations": {
+ "type": "int",
+ "default": 10,
+ "min": 10,
+ "max": 1000,
+ "log_base": true
+ },
+ "BiasLearningRate": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 1,
+ "log_base": true
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaNonCalibratedMulticlassTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaNonCalibratedMulticlassTrainer+Options.approved.txt
new file mode 100644
index 0000000000..4ecb6de5da
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaNonCalibratedMulticlassTrainer+Options.approved.txt
@@ -0,0 +1,37 @@
+{
+ "L2Regularization": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 32768,
+ "log_base": true
+ },
+ "L1Regularization": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 32768,
+ "log_base": true
+ },
+ "ConvergenceTolerance": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 1,
+ "log_base": true
+ },
+ "MaximumNumberOfIterations": {
+ "type": "int",
+ "default": 10,
+ "min": 10,
+ "max": 1000,
+ "log_base": true
+ },
+ "BiasLearningRate": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 1,
+ "log_base": true
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaRegressionTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaRegressionTrainer+Options.approved.txt
new file mode 100644
index 0000000000..4ecb6de5da
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SdcaRegressionTrainer+Options.approved.txt
@@ -0,0 +1,37 @@
+{
+ "L2Regularization": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 32768,
+ "log_base": true
+ },
+ "L1Regularization": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 32768,
+ "log_base": true
+ },
+ "ConvergenceTolerance": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 1,
+ "log_base": true
+ },
+ "MaximumNumberOfIterations": {
+ "type": "int",
+ "default": 10,
+ "min": 10,
+ "max": 1000,
+ "log_base": true
+ },
+ "BiasLearningRate": {
+ "type": "float",
+ "default": 0.0000001,
+ "min": 0.0000001,
+ "max": 1,
+ "log_base": true
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SgdCalibratedTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SgdCalibratedTrainer+Options.approved.txt
new file mode 100644
index 0000000000..6c097ef75c
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SgdCalibratedTrainer+Options.approved.txt
@@ -0,0 +1,30 @@
+{
+ "L2Regularization": {
+ "type": "float",
+ "default": 1,
+ "min": 0.03125,
+ "max": 32768,
+ "log_base": true
+ },
+ "ConvergenceTolerance": {
+ "type": "double",
+ "default": 0.1,
+ "min": 0.000001,
+ "max": 0.1,
+ "log_base": true
+ },
+ "NumberOfIterations": {
+ "type": "int",
+ "default": 1,
+ "min": 1,
+ "max": 20,
+ "log_base": true
+ },
+ "LearningRate": {
+ "type": "double",
+ "default": 0.001,
+ "min": 0.001,
+ "max": 1,
+ "log_base": true
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SgdNonCalibratedTrainer+Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SgdNonCalibratedTrainer+Options.approved.txt
new file mode 100644
index 0000000000..6c097ef75c
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Microsoft.ML.Trainers.SgdNonCalibratedTrainer+Options.approved.txt
@@ -0,0 +1,30 @@
+{
+ "L2Regularization": {
+ "type": "float",
+ "default": 1,
+ "min": 0.03125,
+ "max": 32768,
+ "log_base": true
+ },
+ "ConvergenceTolerance": {
+ "type": "double",
+ "default": 0.1,
+ "min": 0.000001,
+ "max": 0.1,
+ "log_base": true
+ },
+ "NumberOfIterations": {
+ "type": "int",
+ "default": 1,
+ "min": 1,
+ "max": 20,
+ "log_base": true
+ },
+ "LearningRate": {
+ "type": "double",
+ "default": 0.001,
+ "min": 0.001,
+ "max": 1,
+ "log_base": true
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Options.approved.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Options.approved.txt
new file mode 100644
index 0000000000..b1ea94398d
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Options.approved.txt
@@ -0,0 +1,26 @@
+{
+ "L2Regularization": {
+ "default": 1,
+ "min": 0.03125,
+ "max": 32768,
+ "log_base": true
+ },
+ "ConvergenceTolerance": {
+ "default": 0.10000000000000001,
+ "min": 9.9999999999999995E-07,
+ "max": 0.10000000000000001,
+ "log_base": true
+ },
+ "NumberOfIterations": {
+ "default": 1,
+ "min": 1,
+ "max": 20,
+ "log_base": true
+ },
+ "LearningRate": {
+ "default": 0.001,
+ "min": 0.001,
+ "max": 1,
+ "log_base": true
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Options.received.txt b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Options.received.txt
new file mode 100644
index 0000000000..30c5edc93b
--- /dev/null
+++ b/test/Microsoft.ML.SearchSpace.Tests/ApprovalTests/SearchSpaceTest.Trainer_default_search_space_test.Options.received.txt
@@ -0,0 +1,26 @@
+{
+ "L2Regularization": {
+ "default": 1,
+ "min": 0.03125,
+ "max": 32768,
+ "log_base": true
+ },
+ "ConvergenceTolerance": {
+ "default": 0.10000000000000001,
+ "min": 9.9999999999999995E-07,
+ "max": 0.10000000000000001,
+ "log_base": true
+ },
+ "NumberOfIterations": {
+ "default": 1,
+ "min": 1,
+ "max": 20,
+ "log_base": true
+ },
+ "LearningRate": {
+ "default": 0.001,
+ "min": 0.001,
+ "max": 1,
+ "log_base": true
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.ML.SearchSpace.Tests/NestOptionTest.cs b/test/Microsoft.ML.SearchSpace.Tests/NestOptionTest.cs
deleted file mode 100644
index 146369d051..0000000000
--- a/test/Microsoft.ML.SearchSpace.Tests/NestOptionTest.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using FluentAssertions;
-using Microsoft.ML.SearchSpace.Option;
-using Xunit;
-using Xunit.Abstractions;
-
-namespace Microsoft.ML.SearchSpace.Tests
-{
- public class NestOptionTest : TestBase
- {
- public NestOptionTest(ITestOutputHelper output)
- : base(output)
- {
- }
-
- [Fact]
- public void NestOption_sampling_from_uniform_space_test()
- {
- var nestOption = new NestOption();
- nestOption.Add("choice", new ChoiceOption("a", "b", "c"));
- nestOption.Add("int", new UniformIntOption(0, 1));
- var anotherNestOption = new NestOption();
- anotherNestOption["choice"] = new ChoiceOption("d", "e");
- anotherNestOption["int"] = new UniformIntOption(2, 3);
- nestOption["nestOption"] = anotherNestOption;
-
- nestOption.FeatureSpaceDim.Should().Be(4);
- var parameter = nestOption.SampleFromFeatureSpace(new double[] { 0, 0, 0, 0 });
- parameter["nestOption"]["choice"].AsType().Should().Be("d");
- parameter["nestOption"]["int"].AsType().Should().Be(2);
- parameter["choice"].AsType().Should().Be("a");
- parameter["int"].AsType().Should().Be(0);
-
- parameter = nestOption.SampleFromFeatureSpace(new double[] { 1, 1, 1, 1 });
- parameter["nestOption"]["choice"].AsType().Should().Be("e");
- parameter["nestOption"]["int"].AsType().Should().Be(3);
- parameter["choice"].AsType().Should().Be("c");
- parameter["int"].AsType().Should().Be(1);
- }
-
- [Fact]
- public void NestOption_mapping_to_uniform_space_test()
- {
- var nestOption = new NestOption();
- nestOption.Add("choice", new ChoiceOption("a", "b", "c"));
- nestOption.Add("int", new UniformIntOption(0, 1));
-
- var parameter = Parameter.CreateNestedParameter();
- parameter["choice"] = Parameter.FromString("a");
- parameter["int"] = Parameter.FromInt(0);
- nestOption.MappingToFeatureSpace(parameter).Should().Equal(0, 0);
- }
-
- [Fact]
- public void NestOption_mapping_order_test()
- {
- // each dimension in uniform space should be mapping to the options under nest option in a certain (key ascending) order.
- var nestOption = new NestOption();
- nestOption["a"] = new UniformIntOption(0, 1);
- nestOption["b"] = new UniformIntOption(1, 2);
- nestOption["c"] = new UniformIntOption(2, 3);
-
- // changing of the first dimension should be reflected in option "a"
- var parameter = nestOption.SampleFromFeatureSpace(new double[] { 0, 0.5, 0.5 });
- parameter["a"].AsType().Should().Be(0);
- parameter = nestOption.SampleFromFeatureSpace(new double[] { 1, 0.5, 0.5 });
- parameter["a"].AsType().Should().Be(1);
-
- nestOption.Remove("a");
-
- // the first dimension should be option "b"
- parameter = nestOption.SampleFromFeatureSpace(new double[] { 0, 0.5 });
- parameter["b"].AsType().Should().Be(1);
- parameter = nestOption.SampleFromFeatureSpace(new double[] { 1, 0.5 });
- parameter["b"].AsType().Should().Be(2);
- }
- }
-}
diff --git a/test/Microsoft.ML.SearchSpace.Tests/SearchSpaceTest.cs b/test/Microsoft.ML.SearchSpace.Tests/SearchSpaceTest.cs
index eed7e33318..b62eccb49d 100644
--- a/test/Microsoft.ML.SearchSpace.Tests/SearchSpaceTest.cs
+++ b/test/Microsoft.ML.SearchSpace.Tests/SearchSpaceTest.cs
@@ -3,10 +3,17 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Buffers.Text;
+using System.Buffers;
using System.Text.Json;
+using System.Text.Json.Serialization;
+using ApprovalTests;
+using ApprovalTests.Namers;
+using ApprovalTests.Reporters;
using FluentAssertions;
using Microsoft.ML.SearchSpace.Option;
using Microsoft.ML.SearchSpace.Tuner;
+using Microsoft.ML.Trainers;
using Xunit;
using Xunit.Abstractions;
@@ -14,9 +21,18 @@ namespace Microsoft.ML.SearchSpace.Tests
{
public class SearchSpaceTest : TestBase
{
+ private readonly JsonSerializerOptions _settings = new JsonSerializerOptions()
+ {
+ WriteIndented = true,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ NumberHandling = JsonNumberHandling.Strict,
+ };
+
public SearchSpaceTest(ITestOutputHelper output)
: base(output)
{
+ _settings.Converters.Add(new DoubleConverter());
+ _settings.Converters.Add(new SingleConverter());
}
[Fact]
@@ -197,6 +213,98 @@ public void Search_space_hash_code_test()
ss.GetHashCode().Should().Be(125205970);
}
+ [Fact]
+ public void SearchSpace_sampling_from_uniform_space_test()
+ {
+ var searchSpace = new Option.SearchSpace();
+ searchSpace.Add("choice", new ChoiceOption("a", "b", "c"));
+ searchSpace.Add("int", new UniformIntOption(0, 1));
+ var anotherNestOption = new Option.SearchSpace();
+ anotherNestOption["choice"] = new ChoiceOption("d", "e");
+ anotherNestOption["int"] = new UniformIntOption(2, 3);
+ searchSpace["nestOption"] = anotherNestOption;
+
+ searchSpace.FeatureSpaceDim.Should().Be(4);
+ var parameter = searchSpace.SampleFromFeatureSpace(new double[] { 0, 0, 0, 0 });
+ parameter["nestOption"]["choice"].AsType().Should().Be("d");
+ parameter["nestOption"]["int"].AsType().Should().Be(2);
+ parameter["choice"].AsType().Should().Be("a");
+ parameter["int"].AsType().Should().Be(0);
+
+ parameter = searchSpace.SampleFromFeatureSpace(new double[] { 1, 1, 1, 1 });
+ parameter["nestOption"]["choice"].AsType().Should().Be("e");
+ parameter["nestOption"]["int"].AsType().Should().Be(3);
+ parameter["choice"].AsType().Should().Be("c");
+ parameter["int"].AsType().Should().Be(1);
+ }
+
+ [Fact]
+ public void SearchSpace_mapping_to_uniform_space_test()
+ {
+ var searchSpace = new SearchSpace();
+ searchSpace.Add("choice", new ChoiceOption("a", "b", "c"));
+ searchSpace.Add("int", new UniformIntOption(0, 1));
+
+ var parameter = Parameter.CreateNestedParameter();
+ parameter["choice"] = Parameter.FromString("a");
+ parameter["int"] = Parameter.FromInt(0);
+ searchSpace.MappingToFeatureSpace(parameter).Should().Equal(0, 0);
+ }
+
+ [Fact]
+ public void SearchSpace_mapping_order_test()
+ {
+ // each dimension in uniform space should be mapping to the options under nest option in a certain (key ascending) order.
+ var searchSpace = new SearchSpace();
+ searchSpace["a"] = new UniformIntOption(0, 1);
+ searchSpace["b"] = new UniformIntOption(1, 2);
+ searchSpace["c"] = new UniformIntOption(2, 3);
+
+ // changing of the first dimension should be reflected in option "a"
+ var parameter = searchSpace.SampleFromFeatureSpace(new double[] { 0, 0.5, 0.5 });
+ parameter["a"].AsType().Should().Be(0);
+ parameter = searchSpace.SampleFromFeatureSpace(new double[] { 1, 0.5, 0.5 });
+ parameter["a"].AsType().Should().Be(1);
+
+ searchSpace.Remove("a");
+
+ // the first dimension should be option "b"
+ parameter = searchSpace.SampleFromFeatureSpace(new double[] { 0, 0.5 });
+ parameter["b"].AsType().Should().Be(1);
+ parameter = searchSpace.SampleFromFeatureSpace(new double[] { 1, 0.5 });
+ parameter["b"].AsType().Should().Be(2);
+ }
+
+ [Fact]
+ [UseApprovalSubdirectory("ApprovalTests")]
+ [UseReporter(typeof(DiffReporter))]
+ public void Trainer_default_search_space_test()
+ {
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ CreateAndVerifyDefaultSearchSpace();
+ }
+
+ private void CreateAndVerifyDefaultSearchSpace()
+ where TOption : class, new()
+ {
+ var ss = new SearchSpace();
+ var json = JsonSerializer.Serialize(ss, _settings);
+ NamerFactory.AdditionalInformation = typeof(TOption).FullName;
+ Approvals.Verify(json);
+ }
+
private class DefaultSearchSpace
{
public int Int { get; set; }
@@ -253,5 +361,27 @@ private class NestSearchSpace
[Range(-1000.0f, 1000, init: 0)]
public float UniformFloat { get; set; }
}
+
+ class DoubleConverter : JsonConverter
+ {
+ public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ => Convert.ToDouble(reader.GetDecimal());
+
+ public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options)
+ {
+ writer.WriteNumberValue(Math.Round(Convert.ToDecimal(value), 6));
+ }
+ }
+
+ class SingleConverter : JsonConverter
+ {
+ public override float Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ => Convert.ToSingle(reader.GetDecimal());
+
+ public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOptions options)
+ {
+ writer.WriteNumberValue(Convert.ToDecimal(value));
+ }
+ }
}
}