ML.Net中AddPredictionEnginePool无zip文件及默认模型配置问题
ML.NET PredictionEnginePool 配置问题解决与完整示例
一、关于模型文件的疑问
- 无需手动将
.mlnet改名为.zip,训练完成后必须显式导出ZIP格式的模型。.mlnet是ML.NET项目的配置文件(记录训练管道、数据集路径等信息),并非可直接用于预测的序列化模型。训练代码中需添加导出逻辑:// 训练完成后 var trainedModel = pipeline.Fit(trainingData); // 导出为ZIP格式模型文件 trainedModel.Save("MyModel.zip"); - 导出后的ZIP包才是
PredictionEnginePool可加载的模型文件,内部包含序列化后的模型结构与参数。
二、报错原因:命名模型与默认模型的区别
你配置时指定了modelName: "MyModel",这属于命名模型,但调用_predictionEnginePool.Predict(testInput)时,该方法默认会寻找未命名的默认模型,因此触发报错。有两种解决方式:
方法1:配置默认模型(不指定modelName)
移除modelName参数,直接将模型配置为默认模型:
builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>() .FromFile(filePath: "D:\\MyCompany\\MyApp\\MyService.ApiService\\MyModel.zip", watchForChanges: true);
之后调用_predictionEnginePool.Predict(testInput)即可正常使用。
方法2:调用时指定命名模型
若需保留命名模型(如多模型场景),调用时需传入模型名称:
var prediction = _predictionEnginePool.Predict("MyModel", testInput);
三、完整可用示例
1. 训练并导出模型(控制台/类库项目)
using Microsoft.ML; using Microsoft.ML.Data; // 定义模型输入类 public class ModelInput { [LoadColumn(0)] public float Feature1 { get; set; } [LoadColumn(1)] public float Feature2 { get; set; } } // 定义模型输出类 public class ModelOutput { [ColumnName("Score")] public float Prediction { get; set; } } class Program { static void Main(string[] args) { var mlContext = new MLContext(); // 模拟训练数据集 var trainingData = mlContext.Data.LoadFromEnumerable(new[] { new ModelInput { Feature1 = 1f, Feature2 = 2f }, new ModelInput { Feature1 = 2f, Feature2 = 3f }, new ModelInput { Feature1 = 3f, Feature2 = 4f } }); // 构建训练管道 var pipeline = mlContext.Transforms.Concatenate("Features", nameof(ModelInput.Feature1), nameof(ModelInput.Feature2)) .Append(mlContext.Regression.Trainers.Sdca(labelColumnName: "Score", featureColumnName: "Features")); // 训练模型 var trainedModel = pipeline.Fit(trainingData); // 导出ZIP模型,之后复制到API项目目录 trainedModel.Save("MyModel.zip"); } }
2. API项目配置(Program.cs)
using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.ML; var builder = WebApplication.CreateBuilder(args); // 注册PredictionEnginePool服务,加载默认模型 builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>() .FromFile(filePath: "MyModel.zip", watchForChanges: true); // 添加控制器支持 builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run();
3. 控制器调用示例
using Microsoft.AspNetCore.Mvc; using Microsoft.ML; [ApiController] [Route("api/[controller]")] public class PredictionController : ControllerBase { private readonly PredictionEnginePool<ModelInput, ModelOutput> _predictionEnginePool; // 注入PredictionEnginePool public PredictionController(PredictionEnginePool<ModelInput, ModelOutput> predictionEnginePool) { _predictionEnginePool = predictionEnginePool; } [HttpPost] public IActionResult Predict([FromBody] ModelInput input) { // 使用默认模型执行预测 var result = _predictionEnginePool.Predict(input); return Ok(new { Prediction = result.Prediction }); } }
四、注意事项
- 确保ZIP模型文件路径正确,可在API项目中将模型文件的“复制到输出目录”设置为“如果较新则复制”,避免硬编码绝对路径。
PredictionEnginePool是线程安全的,适配多线程/高并发场景,禁止手动创建PredictionEngine(非线程安全)。
内容的提问来源于stack exchange,提问作者Age of Empires
相关产品推荐
相关产品推荐

