将 ML.NET 的 CreatePredictionEngine 与发射类型一起使用

问题描述

对于我正在处理的项目,我需要使用 ML.NETCreatePredictionEngine 方法以及 TSrcTDst 的发射类型。我用 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 });

这里,inputObjectoutputObject 是我发出的类的实例。

然后,我像这样运行预测引擎:

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 是我创建的类的名称):

Debugger screenshot

作为参考,这里是我的 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 });