diff --git a/Microsoft.ML.sln b/Microsoft.ML.sln
index 8b6a05ffda..5b90ca306b 100644
--- a/Microsoft.ML.sln
+++ b/Microsoft.ML.sln
@@ -121,6 +121,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.AutoML", "src\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.AutoML.Samples", "docs\samples\Microsoft.ML.AutoML.Samples\Microsoft.ML.AutoML.Samples.csproj", "{A6924919-9E37-4023-8B7F-E85C8E3CC9B3}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.AutoML.Interactive", "src\Microsoft.ML.AutoML.Interactive\Microsoft.ML.AutoML.Interactive.csproj", "{3B00090A-B5E4-4570-BCD0-B4CD5D499394}"
+EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.Samples.GPU", "docs\samples\Microsoft.ML.Samples.GPU\Microsoft.ML.Samples.GPU.csproj", "{3C8F910B-7F23-4D25-B521-6D5AC9570ADD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.Featurizers", "src\Microsoft.ML.Featurizers\Microsoft.ML.Featurizers.csproj", "{E2DD0721-5B0F-4606-8182-4C7EFB834518}"
@@ -155,7 +157,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.SearchSpace.Te
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.AutoML.SourceGenerator", "tools-local\Microsoft.ML.AutoML.SourceGenerator\Microsoft.ML.AutoML.SourceGenerator.csproj", "{C804B990-390E-41D7-8FF1-6774495D70E2}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.ML.TorchSharp", "src\Microsoft.ML.TorchSharp\Microsoft.ML.TorchSharp.csproj", "{FF0BD187-4451-4A3B-934B-2AE3454896E2}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.TorchSharp", "src\Microsoft.ML.TorchSharp\Microsoft.ML.TorchSharp.csproj", "{FF0BD187-4451-4A3B-934B-2AE3454896E2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -597,6 +599,14 @@ Global
{A6924919-9E37-4023-8B7F-E85C8E3CC9B3}.Release|Any CPU.Build.0 = Release|Any CPU
{A6924919-9E37-4023-8B7F-E85C8E3CC9B3}.Release|x64.ActiveCfg = Release|Any CPU
{A6924919-9E37-4023-8B7F-E85C8E3CC9B3}.Release|x64.Build.0 = Release|Any CPU
+ {3B00090A-B5E4-4570-BCD0-B4CD5D499394}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3B00090A-B5E4-4570-BCD0-B4CD5D499394}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3B00090A-B5E4-4570-BCD0-B4CD5D499394}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3B00090A-B5E4-4570-BCD0-B4CD5D499394}.Debug|x64.Build.0 = Debug|Any CPU
+ {3B00090A-B5E4-4570-BCD0-B4CD5D499394}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3B00090A-B5E4-4570-BCD0-B4CD5D499394}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3B00090A-B5E4-4570-BCD0-B4CD5D499394}.Release|x64.ActiveCfg = Release|Any CPU
+ {3B00090A-B5E4-4570-BCD0-B4CD5D499394}.Release|x64.Build.0 = Release|Any CPU
{3C8F910B-7F23-4D25-B521-6D5AC9570ADD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C8F910B-7F23-4D25-B521-6D5AC9570ADD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C8F910B-7F23-4D25-B521-6D5AC9570ADD}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -796,6 +806,7 @@ Global
{C2652287-CD6D-40FB-B042-95FB56D09DB8} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4}
{E48285BF-F49A-4EA3-AED0-1BDDBF77EB80} = {09EADF06-BE25-4228-AB53-95AE3E15B530}
{A6924919-9E37-4023-8B7F-E85C8E3CC9B3} = {DA452A53-2E94-4433-B08C-041EDEC729E6}
+ {3B00090A-B5E4-4570-BCD0-B4CD5D499394} = {09EADF06-BE25-4228-AB53-95AE3E15B530}
{3C8F910B-7F23-4D25-B521-6D5AC9570ADD} = {DA452A53-2E94-4433-B08C-041EDEC729E6}
{E2DD0721-5B0F-4606-8182-4C7EFB834518} = {09EADF06-BE25-4228-AB53-95AE3E15B530}
{56CB0850-7341-4D71-9AE4-9EFC472D93DD} = {09EADF06-BE25-4228-AB53-95AE3E15B530}
diff --git a/eng/Versions.props b/eng/Versions.props
index da4fc00545..5178e7ece8 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -35,8 +35,8 @@
2.3.1
3.3.0
3.9.0
- 1.0.0-beta.22103.1
- 1.0.0-beta.22103.1
+ 1.0.0-beta.22314.1
+ 1.0.0-beta.22314.1
0.4.1
1.10.0
0.0.0.12
@@ -44,6 +44,7 @@
2.1.0
10.0.3
2.1.3
+ 0.0.1
1.3.3
0.20.1
2
diff --git a/src/Microsoft.ML.AutoML.Interactive/ActionThrottler.cs b/src/Microsoft.ML.AutoML.Interactive/ActionThrottler.cs
new file mode 100644
index 0000000000..16c15b947a
--- /dev/null
+++ b/src/Microsoft.ML.AutoML.Interactive/ActionThrottler.cs
@@ -0,0 +1,50 @@
+// 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.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Microsoft.ML.AutoML
+{
+ internal class ActionThrottler
+ {
+ private readonly Action _action;
+ private readonly TimeSpan _minDelay;
+
+ private DateTime _nextUpdateTime = DateTime.MinValue;
+ private int _updatePending = 0;
+
+ ///
+ /// This constructor initializes an ActionThrottler that ensures runs no more than once per .
+ ///
+ /// The action to thorttle.
+ /// Timespan to indicate the minimum delay between each time action is executed.
+ public ActionThrottler(Action action, TimeSpan minDelay)
+ {
+ _minDelay = minDelay;
+ _action = action;
+ }
+
+
+ public async Task ExecuteAsync()
+ {
+ if (Interlocked.CompareExchange(ref _updatePending, 1, 0) == 0) // _updatePending is int initialized with 0
+ {
+ DateTime currentTime = DateTime.UtcNow;
+
+ if (_nextUpdateTime > currentTime)
+ {
+ await Task.Delay(_nextUpdateTime - currentTime);
+ }
+ _action();
+ _nextUpdateTime = DateTime.UtcNow + _minDelay;
+ _updatePending = 0;
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.ML.AutoML.Interactive/AutoMLMonitorKernelExtension.cs b/src/Microsoft.ML.AutoML.Interactive/AutoMLMonitorKernelExtension.cs
new file mode 100644
index 0000000000..7868a24b4c
--- /dev/null
+++ b/src/Microsoft.ML.AutoML.Interactive/AutoMLMonitorKernelExtension.cs
@@ -0,0 +1,103 @@
+// 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.AspNetCore.Html;
+using Microsoft.Data.Analysis;
+using Microsoft.DotNet.Interactive;
+using Microsoft.DotNet.Interactive.Commands;
+using Microsoft.DotNet.Interactive.Formatting;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.Json;
+using System.Threading.Tasks;
+using Plotly.NET.CSharp;
+using static Microsoft.DotNet.Interactive.Formatting.PocketViewTags;
+
+
+namespace Microsoft.ML.AutoML
+{
+ public class AutoMLMonitorKernelExtension : IKernelExtension
+ {
+ public async Task OnLoadAsync(Kernel kernel)
+ {
+ Formatter.Register((monitor, writer) =>
+ {
+ WriteSummary(monitor, writer);
+ WriteChart(monitor, writer);
+ WriteTable(monitor, writer);
+ }, "text/html");
+
+ if (Kernel.Root?.FindKernel("csharp") is { } csKernel)
+ {
+ await LoadExtensionApiAsync(csKernel);
+ }
+ }
+
+ private static async Task LoadExtensionApiAsync(Kernel cSharpKernel)
+ {
+ await cSharpKernel.SendAsync(new SubmitCode($@"#r ""{typeof(AutoMLMonitorKernelExtension).Assembly.Location}""
+using {typeof(NotebookMonitor).Namespace};"));
+ }
+
+ private static void WriteSummary(NotebookMonitor monitor, TextWriter writer)
+ {
+
+ var summary = new List();
+
+ if (monitor.BestTrial != null)
+ {
+ var bestTrialParam = JsonSerializer.Serialize(monitor.BestTrial.TrialSettings.Parameter, new JsonSerializerOptions() { WriteIndented = true, });
+ summary.Add(h3("Best Trial"));
+ summary.Add(p($"Id: {monitor.BestTrial.TrialSettings.TrialId}"));
+ summary.Add(p($"Trainer: {monitor.BestTrial.TrialSettings.Pipeline}".Replace("Unknown=>", "")));
+ summary.Add(p($"Parameters: {bestTrialParam}"));
+ }
+ if (monitor.ActiveTrial != null)
+ {
+
+ var activeTrialParam = JsonSerializer.Serialize(monitor.ActiveTrial.Parameter, new JsonSerializerOptions() { WriteIndented = true, });
+
+ summary.Add(h3("Active Trial"));
+ summary.Add(p($"Id: {monitor.ActiveTrial.TrialId}"));
+ summary.Add(p($"Trainer: {monitor.ActiveTrial.Pipeline}".Replace("Unknown=>", "")));
+ summary.Add(p($"Parameters: {activeTrialParam}"));
+ }
+
+ writer.Write(div(summary));
+ }
+
+ private static void WriteChart(NotebookMonitor monitor, TextWriter writer)
+ {
+ var x = monitor.CompletedTrials.Select(x => x.TrialSettings.TrialId);
+ var y = monitor.CompletedTrials.Select(x => x.Metric);
+
+ var chart = Chart.Point(x, y, "Plot Metrics over Trials.")
+ .WithTraceInfo(ShowLegend: false)
+ .WithXAxisStyle(TitleText: "Trial", ShowGrid: false)
+ .WithYAxisStyle(TitleText: "Metric", ShowGrid: false);
+
+ var chartHeader = new List();
+ chartHeader.Add(h3("Plot Metrics over Trials"));
+ writer.Write(div(chartHeader));
+
+
+ Formatter.GetPreferredFormatterFor(typeof(Plotly.NET.GenericChart.GenericChart), "text/html").Format(chart, writer);
+
+ // Works around issue with earlier versions of Plotly.NET - https://github.com/plotly/Plotly.NET/pull/305
+ if (writer.ToString().EndsWith("");
+ }
+ }
+
+ private static void WriteTable(NotebookMonitor notebookMonitor, TextWriter writer)
+ {
+ var tableHeader = new List();
+ tableHeader.Add(h3("All Trials Table"));
+ writer.Write(div(tableHeader));
+ Formatter.GetPreferredFormatterFor(typeof(DataFrame), "text/html").Format(notebookMonitor.TrialData, writer);
+ }
+ }
+}
diff --git a/src/Microsoft.ML.AutoML.Interactive/Microsoft.ML.AutoML.Interactive.csproj b/src/Microsoft.ML.AutoML.Interactive/Microsoft.ML.AutoML.Interactive.csproj
new file mode 100644
index 0000000000..15040401ee
--- /dev/null
+++ b/src/Microsoft.ML.AutoML.Interactive/Microsoft.ML.AutoML.Interactive.csproj
@@ -0,0 +1,20 @@
+
+
+
+ net6.0
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.ML.AutoML.Interactive/NotebookMonitor.cs b/src/Microsoft.ML.AutoML.Interactive/NotebookMonitor.cs
new file mode 100644
index 0000000000..6e401d87d7
--- /dev/null
+++ b/src/Microsoft.ML.AutoML.Interactive/NotebookMonitor.cs
@@ -0,0 +1,86 @@
+// 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.DotNet.Interactive;
+using System.Collections.Generic;
+using Microsoft.Data.Analysis;
+using System;
+using System.Threading.Tasks;
+using System.Text.Json;
+using System.Threading;
+
+namespace Microsoft.ML.AutoML
+{
+ public class NotebookMonitor : IMonitor
+ {
+ private readonly ActionThrottler _updateThrottler;
+ private DisplayedValue _valueToUpdate;
+
+ public TrialResult BestTrial { get; set; }
+ public TrialResult MostRecentTrial { get; set; }
+ public TrialSettings ActiveTrial { get; set; }
+ public List CompletedTrials { get; set; }
+ public DataFrame TrialData { get; set; }
+
+ public NotebookMonitor()
+ {
+ CompletedTrials = new List();
+ TrialData = new DataFrame(new PrimitiveDataFrameColumn("Trial"), new PrimitiveDataFrameColumn("Metric"), new StringDataFrameColumn("Trainer"), new StringDataFrameColumn("Parameters"));
+ _updateThrottler = new ActionThrottler(Update, TimeSpan.FromSeconds(5));
+ }
+
+ public void ReportBestTrial(TrialResult result)
+ {
+ BestTrial = result;
+
+ ThrottledUpdate();
+ }
+
+ public void ReportCompletedTrial(TrialResult result)
+ {
+ MostRecentTrial = result;
+ CompletedTrials.Add(result);
+
+ var activeRunParam = JsonSerializer.Serialize(result.TrialSettings.Parameter, new JsonSerializerOptions() { WriteIndented = false, });
+
+ TrialData.Append(new List>()
+ {
+ new KeyValuePair("Trial",result.TrialSettings.TrialId),
+ new KeyValuePair("Metric", result.Metric),
+ new KeyValuePair("Trainer",result.TrialSettings.Pipeline.ToString().Replace("Unknown=>","")),
+ new KeyValuePair("Parameters",activeRunParam),
+ }, true);
+
+ ThrottledUpdate();
+ }
+
+ public void ReportFailTrial(TrialResult result)
+ {
+ // TODO figure out what to do with failed trials.
+ ThrottledUpdate();
+ }
+
+ public void ReportRunningTrial(TrialSettings setting)
+ {
+ ActiveTrial = setting;
+ ThrottledUpdate();
+ }
+
+ private void ThrottledUpdate()
+ {
+ Task.Run(async () => await _updateThrottler.ExecuteAsync());
+ }
+
+ public void Update()
+ {
+ _valueToUpdate.Update(this);
+ }
+
+ public void SetUpdate(DisplayedValue valueToUpdate)
+ {
+ _valueToUpdate = valueToUpdate;
+ ThrottledUpdate();
+ }
+ }
+}
diff --git a/src/Microsoft.ML.AutoML/Microsoft.ML.AutoML.csproj b/src/Microsoft.ML.AutoML/Microsoft.ML.AutoML.csproj
index 36a14ec5ce..2a223df06f 100644
--- a/src/Microsoft.ML.AutoML/Microsoft.ML.AutoML.csproj
+++ b/src/Microsoft.ML.AutoML/Microsoft.ML.AutoML.csproj
@@ -6,8 +6,29 @@
Microsoft.ML.AutoML
ML.NET AutoML: Optimizes an ML pipeline for your dataset, by automatically locating the best feature engineering, model, and hyperparameters
$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage
+
+
+ $(NoWarn);1591;NU5100
+ $(TargetsForTfmSpecificContentInPackage);AddAutoMLInteractiveToInteractiveExtensionsFolder
+
+
+
+
+
+
+
+
+
+ <_ItemsToIncludeForInteractive Update="@(_ItemsToIncludeForInteractive)" PackagePath="interactive-extensions/dotnet" />
+
+
+
+