From c512a164025d0d64fe2f48cd47b44897b1b53e75 Mon Sep 17 00:00:00 2001 From: Ross Smith Date: Fri, 15 Jun 2018 17:32:55 +0100 Subject: [PATCH 1/2] Changed List to HashSet to ensure that there are no duplicates --- Microsoft.ML.sln | 7 ++ src/Microsoft.ML.Core/Prediction/ISweeper.cs | 5 ++ src/Microsoft.ML.Sweeper/Algorithms/Grid.cs | 8 +-- .../Microsoft.ML.Sweeper.Tests.csproj | 16 +++++ .../Microsoft.ML.Sweeper.Tests/SweeperTest.cs | 65 +++++++++++++++++++ 5 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 test/Microsoft.ML.Sweeper.Tests/Microsoft.ML.Sweeper.Tests.csproj create mode 100644 test/Microsoft.ML.Sweeper.Tests/SweeperTest.cs diff --git a/Microsoft.ML.sln b/Microsoft.ML.sln index 8f7dc39b88..57b077cec5 100644 --- a/Microsoft.ML.sln +++ b/Microsoft.ML.sln @@ -114,6 +114,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "netstandard2.0", "netstanda pkg\Microsoft.ML\build\netstandard2.0\Microsoft.ML.targets = pkg\Microsoft.ML\build\netstandard2.0\Microsoft.ML.targets EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.Sweeper.Tests", "test\Microsoft.ML.Sweeper.Tests\Microsoft.ML.Sweeper.Tests.csproj", "{3DEB504D-7A07-48CE-91A2-8047461CB3D4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -216,6 +218,10 @@ Global {362A98CF-FBF7-4EBB-A11B-990BBF845B15}.Debug|Any CPU.Build.0 = Debug|Any CPU {362A98CF-FBF7-4EBB-A11B-990BBF845B15}.Release|Any CPU.ActiveCfg = Release|Any CPU {362A98CF-FBF7-4EBB-A11B-990BBF845B15}.Release|Any CPU.Build.0 = Release|Any CPU + {3DEB504D-7A07-48CE-91A2-8047461CB3D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3DEB504D-7A07-48CE-91A2-8047461CB3D4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3DEB504D-7A07-48CE-91A2-8047461CB3D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3DEB504D-7A07-48CE-91A2-8047461CB3D4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -253,6 +259,7 @@ Global {362A98CF-FBF7-4EBB-A11B-990BBF845B15} = {09EADF06-BE25-4228-AB53-95AE3E15B530} {487213C9-E8A9-4F94-85D7-28A05DBBFE3A} = {DEC8F776-49F7-4D87-836C-FE4DC057D08C} {9252A8EB-ABFB-440C-AB4D-1D562753CE0F} = {487213C9-E8A9-4F94-85D7-28A05DBBFE3A} + {3DEB504D-7A07-48CE-91A2-8047461CB3D4} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {41165AF1-35BB-4832-A189-73060F82B01D} diff --git a/src/Microsoft.ML.Core/Prediction/ISweeper.cs b/src/Microsoft.ML.Core/Prediction/ISweeper.cs index a0a1850be0..b3dd0dc3da 100644 --- a/src/Microsoft.ML.Core/Prediction/ISweeper.cs +++ b/src/Microsoft.ML.Core/Prediction/ISweeper.cs @@ -174,6 +174,11 @@ public override string ToString() { return string.Join(" ", _parameterValues.Select(kvp => string.Format("{0}={1}", kvp.Value.Name, kvp.Value.ValueText)).ToArray()); } + + public override int GetHashCode() + { + return _hash; + } } /// diff --git a/src/Microsoft.ML.Sweeper/Algorithms/Grid.cs b/src/Microsoft.ML.Sweeper/Algorithms/Grid.cs index 734cf93e30..53e7046ebd 100644 --- a/src/Microsoft.ML.Sweeper/Algorithms/Grid.cs +++ b/src/Microsoft.ML.Sweeper/Algorithms/Grid.cs @@ -64,10 +64,10 @@ protected SweeperBase(ArgumentsBase args, IHostEnvironment env, IValueGenerator[ SweepParameters = sweepParameters; } - public virtual ParameterSet[] ProposeSweeps(int maxSweeps, IEnumerable previousRuns) + public virtual ParameterSet[] ProposeSweeps(int maxSweeps, IEnumerable previousRuns = null) { var prevParamSets = previousRuns?.Select(r => r.ParameterSet).ToList() ?? new List(); - var result = new List(); + var result = new HashSet(); for (int i = 0; i < maxSweeps; i++) { ParameterSet paramSet; @@ -150,12 +150,12 @@ public RandomGridSweeper(IHostEnvironment env, Arguments args, IValueGenerator[] } } - public override ParameterSet[] ProposeSweeps(int maxSweeps, IEnumerable previousRuns) + public override ParameterSet[] ProposeSweeps(int maxSweeps, IEnumerable previousRuns = null) { if (_nGridPoints == 0) return base.ProposeSweeps(maxSweeps, previousRuns); - var result = new List(); + var result = new HashSet(); var prevParamSets = (previousRuns != null) ? previousRuns.Select(r => r.ParameterSet).ToList() : new List(); diff --git a/test/Microsoft.ML.Sweeper.Tests/Microsoft.ML.Sweeper.Tests.csproj b/test/Microsoft.ML.Sweeper.Tests/Microsoft.ML.Sweeper.Tests.csproj new file mode 100644 index 0000000000..27d2484909 --- /dev/null +++ b/test/Microsoft.ML.Sweeper.Tests/Microsoft.ML.Sweeper.Tests.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp2.0 + CORECLR + false + + + true + AnyCPU + + + + + + diff --git a/test/Microsoft.ML.Sweeper.Tests/SweeperTest.cs b/test/Microsoft.ML.Sweeper.Tests/SweeperTest.cs new file mode 100644 index 0000000000..83b383f7dd --- /dev/null +++ b/test/Microsoft.ML.Sweeper.Tests/SweeperTest.cs @@ -0,0 +1,65 @@ +using Microsoft.ML.Runtime; +using Microsoft.ML.Runtime.CommandLine; +using Microsoft.ML.Runtime.Data; +using Microsoft.ML.Runtime.RunTests; +using Microsoft.ML.Runtime.Sweeper; +using System; +using System.IO; +using Xunit; + +namespace Microsoft.ML.Sweeper.Tests +{ + public class SweeperTest + { + [Fact] + public void UniformRandomSweeperReturnsDistinctValuesWhenProposeSweep() + { + DiscreteValueGenerator valueGenerator = CreateDiscreteValueGenerator(); + + using (var writer = new StreamWriter(new MemoryStream())) + using (var env = new TlcEnvironment(42, outWriter: writer, errWriter: writer)) + { + var sweeper = new UniformRandomSweeper(env, + new SweeperBase.ArgumentsBase(), + new[] { valueGenerator }); + + var results = sweeper.ProposeSweeps(3); + Assert.NotNull(results); + + int length = results.Length; + Assert.Equal(2, length); + } + } + + [Fact] + public void RandomGridSweeperReturnsDistinctValuesWhenProposeSweep() + { + DiscreteValueGenerator valueGenerator = CreateDiscreteValueGenerator(); + + using (var writer = new StreamWriter(new MemoryStream())) + using (var env = new TlcEnvironment(42, outWriter: writer, errWriter: writer)) + { + var sweeper = new RandomGridSweeper(env, + new RandomGridSweeper.Arguments(), + new[] { valueGenerator }); + + var results = sweeper.ProposeSweeps(3); + Assert.NotNull(results); + + int length = results.Length; + Assert.Equal(2, length); + } + } + + private static DiscreteValueGenerator CreateDiscreteValueGenerator() + { + var args = new DiscreteParamArguments() + { + Name = "TestParam", + Values = new string[] { "one", "two" } + }; + + return new DiscreteValueGenerator(args); + } + } +} From 6fa2e9bfbee77ad352637cc78bc7755565808ab2 Mon Sep 17 00:00:00 2001 From: Ross Smith Date: Tue, 19 Jun 2018 17:18:05 +0100 Subject: [PATCH 2/2] Added standard file header and removed AllowUnsafeBlocks from project file --- .../Microsoft.ML.Sweeper.Tests.csproj | 4 ---- test/Microsoft.ML.Sweeper.Tests/SweeperTest.cs | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Microsoft.ML.Sweeper.Tests/Microsoft.ML.Sweeper.Tests.csproj b/test/Microsoft.ML.Sweeper.Tests/Microsoft.ML.Sweeper.Tests.csproj index 27d2484909..3364b79fda 100644 --- a/test/Microsoft.ML.Sweeper.Tests/Microsoft.ML.Sweeper.Tests.csproj +++ b/test/Microsoft.ML.Sweeper.Tests/Microsoft.ML.Sweeper.Tests.csproj @@ -5,10 +5,6 @@ CORECLR false - - true - AnyCPU - diff --git a/test/Microsoft.ML.Sweeper.Tests/SweeperTest.cs b/test/Microsoft.ML.Sweeper.Tests/SweeperTest.cs index 83b383f7dd..4bcb69874f 100644 --- a/test/Microsoft.ML.Sweeper.Tests/SweeperTest.cs +++ b/test/Microsoft.ML.Sweeper.Tests/SweeperTest.cs @@ -1,3 +1,7 @@ +// 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 Microsoft.ML.Runtime; using Microsoft.ML.Runtime.CommandLine; using Microsoft.ML.Runtime.Data;