Implante um modelo de análise de dados em um aplicativo do Windows com a API do Windows ML
Na parte anterior deste tutorial, você aprendeu a criar e exportar um modelo no formato ONNX. Agora, vamos mostrar como inserir o modelo exportado em um aplicativo do Windows e executá-lo localmente em um dispositivo chamando as APIs do Windows ML.
No final desta atividade, você terá um aplicativo de análise de dados.
Sobre o aplicativo de amostra
Nesta etapa do tutorial, você criará um aplicativo que analisa dados tabulares de Íris. Nesse aplicativo, é possível adicionar o arquivo Excel com as informações de entrada necessárias ou inserir manualmente os parâmetros de entrada: o comprimento e a largura em centímetros da sépala e da pétala da Íris. Esses recursos serão processados por um modelo ONNX de rede neural armazenado localmente, que você já criou e treinou na parte anterior. Com base na saída do modelo, o aplicativo exibirá a espécie correta de Íris.
Aqui, percorreremos esse processo com você.
Observação
Se você optar por usar o exemplo de código predefinido, poderá clonar o arquivo da solução. Clone o repositório, navegue até este exemplo e abra o arquivo Iris Data Analysis.csproj
com o Visual Studio. Vá diretamente para a parte Iniciar o aplicativo desta página para vê-lo em uso.
A seguir, vamos descrever como criar o aplicativo e adicionar código do Windows ML a ele.
Criar um aplicativo de área de trabalho do Windows ML (C#)
Para criar um aplicativo do Windows ML funcional, você precisará fazer o seguinte:
- Carregar um modelo de machine learning.
- Associar as entradas e as saídas do modelo.
- Avaliar o modelo e exibir os resultados significativos.
Também é preciso criar uma IU básica para proporcionar uma experiência melhor ao usuário.
Abrir um novo projeto no Visual Studio
- Vamos começar. Abra o Visual Studio e escolha
Create a new project
.
- Na barra de pesquisa, escolha
C#
como linguagem,Windows
como plataforma de destino eDektop
como tipo de projeto. Selecione a opçãoNUnit Test Project (.NET Core)
como tipo de projeto e clique emnext
para abrir a janela de configuração do projeto.
- Na janela de configuração, faça o seguinte:
- Nomeie o projeto. O nome será Iris Data Analysis.
- Escolha o local do projeto.
- Se você está usando o VS2019, verifique se
Create directory for solution
está marcado. - Se estiver usando o VS2017, verifique se a opção
Place solution and project in the same directory
está desmarcada.
Pressione create
para criar o projeto. A janela de versão de destino mínima pode aparecer. Verifique se a versão mínima está definida como Windows 10, versão 1809 (10.0; build 17763) ou posterior.
- Depois que o projeto for criado, navegue até a pasta do projeto, abra a pasta de ativos
[….\DataClassifier\Assets]
e copie o arquivoNetwork.onnx
para esse local.
Explorar a solução do projeto
Vamos explorar sua solução de projeto.
O Visual Studio criou automaticamente vários arquivos cs-code dentro do Gerenciador de Soluções. O MainPage.xaml
contém o código XAML para sua GUI e o MainPage.xaml.cs
contém o código do aplicativo. Se você já criou um aplicativo UWP, esses arquivos devem ser muito familiares.
O arquivo Network.onnx
foi adicionado à pasta de ativos, mas é preciso incluí-lo neste projeto.
- Clique com o botão direito do mouse na pasta "Assets" no Gerenciador de Soluções e selecione
Add > Existing Item
. - Navegue até a pasta "Assets" em
Iris Data Analysis [….\Iris Data Analysis \Assets]
, localize oNetwork.onnx model
que você copiou e clique emAdd
. - Para garantir que o modelo seja compilado com o seu aplicativo, clique com o botão direito do mouse no arquivo
Network.onnx
e selecioneProperties
. Defina oBuild Action
paraContent
.
Também será necessário criar um novo arquivo de classe cs-code para códigos extra de machine learning, que incluem classes e métodos que chamarão as APIs do Windows ML.
- Clique com o botão direito do mouse no nome da solução no Visual Studio e escolha
add
enew item
. Na janela aberta, selecioneClass
e dê um nome. Aqui, usamosIrisModel.cs
. Um novo arquivo de classe aparecerá no projeto.
.
Criar código do Machine Learning
Nesta etapa, você criará todas as classes e métodos que chamarão as APIs do Windows Machine Learning. Assim, será possível carregar, associar e avaliar um modelo de machine learning ONNX no projeto.
Clique duas vezes no arquivo
IrisModel.cs
.Substitua as instruções using pelo indicado a seguir para ter acesso a todas as APIs necessárias.
using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.AI.MachineLearning;
using Windows.Storage;
Inicializar classes de machine learning
Será necessário adicionar várias classes ao IrisModel.cs
para ajudar você a interagir com as APIs do Windows Machine Learning.
Para ter acesso ao modelo de machine learning treinado, use a classe LearningModel
. Essa classe faz parte do namespace Windows.AI.MachineLearning
e representa um modelo de machine learning treinado. Uma vez instanciado, o LearningModel
é o objeto inicial usado para interagir com as APIs do Windows ML.
Para avaliar o modelo de aprendizado, você terá que criar uma sessão de avaliação. Use a classe LearningModelSession
para fazer isso. Essa classe é usada para avaliar modelos de machine learning e associa o modelo a um dispositivo que, por sua vez, executa e avalia o modelo. Ao criar uma sessão com essa API, você também pode selecionar um dispositivo para executar o modelo (o padrão é a CPU).
Além disso, será necessário especificar os rótulos da saída dos modelos de machine learning. Você pode conectar esses rótulos à saída prevista do modelo mais tarde.
Observação
Para saber mais sobre as classes LearningModel
e LearningModelSession
, confira as documentações das classes LearningModel e LearningModelSession.
- Copie o código a seguir para o arquivo
IrisModel.cs
.
class IrisModel
{
private LearningModel _learning_model;
private LearningModelSession _session;
private String[] _labels = { "Iris-setosa", "Iris-versicolor", "Iris-virginica"};
Carregar o modelo
Em seguida, é preciso carregar o modelo de machine learning e criar uma sessão, e isso é feito com as classes que você acabou de definir. Para carregar o modelo, você usará diversos métodos estáticos da classe LearningModel
. Neste caso, LoadFromStorageFileAsync, que permite carregar um modelo ONNX de um ISorageFile
de modo assíncrono.
Observação
Para descobrir outras maneiras de carregar o modelo, confira a documentação "Carregar um modelo".
- Copie o código a seguir para o arquivo
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);
}
Definir o tensor de entrada do modelo
Agora, defina a entrada correta com base nos requisitos do modelo. O modelo de rede criado na parte anterior tem quatro valores de entrada. Cada valor de entrada representa os tamanhos possíveis de quatro recursos de íris: comprimento da sépala em centímetros, largura da sépala em centímetros, comprimento da pétala em centímetros e largura da pétala em centímetros. Com base nessa entrada, o modelo retornará a espécie de íris que melhor se ajusta a esses parâmetros. Você precisará limitar o tamanho dos valores de entrada aos valores lógicos válidos – neste tutorial, vamos usar o seguinte:
- Comprimento da sépala: de 1 cm a 100 cm
- Largura da sépala: de 1 cm a 8 cm
- Comprimento da pétala: de 0,5 cm a 10 cm
- Largura da pétala: de 0,1 cm a 5 cm
- Copie o código a seguir para o arquivo
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;
}
}
}
As APIs do Windows ML aceitam valores de entrada das quatro classes descritivas compatíveis com modelos ONNX: tensores, sequências, mapas e imagens. Nesse caso, o modelo requer um objeto tensor flutuante de 32 bits em uma forma de float32[batch_size,4]. Como o tamanho do lote é 1, a forma do tensor de entrada será [1x4].
Para criar uma entrada de tensor, use a classe TensorFloat.
A classe TensorFloat
faz parte do namespace Windows.AI.MachineLearning
e é usada para definir um objeto tensor flutuante de 32 bits – um tensor de valores de ponto flutuante de 32 bits. Essa classe contém vários métodos úteis para criar um tensor. Neste caso, você usará o método CreateFromArray para criar uma entrada de tensor no tamanho exato exigido pelo modelo. Adicione essa chamada ao método de avaliação.
Associar e avaliar o modelo
Agora que você definiu o tensor de entrada do modelo e instanciou o modelo treinado e a sessão, é hora de criar um método para associar e avaliar o modelo de machine learning treinado.
Esse método é a parte principal de um aplicativo de machine learning, pois inclui a tensorização dos valores de entrada e a associação da entrada do modelo. Você usará esse modelo posteriormente no código do aplicativo para avaliar seu modelo.
Para associar entrada e saída, use a classe LearningModelBinding
. Um modelo de machine learning tem recursos de entrada e saída, que transmitem informações para dentro e fora do modelo. Lembre-se de que os recursos necessários devem ser compatíveis com as APIs do Windows ML. A classe LearningModelBinding
é aplicada em um LearningModelSession
para associar valores aos recursos de entrada e saída nomeados.
A classe LearningModelBinding
tem vários métodos predefinidos que você pode usar para associar valores a esses recursos nomeados. Aqui, você usará o método Bind
para associar valores ao modelo.
Para avaliar o modelo e receber os resultados dele, chame os métodos de avaliação predefinidos de LearningModelSession
, neste caso, o método Evaluate
. Esse método oferece a funcionalidade de que você precisa, porque avalia o modelo de machine learning usando os valores de recursos fornecidos pela classe LearningModelBinding
.
Observação
Para saber mais sobre outros métodos de avaliação para executar o modelo, verifique quais métodos podem ser implementados em LearningModelSession examinando a documentação da Classe LearningModelSession.
Extrair e exibir os resultados
O modelo retorna os valores previstos no formato de tensor como uma saída de tensor flutuante. Agora, você precisa extrair a saída do modelo e exibir os resultados corretos. Para fazer isso, converta o formato de tensor em um vetor executando a função GetAsVectorView()
na saída com o predicado.
O modelo retorna três valores de probabilidade, e cada um representa uma espécie específica de íris. Você precisará retornar o rótulo com a maior probabilidade.
- Copie o código a seguir para o arquivo
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);
}
Você concluiu a parte de machine learning do código. Agora, pode integrar facilmente o modelo com um aplicativo do Windows. Na última parte deste tutorial, há uma GUI básica do Windows e um código de controle para testar o modelo usando os métodos que você já criou.
Criar a GUI do aplicativo
Para criar um código de aplicativo de GUI para o aplicativo, clique duas vezes no arquivo de código
MainPage.xaml
e abra um modelo predefinido para a GUI.Copie e cole o código abaixo em
MainPage.xaml
, abaixo da linha“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>
Criar o controle do aplicativo
O código de controle do aplicativo, MainPage.xaml.cs
, inclui o método main para executar o aplicativo e várias etapas para executar o modelo e executar a saída:
- Você criará uma instância de um novo objeto da classe
IrisModel
criada anteriormente neste tutorial. - Você chamará o método
Evaluate()
criado na parte anterior no modelo. Esse método será aplicado quatro vezes, uma em cada um dos parâmetros de entrada: comprimento da sépala, largura da sépala, comprimento da pétala e largura da pétala.
O aplicativo exibirá o resultado com base no algoritmo de previsão de machine learning.
- Para criar um código de controle de aplicativo, clique duas vezes no arquivo de código
MainPage.xaml.cs
e adicione o código a seguir.
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 o aplicativo
Agora está tudo pronto para iniciar o aplicativo e ver os resultados.
Habilite o modo de desenvolvedor e teste seu aplicativo com o Visual Studio. Verifique se os menus suspensos na barra de ferramentas superior estão definidos como Debug
. Altere a Plataforma de Solução para x64 para executar o projeto no computador local se seu dispositivo for de 64 bits ou x86 se for de 32 bits.
A GUI do aplicativo inclui quatro controles deslizantes para alterar a entrada dos parâmetros necessários. Qualquer alteração na entrada gera uma nova saída com base no algoritmo de previsão. A saída é exibida abaixo dos controles deslizantes de entrada.
Veja que, dada a entrada de comprimento da sépala = 40 mm, largura da sépala = 50, comprimento da pétala = 75 e largura da pétala = 15, a entrada gerada pelo aplicativo é a espécie {i>Iris versicolor
Resumo
Você acabou de criar seu primeiro aplicativo do Windows Machine Learning, da criação do modelo até a execução bem-sucedida.
Recursos adicionais
Para saber mais sobre os tópicos mencionados neste tutorial, visite os seguintes recursos:
- Ferramentas do Windows ML: conheça mais ferramentas como o Painel do Windows ML, o WinMLRunner e o gerador de código do Windows ML mlgen.
- Modelo de ONNX: saiba mais sobre o formato ONNX.
- Desempenho e memória do Windows ML: saiba mais sobre como gerenciar o desempenho do aplicativo com o Windows ML.
- Referência de API do Windows Machine Learning: saiba mais sobre três áreas das APIs do Windows ML.