hellobonjour,
I’m doing tests with node factories and ML.NET. The idea is that you can train an ML model with Visual Studio’s Model Builder and automagically turn it into a VL node with the appropriate inputs and outputs, kinda like VL.RunwayML does.
Visual Studio gives you this black-box zip file that’s been trained on your dataset, you drop it inside a folder next to your patch and you get a node that runs this model.
So far so good, I managed to get a node with the appropriate inputs and outputs and successfully run the model against some arbitrary input data. Here, you can see a model predicting taxi fare prices in New York City.
There’s one issue though : each time I change an input pin’s value or create a new node, or do any action that would trigger the GC (which shows up as this yellow marker in VS’ debugger), the output value of the node is reset to zero :
(For some reason, the orange/red bar under the quad menu does not show up when doing a gif recording…)
For the reference, here what’s happening inside the node’s Update()
:
public void Update()
{
if (!Inputs.Any())
return;
if((bool)Inputs.Last().Value)
{
// Create an input object that will hold our pin's data
var inputObject = Activator.CreateInstance(inputType);
// Stuff our input object with input pin's data
foreach (var input in Inputs.Cast<MyPin>().SkipLast(1))
{
inputType.InvokeMember(input.Name, BindingFlags.SetProperty, null, inputObject, new object[] { input.Value });
}
// Invoke the predict method
var predictMethod = predictionEngine.GetType().GetMethod("Predict", new[] { inputType });
var result = predictMethod.Invoke(predictionEngine, new[] { inputObject });
// Look for the "Score" output pin and assign it the value return by the prediction
var outputPin = Outputs.Cast<MyPin>().FirstOrDefault(o => o.Name == "Score");
outputPin.Value = outputType.InvokeMember("Score", BindingFlags.GetProperty, null, result, new object[] { });
}
}
If you wanna have a look at the code, the source is there.
Any idea what’s going on here? I guess the GC is getting rid of inputObject
, but how could I persist this?
Thanks!