-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Public Constructors for ModelParameters #1866
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I think it make sense to some degree for me. |
Curious, how would you create an IPredictor by hand? Where would you get the values for the model parameters? |
With @najeeb-kazmi changes, like this: |
I can always explore predictor from training, and decide to manually boost certain weight or bias. |
I believe in general this positive changes. |
I think it would be super useful to be able to create some predictors by hand. I do this quite a bit to compare models across implementations and languages. This would make it way easier. This would be a more advanced usage, though. An interesting use-case that I could see becoming popular would be to create importers of non-ML.NET models for ML.NET predictor classes. For example, if you had an in-house tree learner, you could write custom code to import your models as a |
What @Ivanidzo4ka says is the primary reason I like public constructors. Being able to tweak the model and then plug it back into the system is a useful functionality. |
I suppose we can close it now |
re-opening this discussion.
|
Some scenarios where it's important to have public constructors: Adjusting model parameters: Often there are situations where you may want to modify some parameters based on prior knowledge, as @Ivanidzo4ka and @Zruty0 mention above. Importing models: Many people need to train models in custom systems, but need to deploy them in .NET. Imagine if you train a large-scale model in Spark or Hive and need to deploy it in .NET. Or your data scientists are using Python or R. You could hand-code some model, or you could simply plug in your linear model parameters, gradient-boosted-trees, or k-means parameters, etc. into ML.NET and use our framework for scoring. |
Can you write some code demonstrating how this then becomes used @rogancarr? Don't be afraid to be specific; links to actual code would be most informative. If I take your statements as mere theoretical benefits, it is difficult to see how they're actually become practical. You can't just take one of these models and make a transformer out of it. The model parameters are something you get out of the transformer you get by training. The reason why we have the trainers return a transformer rather than just having the user get the predictor and make a transformer out of it, is because it is kind of tricky, and highly scenario dependent. My impression is, that it's not useful right now, but with a hypothetical new surface area for creating transformers out of these things that does not exist, it might become useful. Is that so? |
Hi @TomFinley , Let me give you some examples where I go around the system and actually do this in ML.NET. First let's talk about Use Case No. 2: I do the following when I bring in models trained in different systems: public static ITransformer GetLinearModelScorerForFeature(MLContext mlContext)
{
Action<ScaleMapInputRow, ScaleMapOutputRow> mapping = (input, output) =>
{
output.Score = LinearModel.Score(input.features);
};
// Make a custom transformer and transform the data.
var transformer = mlContext.Transforms.CustomMappingTransformer(mapping, null);
return transformer;
} Here, I use a Now, when you do have proper model parameters, you can totally make transformers. I have code that does this too. In my case, I was instantiating models directly so that I could train with validation sets or do weird things to the training data outside of pipelines. When you do this, you receive the model parameters back (once called predictors) instead of a transformer. Here are some examples (v0.9 naming conventions): // OLS (needed to to strange non-pipeline operations on the training set)
var linearTransformer = new RegressionPredictionTransformer<OlsLinearRegressionPredictor>(mlContext, linearPredictor, trainSet.Schema, featureName);
// Binary classification linear models (needed to to strange non-pipeline operations on the training set)
if (returnLogit)
linearTransformer = new RegressionPredictionTransformer<IPredictorProducing<float>>(mlContext, linearPredictor.SubPredictor, trainSet.Schema, featureName);
else
linearTransformer = new BinaryPredictionTransformer<ParameterMixingCalibratedPredictor>(mlContext, linearPredictor, trainSet.Schema, featureName);
// Binary prediction GAM (needed validation)
gamTransformer = new BinaryPredictionTransformer<CalibratedPredictor>(mlContext, gamPredictor, trainSet.Schema, "Features");
// Regression GAM (needed validation)
gamTransformer = new RegressionPredictionTransformer<RegressionGamPredictor>(mlContext, gamPredictor, trainSet.Schema, "Features"); One of the beautiful things about ML.NET is how much expressivity you have. It allows you to be super creative in building solutions. This does result in rather hacky code sometimes (see above), but one thing that I worry about in closing down a lot of our APIs is losing the ability to do these creative workarounds. |
I see. As you've observed, But as you've also observed, there are lots of things that are still public that should not be. E.g., these constructors for However, this work is not completed. To give an example, I have this PR currently opened. #2245. Ivan points out correctly here that the constructor should not be public, instead we should work via a mechanism of There are also more red flags, like the current-but-not-forever exposure of things like marker interfaces like Note that it is insufficient at this stage for something to merely be useful, since we currently have a problem where we have a limited amount of time before we must "freeze" the API. Anything that is part of that API at that time must stay forever. Therefore the focus in the immediate term will be on actually closing off the public surface as much as possible, since we literally do not have capacity to do anything else (if we even have capacity to do this). If you wish to help with that, that might be a good way to help us get more capacity. |
Hi @TomFinley. That makes a lot of sense. I suppose that the first workaround that I use — creating a custom transformer with a custom model — will be a fine workaround for the next little bit then. |
So conclusion is following. We don't do it for v1.0, but will explore that option post release. |
@Ivanidzo4ka We will need a new issue for Project 13 to re-internalize these APIs |
During the course of fixing #1698 and deriving work items (e.g. #1699, #1701, #1702), we created public constructors for the various
ModelParameter
objects (formerlyPredictor
objects).@sfilipi raised the question whether these should be public or be made internal as the only thing that can create
ModelParameters
(Predictors
) is training a model. What use case are we supporting with this? When might a user want to create say aLinearRegressionModelParameters
object with bias and weights instead of training a linear regression model?The text was updated successfully, but these errors were encountered: