ML.net C#中如何在运行时动态设置ColumnName与VectorType参数
解决方案
方案1:管道末尾追加列映射统一输出结构(优先推荐,实现成本最低)
你不需要尝试修改特性的动态参数,只要在ONNX推理之后的处理管道中,把动态输出的列统一映射为固定结构即可完美适配预定义的预测类:
- 预测类直接写死固定特性参数,
[VectorType]不指定长度时ML.NET会自动适配运行时的向量维度:
class MLObjectDetectionPrediction { [VectorType] [ColumnName("FixedOutput")] public float[] Output { get; set; } [ColumnName("width")] public float ImageWidth { get; set; } [ColumnName("height")] public float ImageHeight { get; set; } }
- 在
ApplyOnnxModel后追加列转换逻辑,把动态输出的列映射为固定列:
var pipeline = mLContext.Transforms.ResizeImages(inputColumnName: MachineLearningModelObject.ImageInputColumnName, outputColumnName: MachineLearningModelObject.ImageOutputColumnName, imageWidth: MachineLearningModelObject.ImageWidth, imageHeight: MachineLearningModelObject.ImageHeight, resizing: Microsoft.ML.Transforms.Image.ImageResizingEstimator.ResizingKind.Fill) .Append(mLContext.Transforms.ExtractPixels(outputColumnName: MachineLearningModelObject.ImageOutputColumnName, scaleImage: 1f / 255f, interleavePixelColors: false)) .Append(mLContext.Transforms.ApplyOnnxModel( shapeDictionary: new Dictionary<string, int[]>() { { MachineLearningModelObject.ModelInputColumnName, MachineLearningModelObject.ModelInputVector }, { MachineLearningModelObject.ModelOutputColumnName, MachineLearningModelObject.ModelOutputVector} }, inputColumnName: MachineLearningModelObject.ModelInputColumnName, outputColumnName: MachineLearningModelObject.ModelOutputColumnName, modelFile: MachineLearningModelObject.ModelName )) // 新增转换逻辑,适配所有动态模型输出 .Append(mLContext.Transforms.CopyColumns("FixedOutput", MachineLearningModelObject.ModelOutputColumnName)) .Append(mLContext.Transforms.DropColumns(MachineLearningModelObject.ModelOutputColumnName));
方案2:使用非泛型API直接操作IDataView(灵活性最高)
如果切换的模型输出结构差异极大,不需要定义预测类,直接用非泛型API动态读取输出列即可:
// 构造输入数据 var inputData = new List<MLImageObject> { yourInputObject }; var inputDV = mLContext.Data.LoadFromEnumerable(inputData); // 直接推理得到输出 var outputDV = model.Transform(inputDV); // 运行时动态读取指定列 var predictResult = outputDV.GetColumn<float[]>(MachineLearningModelObject.ModelOutputColumnName).First(); var width = outputDV.GetColumn<float>("width").First(); var height = outputDV.GetColumn<float>("height").First();
内容的提问来源于stack exchange,提问作者Pietr Podschinski
相关产品推荐
相关产品推荐

