Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用动态类创建ML.NET预测引擎_C#_Ml.net - Fatal编程技术网

C# 使用动态类创建ML.NET预测引擎

C# 使用动态类创建ML.NET预测引擎,c#,ml.net,C#,Ml.net,我有一个ML.NET应用程序,我必须在编译后动态创建接口IDataView,以用于培训。我发现了这一点,并成功地为训练数据集创建了一个动态界面,然后使用它来训练模型。当我试图使用同一个接口来使用经过训练的模型创建预测时,我的问题就出现了。建议您创建一个预测引擎,其中必须定义输入和输出类类型才能创建引擎。比如: mlContext.Model.CreatePredictionEngine<TSrc,TDst>(ITransformer, DataViewSchema) mlConte

我有一个ML.NET应用程序,我必须在编译后动态创建接口IDataView,以用于培训。我发现了这一点,并成功地为训练数据集创建了一个动态界面,然后使用它来训练模型。当我试图使用同一个接口来使用经过训练的模型创建预测时,我的问题就出现了。建议您创建一个预测引擎,其中必须定义输入和输出类类型才能创建引擎。比如:

mlContext.Model.CreatePredictionEngine<TSrc,TDst>(ITransformer, DataViewSchema)
mlContext.Model.CreatePredictionEngine(ITransformer,DataViewSchema)
其中TSrcTDst是编译时已知的类类型。我的问题是,我在编译时不知道输入类类型的结构,必须为输入数据源创建一个动态接口。由于参数是已知的,所以可以定义输出类对象,但我不确定如何处理动态输入

我想我可以尝试在接口上使用类似GetType()的东西,但它说“隐式类型变量不能有多个声明器”。我的简化示例如下所示:

public class ModelOutput
{
    public string PredictedLabel { get; set; }
    public float[] Score { get; set; }
}

public class MakePrediction
{
    protected void Solve(IDataView data, ITransformer model)
    {
        var mlContext = new MLContext();
        var engine = mlContext.Model.CreatePredictionEngine<data.GetType(), ModelOutput>(model, data.Schema);
    }
}
公共类模型输出
{
公共字符串PredictedLabel{get;set;}
公共浮点[]分数{get;set;}
}
公共类预测
{
受保护的无效解算(IDataView数据、ITransformer模型)
{
var mlContext=新的mlContext();
var engine=mlContext.Model.CreatePredictionEngine(Model,data.Schema);
}
}

查找MethodInfo.MakeGenericMethod()

可以生成一个运行时类,其中包含DataViewSchema中列出的所有字段。这将允许您创建PredictionEngine

您将无法直接创建PredictionEngine,您必须调用它。以下是一些示例代码:

        // Create runtime type from fields and types in a DataViewSchema
        var runtimeType = ClassFactory.CreateType(dataViewSchema);

        dynamic dynamicPredictionEngine;
        var genericPredictionMethod = mlContext.Model.GetType().GetMethod("CreatePredictionEngine", new[] { typeof(ITransformer), typeof(DataViewSchema) });
        var predictionMethod = genericPredictionMethod.MakeGenericMethod(runtimeType, typeof(PricePrediction));
        dynamicPredictionEngine = predictionMethod.Invoke(mlContext.Model, new object[] { model, dataViewSchema });
要实际使用PredictionEngine(dynamicPredictionEngine),请使用类似于以下内容的调用:

var predictMethod = dynamicPredictionEngine.GetType().GetMethod("Predict", new[] { runtimeType });
var predict = predictMethod.Invoke(dynamicPredictionEngine, new[] { inputObject });
我使用了源代码的修改副本(上面的ClassFactory)。My copy接受DataViewSchema以自动生成requires类。代码如下:

using Microsoft.ML;
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;

public static class ClassFactory
{
    private static AssemblyName _assemblyName;

    public static object CreateObject(string[] PropertyNames, Type[] Types)
    {
        _assemblyName = new AssemblyName("DynamicInput");

        if (PropertyNames.Length != Types.Length)
        {
            Console.WriteLine("The number of property names should match their corresponding types number");
        }

        TypeBuilder DynamicClass = CreateTypeBuilder();
        CreateConstructor(DynamicClass);
        for (int ind = 0; ind < PropertyNames.Count(); ind++)
            CreateProperty(DynamicClass, PropertyNames[ind], Types[ind]);
        Type type = DynamicClass.CreateType();

        return Activator.CreateInstance(type);
    }

    public static Type CreateType(DataViewSchema dataViewSchema)
    {
        _assemblyName = new AssemblyName("DynamicInput");

        TypeBuilder DynamicClass = CreateTypeBuilder();
        CreateConstructor(DynamicClass);
        foreach (var item in dataViewSchema)
        {
            CreateProperty(DynamicClass, item.Name, item.Type.RawType);
        }

        return DynamicClass.CreateType(); 
    }

    private static TypeBuilder CreateTypeBuilder()
    {
        AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
        TypeBuilder typeBuilder = moduleBuilder.DefineType(_assemblyName.FullName
                            , TypeAttributes.Public |
                            TypeAttributes.Class |
                            TypeAttributes.AutoClass |
                            TypeAttributes.AnsiClass |
                            TypeAttributes.BeforeFieldInit |
                            TypeAttributes.AutoLayout
                            , null);
        return typeBuilder;
    }

    private static void CreateConstructor(TypeBuilder typeBuilder)
    {
        typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
    }

    private static void CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType)
    {
        FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);

        PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
        MethodBuilder getPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
        ILGenerator getIl = getPropMthdBldr.GetILGenerator();

        getIl.Emit(OpCodes.Ldarg_0);
        getIl.Emit(OpCodes.Ldfld, fieldBuilder);
        getIl.Emit(OpCodes.Ret);

        MethodBuilder setPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName,
              MethodAttributes.Public |
              MethodAttributes.SpecialName |
              MethodAttributes.HideBySig,
              null, new[] { propertyType });

        ILGenerator setIl = setPropMthdBldr.GetILGenerator();
        Label modifyProperty = setIl.DefineLabel();
        Label exitSet = setIl.DefineLabel();

        setIl.MarkLabel(modifyProperty);
        setIl.Emit(OpCodes.Ldarg_0);
        setIl.Emit(OpCodes.Ldarg_1);
        setIl.Emit(OpCodes.Stfld, fieldBuilder);

        setIl.Emit(OpCodes.Nop);
        setIl.MarkLabel(exitSet);
        setIl.Emit(OpCodes.Ret);

        propertyBuilder.SetGetMethod(getPropMthdBldr);
        propertyBuilder.SetSetMethod(setPropMthdBldr);
    }
}
使用Microsoft.ML;
使用制度;
使用System.Linq;
运用系统反思;
使用System.Reflection.Emit;
公共静态类工厂
{
私有静态AssemblyName _AssemblyName;
公共静态对象CreateObject(字符串[]属性名称,类型[]类型)
{
_assemblyName=新的assemblyName(“DynamicInput”);
if(PropertyNames.Length!=类型.Length)
{
Console.WriteLine(“属性名称的数量应与其对应的类型编号相匹配”);
}
TypeBuilder DynamicClass=CreateTypeBuilder();
CreateConstructor(DynamicClass);
对于(int ind=0;ind
你能帮我翻译一下吗