Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Observação
Para maior funcionalidade, o PyTorch também pode ser usado com DirectML no Windows.
Na parte anterior deste tutorial, você aprendeu como criar e exportar um modelo no formato ONNX. Agora, mostraremos como incorporar seu modelo exportado em um aplicativo do Windows e executá-lo localmente em um dispositivo chamando APIs do WinML.
Quando terminarmos, você terá um aplicativo de classificação de imagens funcionando.
Sobre o aplicativo de exemplo
Nesta etapa do tutorial, você criará um aplicativo que pode classificar imagens usando seu modelo de ML. Sua interface do usuário básica permite que você selecione uma imagem do seu dispositivo local e usa o modelo ONNX de classificação que você criou e treinou na parte anterior para classificá-la. As tags retornadas pelo modelo são exibidas ao lado da imagem.
Aqui, vamos orientá-lo através desse processo.
Observação
Se você optar por usar o exemplo de código predefinido, poderá clonar o arquivo de solução. Clone o repositório, navegue até este exemplo e abra o classifierPyTorch.sln arquivo com o Visual Studio. Pule para a parte Iniciar a Aplicação desta página para vê-lo em uso.
Abaixo, vamos orientá-lo sobre como criar seu aplicativo e adicionar o código de ML do Windows.
Criar um Windows ML UWP (C#)
Para criar um aplicativo de ML do Windows em funcionamento, você precisará fazer o seguinte:
- Carregue um modelo de aprendizado de máquina.
- Carregue uma imagem no formato necessário.
- Vincule as entradas e saídas do modelo.
- Avalie o modelo e exiba resultados significativos.
Você também precisará criar uma interface do usuário básica, pois é difícil criar um aplicativo baseado em imagem satisfatório na linha de comando.
Abrir um novo projeto no Visual Studio
- Vamos começar. Abra o Visual Studio e escolha criar um novo projeto.
- Na barra de pesquisa, escreva
UWPe, em seguida, selecioneBlank APP (Universal Windows). Isso abre um projeto C# para um aplicativo da Plataforma Universal do Windows (UWP) de página única com controles ou layout predefinidos. Selecionenextpara abrir uma janela de configuração para o projeto.
- Na janela de configuração, faça o seguinte:
- Atribua um nome ao seu projeto. Aqui, chamamos-lhe classificadorPyTorch.
- Escolha a localização do seu projeto.
- Se você estiver usando o VS2019, verifique se
Create directory for solutionestá marcado. - Se você estiver usando o VS2017, verifique se
Place solution and project in the same directoryestá desmarcado.
Pressione create para criar seu projeto. A janela da versão de destino mínima pode aparecer. Certifique-se de que a sua versão mínima está definida para Windows 10, versão 1809 (10.0; build 17763) ou superior.
- Depois que o projeto for criado, navegue até a pasta do projeto, abra a pasta
[….\classifierPyTorch \Assets]e copie oImageClassifier.onnxarquivo para esse local.
Explore a solução do projeto
Vamos explorar a solução do seu projeto.
O Visual Studio criou automaticamente vários arquivos de código cs, dentro do Gerenciador de Soluções.
MainPage.xaml contém o código XAML para sua GUI e MainPage.xaml.cs contém o código do aplicativo, também conhecido como code-behind. Se você já criou um aplicativo UWP antes, esses arquivos devem ser muito familiares para você.
Criar a GUI do aplicativo
Primeiro, vamos criar uma GUI simples para seu aplicativo.
Faça duplo clique no ficheiro
MainPage.xamlde código. Em seu aplicativo em branco, o modelo XAML para a GUI do seu aplicativo está vazio, portanto, precisaremos adicionar alguns recursos da interface do usuário.Adicione o código abaixo ao
MainPage.xaml, substituindo as<Grid>tags e</Grid>.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Margin="1,0,-1,0">
<TextBlock x:Name="Menu"
FontWeight="Bold"
TextWrapping="Wrap"
Margin="10,0,0,0"
Text="Image Classification"/>
<TextBlock Name="space" />
<Button Name="recognizeButton"
Content="Pick Image"
Click="OpenFileButton_Click"
Width="110"
Height="40"
IsEnabled="True"
HorizontalAlignment="Left"/>
<TextBlock Name="space3" />
<Button Name="Output"
Content="Result is:"
Width="110"
Height="40"
IsEnabled="True"
HorizontalAlignment="Left"
VerticalAlignment="Top">
</Button>
<!--Display the Result-->
<TextBlock Name="displayOutput"
FontWeight="Bold"
TextWrapping="Wrap"
Margin="25,0,0,0"
Text="" Width="1471" />
<TextBlock Name="space2" />
<!--Image preview -->
<Image Name="UIPreviewImage" Stretch="Uniform" MaxWidth="300" MaxHeight="300"/>
</StackPanel>
</Grid>
Adicione o modelo ao projeto usando o Gerador de Código de ML do Windows (mlgen)
O Gerador de Código do Windows Machine Learning, ou mlgen, é uma extensão do Visual Studio para ajudá-lo a começar a usar APIs WinML em aplicativos UWP. Ele gera código de modelo quando você adiciona um arquivo ONNX treinado ao projeto UWP.
O gerador de código mlgen do Windows Machine Learning cria uma interface (para C#, C++/WinRT e C++/CX) com classes wrapper que chamam a API do Windows ML para você. Isso permite que você carregue, vincule e avalie facilmente um modelo em seu projeto. Vamos usá-lo neste tutorial para lidar com muitas dessas funções para nós.
O gerador de código está disponível para o Visual Studio 2017 e posterior. Recomendamos o uso do Visual Studio. Por favor, esteja ciente de que no Windows 10, versão 1903 e posterior, mlgen não está mais incluído no SDK do Windows 10, então você deve baixar e instalar a extensão. Se você tem acompanhado este tutorial desde a introdução, você já terá lidado com isso, mas se não, você deve baixar para VS 2019 ou VS 2017.
Observação
Para saber mais sobre mlgen, consulte a documentação mlgen
Se ainda não o fez, instale o mlgen.
Clique com o botão direito do mouse na pasta
Assetsno Gerenciador de Soluções no Visual Studio e selecioneAdd > Existing Item.Navegue até a pasta assets dentro
classifierPyTorch [….\classifierPyTorch \Assets], encontre o modelo ONNX que você já copiou lá e selecioneadd.Depois de adicionar um modelo ONNX à pasta assets no gerenciador de soluções no VS, o projeto agora deve ter dois novos arquivos:
-
ImageClassifier.onnx- este é o seu modelo em formato ONNX. -
ImageClassifier.cs– arquivo de código WinML gerado automaticamente.
- Para se certificar de que o modelo é construído ao compilar a nossa aplicação, selecione o ficheiro
ImageClassifier.onnxe escolhaProperties. ParaBuild Action, selecioneContent.
Código do arquivo ONNX
Agora, vamos explorar um código recém-gerado no ImageClassifier.cs arquivo.
O código gerado inclui três classes:
-
ImageClassifierModel: Esta classe inclui dois métodos para instanciação de modelo e avaliação de modelo. Isso nos ajudará a criar a representação do modelo de aprendizado de máquina, criar uma sessão no dispositivo padrão do sistema, vincular as entradas e saídas específicas ao modelo e avaliar o modelo de forma assíncrona. -
ImageClassifierInput: Esta classe inicializa os tipos de entrada esperados pelo modelo. A entrada do modelo depende dos requisitos do modelo para os dados de entrada. -
ImageClassifierOutput: Esta classe inicializa os tipos que o modelo irá produzir. A saída do modelo depende de como ela é definida pelo modelo.
Neste tutorial, não queremos lidar com tensorização. Faremos uma pequena alteração na ImageClassifierInput classe, para alterar o tipo de dados de entrada e facilitar a nossa vida.
- Faça as seguintes alterações no
ImageClassifier.csarquivo:
Altere a input variável de a TensorFloat para um ImageFeatureValue.
public sealed class ImageClassifierInput
{
public ImageFeatureValue input; // shape(-1,3,32,32)
}
Carregue o modelo
Dê um duplo clique no arquivo
MainPage.xaml.cspara abrir o código subjacente do aplicativo.Substitua as instruções "usando" seguindo para obter acesso a todas as APIs necessárias:
// Specify all the using statements which give us the access to all the APIs that we'll need
using System;
using System.Threading.Tasks;
using Windows.AI.MachineLearning;
using Windows.Graphics.Imaging;
using Windows.Media;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
- Adicione as seguintes declarações de variáveis dentro da sua
MainPageclasse, acima dapublic MainPage()função.
// All the required fields declaration
private ImageClassifierModel modelGen;
private ImageClassifierInput image = new ImageClassifierInput();
private ImageClassifierOutput results;
private StorageFile selectedStorageFile;
private string label = "";
private float probability = 0;
private Helper helper = new Helper();
public enum Labels
{
plane,
car,
bird,
cat,
deer,
dog,
frog,
horse,
ship,
truck
}
Agora, você implementará o LoadModel método. O método irá acessar o modelo ONNX e armazená-lo na memória. Em seguida, você usará o CreateFromStreamAsync método para instanciar o modelo como um LearningModel objeto. A LearningModel classe representa um modelo de aprendizagem de máquina treinado. Uma vez instanciado, o LearningModel é o objeto inicial utilizado para interagir com o Windows ML.
Para carregar o modelo, você pode usar vários métodos estáticos na LearningModel classe. Nesse caso, você usará o CreateFromStreamAsync método.
O CreateFromStreamAsync método foi criado automaticamente com mlgen, então você não precisa implementar esse método. Você pode revisar este método clicando duas vezes no classifier.cs arquivo gerado pelo mlgen.
Observação
Para saber mais sobre a LearningModel classe, consulte a documentação da classe LearningModel. Para saber mais sobre formas adicionais de carregar o modelo, consulte a documentação Carregar um modelo
- Adicione uma chamada ao método
loadModelao construtor da classe principal.
// The main page to initialize and execute the model.
public MainPage()
{
this.InitializeComponent();
loadModel();
}
- Adicione a implementação do
loadModelmétodo, dentro dessaMainPageclasse.
private async Task loadModel()
{
// Get an access the ONNX model and save it in memory.
StorageFile modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/ImageClassifier.onnx"));
// Instantiate the model.
modelGen = await ImageClassifierModel.CreateFromStreamAsync(modelFile);
}
Carregue a imagem
- Precisamos definir um evento de clique para iniciar a sequência de quatro chamadas de método para a execução do modelo – conversão, vinculação e avaliação, extração de saída e exibição dos resultados. Adicione o seguinte método ao seu
MainPage.xaml.csarquivo de código dentro daMainPageclasse.
// Waiting for a click event to select a file
private async void OpenFileButton_Click(object sender, RoutedEventArgs e)
{
if (!await getImage())
{
return;
}
// After the click event happened and an input selected, begin the model execution.
// Bind the model input
await imageBind();
// Model evaluation
await evaluate();
// Extract the results
extractResult();
// Display the results
await displayResult();
}
- Agora, você implementará o
getImage()método. Este método irá selecionar um arquivo de imagem de entrada e salvá-lo na memória. Adicione o seguinte método ao seuMainPage.xaml.csarquivo de código dentro daMainPageclasse.
// A method to select an input image file
private async Task<bool> getImage()
{
try
{
// Trigger file picker to select an image file
FileOpenPicker fileOpenPicker = new FileOpenPicker();
fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
fileOpenPicker.FileTypeFilter.Add(".jpg");
fileOpenPicker.FileTypeFilter.Add(".png");
fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
selectedStorageFile = await fileOpenPicker.PickSingleFileAsync();
if (selectedStorageFile == null)
{
return false;
}
}
catch (Exception)
{
return false;
}
return true;
}
Em seguida, você implementará um método de imagem Bind() para obter a representação do arquivo no formato bitmap BGRA8. Mas primeiro, você criará uma classe auxiliar para redimensionar a imagem.
- Para criar um ficheiro auxiliar, clique com o botão direito do rato no nome da solução (
ClassifierPyTorch) e, em seguida, selecioneAdd a new item. Na janela aberta, selecioneClasse atribua-lhe um nome. Aqui, estamos chamando deHelper.
- Um novo arquivo de classe aparecerá em seu projeto. Abra esta classe e adicione o seguinte código:
using System;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Media;
namespace classifierPyTorch
{
public class Helper
{
private const int SIZE = 32;
VideoFrame cropped_vf = null;
public async Task<VideoFrame> CropAndDisplayInputImageAsync(VideoFrame inputVideoFrame)
{
bool useDX = inputVideoFrame.SoftwareBitmap == null;
BitmapBounds cropBounds = new BitmapBounds();
uint h = SIZE;
uint w = SIZE;
var frameHeight = useDX ? inputVideoFrame.Direct3DSurface.Description.Height : inputVideoFrame.SoftwareBitmap.PixelHeight;
var frameWidth = useDX ? inputVideoFrame.Direct3DSurface.Description.Width : inputVideoFrame.SoftwareBitmap.PixelWidth;
var requiredAR = ((float)SIZE / SIZE);
w = Math.Min((uint)(requiredAR * frameHeight), (uint)frameWidth);
h = Math.Min((uint)(frameWidth / requiredAR), (uint)frameHeight);
cropBounds.X = (uint)((frameWidth - w) / 2);
cropBounds.Y = 0;
cropBounds.Width = w;
cropBounds.Height = h;
cropped_vf = new VideoFrame(BitmapPixelFormat.Bgra8, SIZE, SIZE, BitmapAlphaMode.Ignore);
await inputVideoFrame.CopyToAsync(cropped_vf, cropBounds, null);
return cropped_vf;
}
}
}
Agora, vamos converter a imagem para o formato apropriado.
A ImageClassifierInput classe inicializa os tipos de entrada esperados pelo modelo. No nosso caso, configurámos o nosso código para esperar um ImageFeatureValue.
A ImageFeatureValue classe descreve as propriedades da imagem usada para passar para um modelo. Para criar um ImageFeatureValue, use o método CreateFromVideoFrame. Para obter detalhes mais específicos sobre por que esse é o caso e como essas classes e métodos funcionam, consulte a documentação da classe ImageFeatureValue
Observação
Neste tutorial, usamos a ImageFeatureValue classe em vez de um tensor. Se o Window ML não suportar o formato de cores do seu modelo, esta não será uma opção. Para obter um exemplo de como trabalhar com conversões de imagem e tensorização, consulte o Exemplo de tensorização personalizada.
- Adicione a implementação do método
convert()ao seu ficheiro de códigoMainPage.xaml.csdentro da classe MainPage. O método convert nos dará uma representação do arquivo de entrada em um formato BGRA8.
// A method to convert and bide the input image.
private async Task imageBind ()
{
UIPreviewImage.Source = null;
try
{
SoftwareBitmap softwareBitmap;
using (IRandomAccessStream stream = await selectedStorageFile.OpenAsync(FileAccessMode.Read))
{
// Create the decoder from the stream
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
// Get the SoftwareBitmap representation of the file in BGRA8 format
softwareBitmap = await decoder.GetSoftwareBitmapAsync();
softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
}
// Display the image
SoftwareBitmapSource imageSource = new SoftwareBitmapSource();
await imageSource.SetBitmapAsync(softwareBitmap);
UIPreviewImage.Source = imageSource;
// Encapsulate the image within a VideoFrame to be bound and evaluated
VideoFrame inputImage = VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);
// Resize the image size to 32x32
inputImage=await helper.CropAndDisplayInputImageAsync(inputImage);
// Bind the model input with image
ImageFeatureValue imageTensor = ImageFeatureValue.CreateFromVideoFrame(inputImage);
image.modelInput = imageTensor;
// Encapsulate the image within a VideoFrame to be bound and evaluated
VideoFrame inputImage = VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);
// bind the input image
ImageFeatureValue imageTensor = ImageFeatureValue.CreateFromVideoFrame(inputImage);
image.modelInput = imageTensor;
}
catch (Exception e)
{
}
}
Vincular e avaliar o modelo
Em seguida, você criará uma sessão com base no modelo, vinculará a entrada e a saída da sessão e avaliará o modelo.
Crie uma sessão para vincular o modelo:
Para criar uma sessão, use a LearningModelSession classe. Essa classe é usada para avaliar modelos de aprendizado de máquina e vincula o modelo a um dispositivo que, em seguida, executa e avalia o modelo. Você pode selecionar um dispositivo ao criar uma sessão para executar seu modelo em um dispositivo específico da sua máquina. O dispositivo padrão é a CPU.
Observação
Para saber mais sobre como escolher um dispositivo, consulte a documentação Criar uma sessão .
Vincular entradas e saídas do modelo:
Para vincular entrada e saída, use a LearningModelBinding classe. Um modelo de aprendizado de máquina tem recursos de entrada e saída, que passam informações para dentro e para fora do modelo. Lembre-se de que os recursos necessários devem ser suportados pelas APIs do Window ML. A LearningModelBinding classe é aplicada em um LearningModelSession para vincular valores a recursos de entrada e saída nomeados.
A implementação da ligação é gerada automaticamente pelo mlgen, para que você não precise cuidar dela. A associação é implementada chamando os métodos predefinidos da LearningModelBinding classe. No nosso caso, ele usa o Bind método para vincular um valor ao tipo de recurso nomeado.
Avalie o modelo:
Depois de criar uma sessão para vincular o modelo e os valores limitados às entradas e saídas de um modelo, você pode avaliar as entradas do modelo e obter suas previsões. Para executar a execução do modelo, você deve chamar qualquer um dos métodos de avaliação predefinidos no LearningModelSession. No nosso caso, usaremos o EvaluateAsync método.
Semelhante ao CreateFromStreamAsync, o EvaluateAsync método também foi gerado automaticamente pelo WinML Code Generator, então você não precisa implementar esse método. Você pode revisar esse método no ImageClassifier.cs arquivo.
O EvaluateAsync método avaliará de forma assíncrona o modelo de aprendizado de máquina usando os valores de recurso já vinculados em associações. Ele criará uma sessão com LearningModelSession, vinculará a entrada e a saída com LearningModelBinding, executará a avaliação do modelo e obterá os recursos de saída do modelo usando a LearningModelEvaluationResult classe.
Observação
Para saber mais sobre outros métodos de avaliação para executar o modelo, verifique quais métodos podem ser implementados no LearningModelSession examinando a documentação da classe LearningModelSession.
- Adicione o seguinte método ao seu
MainPage.xaml.csarquivo de código dentro da classe MainPage para criar uma sessão, vincular e avaliar o modelo.
// A method to evaluate the model
private async Task evaluate()
{
results = await modelGen.EvaluateAsync(image);
}
Extrair e exibir os resultados
Agora você precisará extrair a saída do modelo e exibir o resultado certo, o que será feito implementando os extractResult métodos e displayResult . Você precisará encontrar a maior probabilidade de retornar o rótulo correto.
- Adicione o
extractResultmétodo ao seuMainPage.xaml.csarquivo de código dentro daMainPageclasse.
// A method to extract output from the model
private void extractResult()
{
// Retrieve the results of evaluation
var mResult = results.modelOutput as TensorFloat;
// convert the result to vector format
var resultVector = mResult.GetAsVectorView();
probability = 0;
int index = 0;
// find the maximum probability
for(int i=0; i<resultVector.Count; i++)
{
var elementProbability=resultVector[i];
if (elementProbability > probability)
{
index = i;
}
}
label = ((Labels)index).ToString();
}
- Adicione o
displayResultmétodo ao seuMainPage.xaml.csarquivo de código dentro daMainPageclasse.
private async Task displayResult()
{
displayOutput.Text = label;
}
Está feito! Você criou com sucesso o aplicativo de aprendizado de máquina do Windows com uma GUI básica para testar nosso modelo de classificação. O próximo passo é iniciar o aplicativo e executá-lo localmente em seu dispositivo Windows.
Inicie o aplicativo
Depois de concluir a interface do aplicativo, adicionar o modelo e gerar o código de ML do Windows, você pode testar o aplicativo!
Habilite o modo de desenvolvedor e teste seu aplicativo do 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 em sua máquina local se o dispositivo for de 64 bits ou x86 se for de 32 bits.
Nosso modelo foi treinado para classificar as seguintes imagens: avião, carro, pássaro, gato, veado, cão, sapo, cavalo, navio, caminhão. Para testar nosso aplicativo, você usará a imagem do carro Lego construído para este projeto. Vamos ver como nosso aplicativo classifica o conteúdo da imagem.
Guarde esta imagem no seu dispositivo local para testar a aplicação. Altere o formato da imagem para
.jpgse necessário. Você também pode usar qualquer outra imagem relevante do seu dispositivo local nos formatos .jpg ou .png.Para executar o projeto, selecione o
Start Debuggingbotão na barra de ferramentas ou pressioneF5.Quando o aplicativo for iniciado, pressione Pick Image e selecione a imagem do seu dispositivo local.
O resultado aparecerá na tela imediatamente. Como você pode ver, nosso aplicativo Windows ML classificou com sucesso a imagem como um carro.
Resumo
Você acabou de criar seu primeiro aplicativo de Aprendizado de Máquina do Windows, desde a 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 de ML do Windows: saiba mais ferramentas como o Painel de ML do Windows, o WinMLRunner e o gerador de códigos mglen Windows ML.
- Modelo ONNX: Saiba mais sobre o formato ONNX.
- Desempenho e memória do Windows ML: saiba mais como gerenciar o desempenho do aplicativo com o Windows ML.
- Referência da API do Windows Machine Learning: saiba mais sobre três áreas das APIs de ML do Windows.