Модель ml.net работает с консольным приложением, но не с веб-интерфейсом - PullRequest
0 голосов
/ 24 июня 2019

Я создал MLModel с помощью конструктора моделей ml.net, и он работает с консольным приложением «потребление» и жестко закодированными значениями для ввода. Я хотел перейти к следующему шагу и кормить значения с помощью веб-API. Я использую модифицированную версию их учебного примера по использованию mlmodel в веб-API. Когда я использую почтальон с webapi, я получаю следующую ошибку:

System.InvalidOperationException: 'Не удалось применить карту к типу' Single 'к столбцу' PG ', поскольку он имеет тип' String ''

mlmodel успешно строится из компоновщика моделей, а код по умолчанию генерируется из компоновщика моделей. Запуск консольного приложения с жестко закодированными значениями в модели работает.

Вот соответствующий код для ввода модели

// ********************************************* ******************************************** // * * // * Это автоматически сгенерированный файл с помощью инструмента командной строки Microsoft ML.NET. * // * * // ************************************************ *****************************************

using Microsoft.ML.Data;

namespace JobClassMLModelML.Model.DataModels
 {
    public class ModelInput
    {
        [ColumnName("EducationLevel"), LoadColumn(0)]
        public float EducationLevel { get; set; }


        [ColumnName("Experience"), LoadColumn(1)]
        public float Experience { get; set; }


        [ColumnName("OrgImpact"), LoadColumn(2)]
        public float OrgImpact { get; set; }


        [ColumnName("ProblemSolving"), LoadColumn(3)]
        public float ProblemSolving { get; set; }


        [ColumnName("Supervision"), LoadColumn(4)]
        public float Supervision { get; set; }


        [ColumnName("ContactLevel"), LoadColumn(5)]
        public float ContactLevel { get; set; }


        [ColumnName("FinancialBudget"), LoadColumn(6)]
        public float FinancialBudget { get; set; }


        [ColumnName("PG"), LoadColumn(7)]
        public string PG { get; set; }


    }
}

А вот и для выхода модели

// ********************************************* ******************************************** // * * // * Это автоматически сгенерированный файл с помощью инструмента командной строки Microsoft ML.NET. * // * * // ************************************************ *****************************************

using System;
using Microsoft.ML.Data;

namespace JobClassMLModelML.Model.DataModels
{
    public class ModelOutput
    {
        // ColumnName attribute is used to change the column name from
        // its default value, which is the name of the field.
        [ColumnName("PredictedLabel")]
        public String Prediction { get; set; }
        public float[] Score { get; set; }
    }
}

Я клонировал классы modelinput и modeloutput в эквивалентных классах webapi для jobclassdata и jobclassprediction соответственно

Консольное приложение, которое работает:

using System;
using Microsoft.ML;
using JobClassMLModelML;
using JobClassMLModelML.Model.DataModels;

namespace ConsumeApp
{
    class Program
    {
        static void Main(string[] args)
        { // Load the model
            MLContext mlContext = new MLContext();
            ITransformer mlModel = mlContext.Model.Load("MLModel.zip", out 
var modelInputSchema);
            var predEngine = 
mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel);

            // Use the code below to add input data
            var input = new ModelInput();
            // input.

            input.ContactLevel = 5;
            input.EducationLevel = 5;
            input.Experience = 5;
            input.FinancialBudget = 5;
            input.OrgImpact = 5;
            input.ProblemSolving = 5;
            input.Supervision =5;
            //input.PG = "PG01";

            // Try model on sample data
            ModelOutput result = predEngine.Predict(input);
            Console.WriteLine($"Predicted value: {result.Prediction} ");

        }
    }
}

Вот код для контроллера прогнозирования

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.ML;
using JobClassMLModelWebAPI.DataModels;

namespace JobClassMLModelWebAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class PredictController : ControllerBase
    {

        private readonly PredictionEnginePool<JobClassData, 
JobClassPrediction> _predictionEnginePool;

        public PredictController(PredictionEnginePool<JobClassData, 
JobClassPrediction> predictionEnginePool)
        {
            _predictionEnginePool = predictionEnginePool;
        }

        [HttpGet]
        public JobClassData Get(JobClassData jobClassData)
        {
            return new JobClassData
            {
                // insert test data here
            };
        }

        [HttpPost]
        public ActionResult<string> Post([FromBody] JobClassData input)
        {
            if (!ModelState.IsValid)
             {
                return BadRequest();
            }

            JobClassPrediction prediction = 
_predictionEnginePool.Predict(input);

            string PredictedJobGrade = prediction.Prediction;
            return Ok(PredictedJobGrade);
         }    
    }  
}

Здесь размещен код тела json

{
    "educationLevel": 3,
    "experience": 3,
    "orgImpact": 3,
    "problemSolving": 3,
    "supervision": 3,
    "contactLevel": 4,
    "financialBudget": 4,
    "pg" : "PG01"
}

Ожидаемый результат будет прогнозируемой выплатой, такой как PG03. Вместо этого ошибка

System.InvalidOperationException: 'Не удалось применить карту к типу' Single 'к столбцу' PG ', поскольку он имеет тип' String ''

на линии

            JobClassPrediction prediction = 
_predictionEnginePool.Predict(input);

без ошибки компиляции и с работающим консольным приложением - это формат ввода json?

Спасибо

...