ML.NET无法提取训练模型参数的问题求助
无法将TransformerChain转换为ISingleFeaturePredictionTransformer的问题
问题场景
我参照微软官网代码尝试重新训练模型,执行提取训练模型参数的代码时触发类型转换错误。
提取参数的代码
// Extract trained model parameters var originalModelParameters = ((ISingleFeaturePredictionTransformer<object>)trainedModel).Model as PoissonRegressionModelParameters;
报错信息
System.InvalidCastException: 'Unable to cast object of type 'Microsoft.ML.Data.TransformerChain`1[Microsoft.ML.ITransformer]' to type 'Microsoft.ML.ISingleFeaturePredictionTransformer`1[System.Object]'.'
相关代码
保存数据预处理和模型的代码
var csvmodel = csvpipeline.Fit(csvTrainingDataView); // Define data preparation estimator IEstimator<ITransformer> dataPrepEstimator = mlContext.Transforms.Concatenate("Features", new string[] { "t" }) .Append(mlContext.Transforms.NormalizeMinMax("Features")); // Create data preparation transformer ITransformer dataPrepTransformer = dataPrepEstimator.Fit(csvTrainingDataView); // Define StochasticDualCoordinateAscent regression algorithm estimator var Estimator = mlContext.Regression.Trainers.LbfgsPoissonRegression(); // Pre-process data using data prep operations IDataView transformedData = dataPrepTransformer.Transform(csvTrainingDataView); //savemodel //csv savemodel savemodel(csvmlContext, csvmodel, transformedData); /* var modelPath = string.Format("{0}/MODEL/{1}-{2}.zip", Environment.CurrentDirectory,"Model","Testing"); using (var fileStream = new FileStream(modelPath, FileMode.Create, FileAccess.Write, FileShare.Write)) csvmlContext.Model.Save(csvmodel, csvTrainingDataView.Schema, fileStream);*/ // Save Data Prep transformer savedatprep(csvmlContext, dataPrepTransformer, csvTrainingDataView);
保存方法代码
static void savemodel(MLContext mlcontext,ITransformer model,IDataView Data) { var modelPath = string.Format("{0}/MODEL/{1}-{2}.zip", Environment.CurrentDirectory, "Model", "Testing"); using (var fileStream = new FileStream(modelPath, FileMode.Create, FileAccess.Write, FileShare.Write)) mlcontext.Model.Save(model, Data.Schema, fileStream); } static void savedatprep(MLContext mlcontext, ITransformer model, IDataView Data) { var modelDataPrepPath = string.Format("{0}/MODEL/{1}-{2}.zip", Environment.CurrentDirectory, "Model", "Testing_DataPrep"); using (var fileStream = new FileStream(modelDataPrepPath, FileMode.Create, FileAccess.Write, FileShare.Write)) mlcontext.Model.Save(model, Data.Schema, fileStream); }
数据文件结构(表头及第一行)
t,o,h,l,c,s,z,q,n,v,x,y,Ema,Rsi,Macd,MacdSign,MacdHistN3,MacdHistN2,MacdHistN1,MacdHistN0,FuturePrice 16636653,1.283,1.283,1.271,1.278,133642.8,1663666199999,170622.876,751,67266.6,85853.53,0,0,45.80812565453984,69.7112186336032,69.38782605382958,3.3440424757016984,2.8439819612832054,1.640807326496386,0.3233925797736106,0
已尝试操作
- 调整保存流程
- 查阅同类问题,确认参数类型与保存模型一致
解决建议
- 从TransformerChain中定位训练模型节点
你保存的csvmodel是由多个转换器组成的TransformerChain,而非单独的Poisson回归模型。需要先从链中筛选出对应的训练模型节点:
// 遍历链找到训练模型节点 var trainedModelNode = ((TransformerChain<ITransformer>)trainedModel) .LastOrDefault(t => t is ISingleFeaturePredictionTransformer<object>); if (trainedModelNode != null) { var originalModelParameters = ((ISingleFeaturePredictionTransformer<object>)trainedModelNode).Model as PoissonRegressionModelParameters; // 后续参数操作 }
- 合并预处理与训练流程后保存完整模型
将数据预处理和训练估算器合并为一个完整流程,拟合后保存整个链,后续加载后可直接使用,也便于定位参数:
// 合并预处理与训练流程 var fullPipeline = dataPrepEstimator.Append(Estimator); // 拟合完整模型 var fullModel = fullPipeline.Fit(csvTrainingDataView); // 保存完整模型 savemodel(csvmlContext, fullModel, csvTrainingDataView);
提取参数时可借助TryGetScoreTransformer辅助获取:
if (mlContext.Model.TryGetScoreTransformer(fullModel, out var scoreTransformer)) { var modelParams = scoreTransformer.Model as PoissonRegressionModelParameters; // 使用模型参数 }
- 单独保存训练模型
如果仅需提取训练模型参数,可在训练完成后单独保存训练模型,而非整个预处理链:
// 单独训练模型 var trainedModel = Estimator.Fit(transformedData); // 保存训练模型 savemodel(csvmlContext, trainedModel, transformedData);
此时加载后可直接转换为ISingleFeaturePredictionTransformer<object>获取参数。
内容的提问来源于stack exchange,提问作者remington.
相关产品推荐
相关产品推荐

