Compartir a través de


Implementación del modelo de análisis de datos en una aplicación de Windows con las API de Windows ML

En la parte anterior de este tutorial, aprendió a compilar y exportar un modelo en formato ONNX. Ahora, le mostraremos cómo insertar el modelo exportado en una aplicación de Windows y ejecutarlo localmente en un dispositivo mediante una llamada a las API de Windows ML.

Cuando hayamos terminado, tendrá una aplicación de análisis de datos que funcionará.

Acerca de la aplicación de ejemplo

En este paso del tutorial, creará una aplicación que puede analizar datos tabulares de Iris. La aplicación le permitirá agregar el archivo de Excel con la información de entrada necesaria o escribir manualmente los parámetros de entrada: la longitud y el ancho del sépalo y pétalo de Iris en cm. Estas características se procesarán mediante un modelo ONNX de red neuronal almacenado localmente que creó y entrenó en la parte anterior. En función de la salida del modelo, la aplicación mostrará el tipo de Iris correcto.

Aquí, le acompañaremos en ese proceso.

Nota:

Si decide usar el ejemplo de código predefinido, puede clonar el archivo de solución. Clone el repositorio, navegue hasta el ejemplo y abra el archivo Iris Data Analysis.csproj con Visual Studio. Vaya a la parte Iniciar la aplicación de esta página para verlo en uso.

A continuación, le guiaremos en la creación de la aplicación y la adición de código Windows ML.

Creación de una aplicación de escritorio de Windows ML (C#)

Para crear una aplicación de Windows ML que funcione, deberá hacer lo siguiente:

  • Cargar un modelo de aprendizaje automático.
  • Enlazar las entradas y salidas del modelo.
  • Evaluar el modelo y mostrar resultados significativos.

También deberá crear una interfaz de usuario básica para proporcionar una mejor experiencia de usuario.

Apertura de un nuevo proyecto en Visual Studio

  1. Empecemos. Abra Visual Studio y elija Create a new project.

Create new Visual Studio project

  1. En la barra de búsqueda, elija C# como lenguaje, Windows como plataforma de destino y Dektop como tipo de proyecto. Seleccione NUnit Test Project (.NET Core) como tipo de proyecto y seleccione next para abrir una ventana de configuración para el proyecto.

Create new NUnit Test Project app

  1. En la ventana de configuración, haga lo siguiente:
  • Dé un nombre al proyecto. Aquí, lo llamamos Análisis de datos de Iris.
  • Elija la ubicación del proyecto.
  • Si usa VS2019, asegúrese de que la opción Create directory for solution esté activada.
  • Si usa VS2017, asegúrese de que la opción Place solution and project in the same directory esté desactivada.

Presione create para crear el proyecto. Puede que se abra la ventana de versión mínima de destino. Asegúrese de que la versión mínima esté establecida en Windows 10, versión 1809 (10.0; compilación 17763) o versión posterior.

  1. Después de crear el proyecto, vaya a la carpeta del proyecto, abra la carpeta assets [….\DataClassifier\Assets] y copie el archivo Network.onnx en esta ubicación.

Exploración de la solución de proyecto

Vamos a explorar la solución de proyecto.

Visual Studio creó automáticamente varios archivos de código CS dentro del Explorador de soluciones. MainPage.xaml contiene el código XAML de la GUI y MainPage.xaml.cs contiene el código de la aplicación. Si ha creado una aplicación para UWP antes, debería estar muy familiarizado con estos archivos.

Aunque hemos agregado el archivo Network.onnx a la carpeta assets, es necesario agregarlo correctamente a este proyecto.

  1. Haga clic con el botón derecho en la carpeta Assets en el Explorador de soluciones y seleccione Add > Existing Item.
  2. Vaya a la carpeta Assets dentro de Iris Data Analysis [….\Iris Data Analysis \Assets], busque el Network.onnx model que copió anteriormente y seleccione Add.
  3. Para asegurarse de que su modelo se genera cuando compile la aplicación, haga clic con el botón derecho en el archivo Network.onnx y seleccione Properties. Establecer Build Action en Content.

También tendrá que crear un nuevo archivo de clase cs-code para dar cabida a algún código de aprendizaje automático adicional, que incluye clases y métodos que llamarán a las API de Windows ML.

  1. Haga clic con el botón derecho en el nombre en Visual Studio y elija add y new item. En la ventana abierta, seleccione Class y asígnele un nombre. En este caso, usaremos IrisModel.cs. Aparecerá un nuevo archivo de clase dentro del proyecto.

Add a new class file to your VS project.

Creación de un código de Machine Learning

En este paso, crearemos todas las clases y métodos que llamarán a las API de Windows Machine Learning. Esto le permitirá cargar, enlazar y evaluar un modelo de aprendizaje automático de ONNX en el proyecto.

  1. Haga doble clic en el archivo IrisModel.cs.

  2. Reemplace las instrucciones using por las siguientes para obtener acceso a todas las API que necesitará.

using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.AI.MachineLearning;
using Windows.Storage;

Inicialización de las clases de aprendizaje automático

Es necesario agregar varias clases a IrisModel.cs para ayudarle a interactuar con las API de Windows Machine Learning.

Para obtener acceso al modelo de aprendizaje automático entrenado, usaremos la clase LearningModel. Esta clase forma parte del espacio de nombres Windows.AI.MachineLearning y representa un modelo de aprendizaje automático entrenado. Una vez creada una instancia, LearningModel es el objeto principal que se usa para interactuar con las API de Windows ML.

Para evaluar el modelo de aprendizaje, tendrá que crear una sesión de evaluación. Para ello, use la clase LearningModelSession. Esta clase se usa para evaluar los modelos de aprendizaje automático y enlaza el modelo a un dispositivo que, a continuación, ejecuta y evalúa el modelo. Al crear una sesión con esta API, también puede seleccionar un dispositivo para ejecutar el modelo (el valor predeterminado es la CPU).

Además, deberá especificar las etiquetas de resultado para los modelos de aprendizaje automático. Puede conectar esas etiquetas al resultado predicho del modelo más adelante.

Nota:

Para obtener más información sobre las clases LearningModel y LearningModelSession, revise la documentación de la clase LearningModel y de la clase LearningModelSession.

  1. Copie el siguiente código al archivo IrisModel.cs.
class IrisModel
    {
        private LearningModel _learning_model;
        private LearningModelSession _session;
        private String[] _labels = { "Iris-setosa", "Iris-versicolor", "Iris-virginica"};

Carga del modelo

A continuación, deberá cargar el modelo de aprendizaje automático y crear una sesión. Podrá hacerlo con las clases que acaba de definir. Para cargar el modelo, usará varios métodos estáticos de la clase LearningModel; en nuestro caso, usaremos LoadFromStorageFileAsync, que le permite cargar un modelo ONNX a partir de un ISorageFile de forma asincrónica.

Nota:

Para más información sobre otras formas de cargar el modelo, consulte la documentación de carga de un modelo.

  1. Copie el siguiente código al archivo IrisModel.cs.
public async Task Initialize()
{
    // Load and create the model and session
    var modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets//Network.onnx"));
    _learning_model = await LearningModel.LoadFromStorageFileAsync(modelFile);
    _session = new LearningModelSession(_learning_model);
}

Definición del tensor de entrada del modelo

Ahora, definiremos la entrada correcta en función de los requisitos del modelo. El modelo de red que creó en la parte anterior tiene cuatro valores de entrada. Cada valor de entrada representa los tamaños posibles de cuatro características de Iris: longitud del sépalo en cm, el ancho del sépalo en cm, la longitud del pétalo en cm y el ancho del pétalo en cm. En función de esta entrada, el modelo devolverá el tipo de Iris que mejor se adapte a esos parámetros. Tendrá que limitar el tamaño de los valores de entrada a los valores lógicos válidos; para este tutorial, usaremos los siguientes:

  • longitud del sépalo: de 1 cm a 100 cm
  • ancho del sépalo: de 1 cm a 8 cm
  • longitud del pétalo: de 0,5 cm a 10 cm
  • ancho del pétalo: de 0,1 cm a 5 cm
  1. Copie el siguiente código al archivo IrisModel.cs.
private float _sepal_length = 1.0f;
public float Sepal_Length
{
    get
    {
        return _sepal_length;
    }
    set
    {
        // validate range [1,10]
        if (value >= 1 && value <= 10)
        {
            _sepal_length = value;
        }
    }
}

private float _sepal_width = 1.0f;
public float Sepal_Width
{
    get
    {
        return _sepal_width;
    }
    set
    {
        // validate range [1, 8]
        if (value >= 1 && value <= 8)
        {
            _sepal_width = value;
        }
    }
}

private float _petal_length = 0.5f;
public float Petal_Length
{
    get
    {
        return _petal_length;
    }
    set
    {
        // validate range [0.5, 10]
        if (value >= 0.5 && value <= 10)
        {
            _petal_length = value;
        }
    }
}

private float _petal_width = 0.1f;
public float Petal_Width
{
    get
    {
        return _petal_width;
    }
    set
    {
        // validate range [0.1, 5]
        if (value >= 0.1 && value <= 5)
        {
            _petal_width = value;
        }
    }
}

Las API de Windows ML aceptan valores de entrada de las cuatro clases descriptivas admitidas por los modelos de ONNX: tensores, secuencias, mapas e imágenes. En este caso, el modelo requiere un objeto float de tensor de 32 bits con el formato float32[batch_size,4]. Puesto que el tamaño del lote es 1, la forma del tensor de entrada es [1x4].

Para crear una entrada de tensor, usará la clase TensorFloat.

La clase TensorFloat forma parte del espacio de nombres Windows.AI.MachineLearning y se usa para definir un objeto float de tensor de 32 bits; es decir, un tensor de valores de punto flotante de 32 bits. Esta clase contiene varios métodos útiles para crear un tensor. En este caso, usará el método CreateFromArray para crear una entrada tensor con el tamaño exacto que requiere el modelo. Agregaremos esa llamada dentro del método de evaluación.

Enlace y evaluación del modelo

Ahora que ha definido el tensor de entrada del modelo y ha creado una instancia del modelo entrenado y la sesión, es el momento de crear un método para enlazar y evaluar el modelo de aprendizaje automático entrenado.

Este método es la parte más importante de una aplicación de aprendizaje automático. Incluye la tensorización de los valores de entrada y el enlace de la entrada del modelo. Usará este modelo más adelante en el código de la aplicación para evaluar el modelo.

Para enlazar la entrada y la salida, use la clase LearningModelBinding. Un modelo de aprendizaje automático tiene características de entrada y salida, que pasan información dentro y fuera del modelo. Tenga en cuenta que las características necesarias deben ser compatibles con las API de Windows ML. La clase LearningModelBinding se aplica a una clase LearningModelSession para enlazar valores a características de entrada y salida con nombre.

La clase LearningModelBinding tiene varios métodos predefinidos que puede usar para enlazar valores a las características con nombre. Aquí, usará el método Bind para enlazar valores al modelo.

Para evaluar el modelo y recibir resultados de él, llame a los métodos de evaluación predefinidos pertinentes desde LearningModelSession, en su caso, el método Evaluate. Este método proporcionará la funcionalidad que necesita, evaluando el modelo de aprendizaje automático mediante los valores de característica proporcionados por la clase LearningModelBinding.

Nota:

Para información sobre otros métodos de evaluación para ejecutar el modelo, compruebe qué métodos se pueden implementar en LearningModelSession revisando la documentación de la clase LearningModelSession.

Extracción y visualización de los resultados

El modelo devuelve los valores predichos en formato tensor como un resultado float de Tensor. Ahora deberá extraer la salida del modelo y mostrar los resultados correctos. Para ello, convertirá el formato de tensor en un vector mediante la ejecución de la función GetAsVectorView() en el resultado predicho.

El modelo devuelve tres valores de probabilidad, cada uno de los cuales representa un tipo de Iris específico. Deberá devolver la etiqueta con la probabilidad más alta.

  1. Copie el siguiente código al archivo IrisModel.cs.
internal String Evaluate()
{
    // input tensor shape is [1x4]
    long[] shape = new long[2];
    shape[0] = 1;
    shape[1] = 4;

    // set up the input tensor
    float[] input_data = new float[4];
    input_data[0] = _sepal_length;
    input_data[1] = _sepal_width;
    input_data[2] = _petal_length;
    input_data[3] = _petal_width;
    TensorFloat tensor_float = TensorFloat.CreateFromArray(shape, input_data);

    // bind the tensor to "input"
    var binding = new LearningModelBinding(_session);
    binding.Bind("input", tensor_float);

    // evaluate
    var results = _session.Evaluate(binding, "");

    // get the results
    TensorFloat prediction = (TensorFloat)results.Outputs.First().Value;
    var prediction_data = prediction.GetAsVectorView();

    // find the highest predicted value
    int max_index = 0;
    float max_value = 0;
    for (int i = 0; i < prediction_data.Count; i++)
    {
        var val = prediction_data.ElementAt(i);
        if (val > max_value)
        {
            max_value = val;
            max_index = i;
        }
    }

    // return the label corresponding to the highest predicted value
    return _labels.ElementAt(max_index);
}

Ahora ha completado la parte de aprendizaje automático del código. Ahora, puede integrar fácilmente el modelo con una aplicación de Windows. En la última parte de este tutorial, proporcionamos una GUI de Windows básica y código de control para probar el modelo mediante los métodos que ya había creado.

Creación de la GUI de la aplicación

  1. Para crear un código de aplicación de GUI para la aplicación, haga doble clic en el archivo de código MainPage.xaml y abra una plantilla predefinida para la GUI.

  2. Copie y pegue el código siguiente en MainPage.xaml, debajo de la línea “Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" " Height="939">.

    <Grid Margin="30,30,30,30">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TextBlock x:Name="title" HorizontalAlignment="Left" Text="Data Analysis App - Windows ML" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="32" TextDecorations="Underline" FontWeight="Bold"/>
        <TextBlock x:Name="subtitle" HorizontalAlignment="Left" Text="Provide the input :" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="20" Grid.Row="1" FontWeight="Bold"/>
        <Grid Grid.Row="2">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock x:Name="sepal_length" Text="sepal length in mm [range of 10 - 100]:" VerticalAlignment="Center"/>
            <TextBlock x:Name="sepal_width" Text="sepal width in mm [range of 10 - 80]:" VerticalAlignment="Center" Grid.Row="1"/>
            <TextBlock x:Name="petal_length" Text="petal length in mm [range of 5 - 100]:" VerticalAlignment="Center" Grid.Row="2"/>
            <TextBlock x:Name="petal_width" Text="sepal width in mm [range of 1 - 50]:" VerticalAlignment="Center" Grid.Row="3"/>

            <Slider x:Name="sepal_length_input" Minimum="10" Maximum="100" Orientation="Horizontal" Grid.Column="1" Width="200" ValueChanged="sepal_length_input_ValueChanged"/>
            <Slider x:Name="sepal_width_input" Minimum="10" Maximum="80" Orientation="Horizontal" Grid.Row="1" Grid.Column="1" Width="200" ValueChanged="sepal_width_input_ValueChanged"/>
            <Slider x:Name="petal_length_input" Minimum="5" Maximum="100" Orientation="Horizontal" Grid.Row="2" Grid.Column="1" Width="200" ValueChanged="petal_length_input_ValueChanged"/>
            <Slider x:Name="petal_width_input" Minimum="1" Maximum="50" Orientation="Horizontal" Grid.Row="3" Grid.Column="1" Width="200" ValueChanged="petal_width_input_ValueChanged"/>
        </Grid>
        <TextBlock x:Name="output" Text="Output:" FontSize="20" FontWeight="Bold" Grid.Row="3"/>
        <Grid Grid.Row="4">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock x:Name="output_subtitle" Text="Based on the information provided, the Iris type is:"/>
            <TextBlock x:Name="model_output" Text="Model output" FontStyle="Italic"  Grid.Column="1" Margin="10,0,0,0"/>
        </Grid>
    </Grid>

Creación del control de la aplicación

El código de control de la aplicación, MainPage.xaml.cs, incluye el método principal para ejecutar la aplicación y varios pasos para ejecutar el modelo y el resultado:

  1. Creará una instancia de un nuevo objeto de la clase IrisModel que creó anteriormente en este tutorial.
  2. Llamará al método Evaluate() que creó en la parte anterior del modelo. Este método se aplicará cuatro veces, una vez en cada uno de los parámetros de entrada: longitud del sépalo, ancho del sépalo, longitud del pétalo y ancho del pétalo.

La aplicación mostrará el resultado en función del algoritmo de predicción de aprendizaje automático.

  1. Para crear un código de control de aplicación, haga doble clic en el archivo de código MainPage.xaml.cs y agregue el código siguiente.
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace Iris_Data_Analysis
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private IrisModel _iris_model;

        public MainPage()
        {
            this.InitializeComponent();
            _iris_model = new IrisModel();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            _iris_model.Initialize();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
        }

        private void sepal_length_input_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (_iris_model != null)
            {
                _iris_model.Sepal_Length = (float)sepal_length_input.Value / 10.0f;
                model_output.Text = _iris_model.Evaluate();
            }
        }

        private void sepal_width_input_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (_iris_model != null)
            {
                _iris_model.Sepal_Width = (float)sepal_width_input.Value / 10.0f;
                model_output.Text = _iris_model.Evaluate();
            }
        }

        private void petal_length_input_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (_iris_model != null)
            {
                _iris_model.Petal_Length = (float)petal_length_input.Value / 10.0f;
                model_output.Text = _iris_model.Evaluate();
            }
        }

        private void petal_width_input_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (_iris_model != null)
            {
                _iris_model.Petal_Width = (float)petal_width_input.Value / 10.0f;
                model_output.Text = _iris_model.Evaluate();
            }
        }
    }
}

Iniciar la aplicación

Ahora está listo para iniciar la aplicación y ver los resultados.

Habilite el modo de desarrollador y pruebe la aplicación desde Visual Studio. Asegúrese de que los menús desplegables de la barra de herramientas superior están establecidos en Debug. Cambie la plataforma de soluciones a x64 para ejecutar el proyecto en la máquina local si el dispositivo es de 64 bits o a x86 si el dispositivo es de 32 bits.

La GUI de la aplicación incluye cuatro controles deslizantes para cambiar la entrada de los parámetros necesarios. Cualquier cambio en la entrada generará un nuevo resultado basado en el algoritmo de predicción. El resultado se muestra debajo de los controles deslizantes de entrada.

Puede ver que dada la entrada de longitud de sépalo = 40 mm, ancho de sépalo = 50, longitud del pétalo = 75 y ancho de pétalo = 15, la aplicación generó una entrada de tipo Iris versicolor.

Successful classification in your app

Resumen

Acaba de crear la primera aplicación de Windows Machine Learning, desde la creación del modelo hasta la ejecución correcta.

Recursos adicionales

Para más información sobre los temas mencionados en este tutorial, visite estos recursos: