问题描述
对于我正在处理的项目,我需要使用 ML.NET 的 CreatePredictionEngine 方法以及 TSrc
和 TDst
的发射类型。我用 System.Reflection.Emit
发出那些。
以下是我创建动态预测引擎的方法:
dynamic dynamicPredictionEngine;
var genericPredictionMethod = mlContext.Model.GetType().getmethod("CreatePredictionEngine",new[] { typeof(ITransformer),typeof(DataViewSchema) });
var predictionMethod = genericPredictionMethod.MakeGenericmethod(inputObject.GetType(),outputObject.GetType());
dynamicPredictionEngine = predictionMethod.Invoke(mlContext.Model,new object[] { TrainedModel,PredictionPipeline });
这里,inputObject
和 outputObject
是我发出的类的实例。
然后,我像这样运行预测引擎:
var result = dynamicPredictionEngine.Predict(inputObject)
但我得到以下异常:
'The best overloaded method match for 'microsoft.ml.PredictionEngineBase<Object0f33ea95-c496-4c57-bd2c-728bb65dd0a9,Object5623e4bd-ba82-42cf-876f-5e11a5cb8bb2>.Predict(Object0f33ea95-c496-4c57-bd2c-728bb65dd0a9)' has some invalid arguments'
您在此处看到的 GUID 是我发出的类的名称。
为了调试这个,我尝试手动创建一个与发出的属性相同的类,并再次运行预测引擎,手动创建的类为 TSrc
并将发出的类保持为 {{ 1}}。这一次,效果很好。
我查看调试器将发出的输入类与手动创建的类进行比较,它们似乎匹配(TDst
是我创建的类的名称):
作为参考,这里是我的 TaxiTrip
类的定义方式
TaxiTrip
有人知道这里发生了什么吗?
我已经在 SO 上偶然发现了 this question,但我的问题看起来有所不同:正如我所说,如果我手动创建一个没有任何属性的类(见上文),namespace VL.ML
{
class TaxiTrip
{
public string vendorId { get; set; }
public string RateCode { get; set; }
public float PassengerCount { get; set; }
public float TripTime { get; set; }
public float Tripdistance { get; set; }
public string PaymentType { get; set; }
public float fareAmount { get; set; }
}
}
工作得很好。另外,它似乎能够将我发出的类型用于 Predict
,那么为什么 TDst
会失败?
如有必要,很乐意提供更多详细信息。
提前致谢!
解决方法
您必须调用 Predict 方法:
var predictMethod = dynamicPredictionEngine.GetType().GetMethod("Predict",new[] { runtimeType });
var predict = predictMethod.Invoke(dynamicPredictionEngine,new[] { inputObject });